Optional Module Dependency

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Optional Module Dependency

cobusve
I have ModuleA which Optionally needs ModuleB. What I mean is that I want to
use a class in Module B only if it exists, if not I am OK with that, we just
do not use it.

Essentially I want to do in Module A:

try { ModBClass  foo = new  ModBClass();}
catch (NoClassDefFoundError) ...

And then going forward not use the functionality when not present.

What I have tried :

I can make this happen using reflection, but that is too ugly to accept.
There must be a better way !

I have compiled ModuleA, which results in info.xml containing
"OpenIDE-Module-Module-Dependencies="ModuleB". If this is present the module
will not install. If I remove it the module installs but does not load. If I
add OpenIDE-Module-Recommends="ModuleB" it still installs and does not load.

I get an error dialog stating
"Warning - could not install some modules: ModuleA - The module named
ModuleB was needed and not found."

All I find in the logs is "Warning - could not install some modules:
        ModuleA - The module named ModuleB was needed and not found."

Note that when I run/debug the ModuleA project from the IDE it opens a
NetBeans instance and runs just fine and works as expected when ModuleB is
present and also when it is not present.

It seems like the process of loading of ModuleA in Netbeans IDE when running
normally does some additional checks which prevents the module from loading.

So where is the magic sauce ? If I understood what Netbeans is doing when
loading the module I could try and figure it out. My modules do not contain
any class member properties or statics so just loading the module should not
trigger any errors. It seems almost like the Netbeans module loader is
re-checking my imports, so how do I tell it that I know what I am doing do
not worry ?

ps. This is similar to the case described here
http://netbeans-org.1045718.n5.nabble.com/Optional-module-dependency-td3027893.html



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html
Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

geertjan.wielenga@oracle.com

I don’t know the answer to this — best would be if you’d put a small demo app that reproduces this on GitHub. Then someone will be able to take a look and suggest solutions.

Thanks,


Geertjan Wielenga | Principal Product Manager
Phone: +31620320056 | 
Oracle Developer Tools

ORACLE Netherlands | Hertogswetering 163-167 | 3543 AS Utrecht | Netherlands


Oracle is committed to developing practices and products that help protect the environment

On 3 Nov 2017, at 21:30, cobusve <[hidden email]> wrote:

I have ModuleA which Optionally needs ModuleB. What I mean is that I want to
use a class in Module B only if it exists, if not I am OK with that, we just
do not use it.

Essentially I want to do in Module A:

try { ModBClass  foo = new  ModBClass();}
catch (NoClassDefFoundError) ...

And then going forward not use the functionality when not present.

What I have tried :

I can make this happen using reflection, but that is too ugly to accept.
There must be a better way !

I have compiled ModuleA, which results in info.xml containing
"OpenIDE-Module-Module-Dependencies="ModuleB". If this is present the module
will not install. If I remove it the module installs but does not load. If I
add OpenIDE-Module-Recommends="ModuleB" it still installs and does not load. 

I get an error dialog stating 
"Warning - could not install some modules: ModuleA - The module named
ModuleB was needed and not found."

All I find in the logs is "Warning - could not install some modules:
ModuleA - The module named ModuleB was needed and not found."

Note that when I run/debug the ModuleA project from the IDE it opens a
NetBeans instance and runs just fine and works as expected when ModuleB is
present and also when it is not present.

It seems like the process of loading of ModuleA in Netbeans IDE when running
normally does some additional checks which prevents the module from loading. 

So where is the magic sauce ? If I understood what Netbeans is doing when
loading the module I could try and figure it out. My modules do not contain
any class member properties or statics so just loading the module should not
trigger any errors. It seems almost like the Netbeans module loader is
re-checking my imports, so how do I tell it that I know what I am doing do
not worry ?

ps. This is similar to the case described here 
http://netbeans-org.1045718.n5.nabble.com/Optional-module-dependency-td3027893.html



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html

Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

cobusve
Thanks ! Not sure what hope I have if Geertjan doesn't know but I will put
together a demo in the next couple of days and post it. Watch this space !



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html
Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

geertjan.wielenga@oracle.com

Great, thanks.

Typically things start making sense and people start providing solutions when the problem statement is provided in the form of code.

Thanks,


Geertjan Wielenga | Principal Product Manager
Phone: +31620320056 | 
Oracle Developer Tools

ORACLE Netherlands | Hertogswetering 163-167 | 3543 AS Utrecht | Netherlands


Oracle is committed to developing practices and products that help protect the environment

On 7 Nov 2017, at 14:23, cobusve <[hidden email]> wrote:

Thanks ! Not sure what hope I have if Geertjan doesn't know but I will put
together a demo in the next couple of days and post it. Watch this space ! 



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html

Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

Graeme
In reply to this post by geertjan.wielenga@oracle.com

Have you considered the ServiceProvider interface?

 

You could either define an interface in another module say Module C – or I believe in this case Module B would not be used standalone but would only be used if ModuleA existed.

 

So ModuleA could define an interface and ModuleB could define an implementation of that interface.  Mark it with the ServerProvider annotation and in ModuleA use the Lookup interface to obtain a reference to ModuleB’s implementation.   

 

http://wiki.netbeans.org/DevFaqWhenToUseWhatRegistrationMethod

 

 

http://bits.netbeans.org/8.0/javadoc/org-openide-util-lookup/org/openide/util/lookup/ServiceProvider.html

 

From: [hidden email] [mailto:[hidden email]]
Sent: Tuesday, November 07, 2017 4:53 AM
To: [hidden email]
Subject: [platform-dev] Re: Optional Module Dependency

 

 

I don’t know the answer to this — best would be if you’d put a small demo app that reproduces this on GitHub. Then someone will be able to take a look and suggest solutions.

 

Thanks,

 


Geertjan Wielenga | Principal Product Manager
Phone: +31620320056 | 
Oracle Developer Tools

ORACLE Netherlands | Hertogswetering 163-167 | 3543 AS Utrecht | Netherlands


Oracle is committed to developing practices and products that help protect the environment



On 3 Nov 2017, at 21:30, cobusve <[hidden email]> wrote:

I have ModuleA which Optionally needs ModuleB. What I mean is that I want to
use a class in Module B only if it exists, if not I am OK with that, we just
do not use it.

Essentially I want to do in Module A:

try { ModBClass  foo = new  ModBClass();}
catch (NoClassDefFoundError) ...

And then going forward not use the functionality when not present.

What I have tried :

I can make this happen using reflection, but that is too ugly to accept.
There must be a better way !

I have compiled ModuleA, which results in info.xml containing
"OpenIDE-Module-Module-Dependencies="ModuleB". If this is present the module
will not install. If I remove it the module installs but does not load. If I
add OpenIDE-Module-Recommends="ModuleB" it still installs and does not load. 

I get an error dialog stating 
"Warning - could not install some modules: ModuleA - The module named
ModuleB was needed and not found."

All I find in the logs is "Warning - could not install some modules:
            ModuleA - The module named ModuleB was needed and not found."

Note that when I run/debug the ModuleA project from the IDE it opens a
NetBeans instance and runs just fine and works as expected when ModuleB is
present and also when it is not present.

It seems like the process of loading of ModuleA in Netbeans IDE when running
normally does some additional checks which prevents the module from loading. 

So where is the magic sauce ? If I understood what Netbeans is doing when
loading the module I could try and figure it out. My modules do not contain
any class member properties or statics so just loading the module should not
trigger any errors. It seems almost like the Netbeans module loader is
re-checking my imports, so how do I tell it that I know what I am doing do
not worry ?

ps. This is similar to the case described here 
http://netbeans-org.1045718.n5.nabble.com/Optional-module-dependency-td3027893.html



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html

 

Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

Graeme

If you really don’t want to use the ServiceProvider (which I’d recommend) – you could use the SystemClass loader…

 

http://wiki.netbeans.org/ClassloaderTrick

 

This will get you a classloader capable of loading resources from any enabled module.

 

 

From: Ingleby, Graeme [mailto:[hidden email]]
Sent: Tuesday, November 07, 2017 8:48 AM
To: [hidden email]
Subject: [platform-dev] Re: Optional Module Dependency

 

Have you considered the ServiceProvider interface?

 

You could either define an interface in another module say Module C – or I believe in this case Module B would not be used standalone but would only be used if ModuleA existed.

 

So ModuleA could define an interface and ModuleB could define an implementation of that interface.  Mark it with the ServerProvider annotation and in ModuleA use the Lookup interface to obtain a reference to ModuleB’s implementation.   

 

http://wiki.netbeans.org/DevFaqWhenToUseWhatRegistrationMethod

 

 

http://bits.netbeans.org/8.0/javadoc/org-openide-util-lookup/org/openide/util/lookup/ServiceProvider.html

 

From: [hidden email] [[hidden email]]
Sent: Tuesday, November 07, 2017 4:53 AM
To: [hidden email]
Subject: [platform-dev] Re: Optional Module Dependency

 

 

I don’t know the answer to this — best would be if you’d put a small demo app that reproduces this on GitHub. Then someone will be able to take a look and suggest solutions.

 

Thanks,

 


Geertjan Wielenga | Principal Product Manager
Phone: +31620320056 | 
Oracle Developer Tools

ORACLE Netherlands | Hertogswetering 163-167 | 3543 AS Utrecht | Netherlands


Oracle is committed to developing practices and products that help protect the environment

 

On 3 Nov 2017, at 21:30, cobusve <[hidden email]> wrote:

I have ModuleA which Optionally needs ModuleB. What I mean is that I want to
use a class in Module B only if it exists, if not I am OK with that, we just
do not use it.

Essentially I want to do in Module A:

try { ModBClass  foo = new  ModBClass();}
catch (NoClassDefFoundError) ...

And then going forward not use the functionality when not present.

What I have tried :

I can make this happen using reflection, but that is too ugly to accept.
There must be a better way !

I have compiled ModuleA, which results in info.xml containing
"OpenIDE-Module-Module-Dependencies="ModuleB". If this is present the module
will not install. If I remove it the module installs but does not load. If I
add OpenIDE-Module-Recommends="ModuleB" it still installs and does not load. 

I get an error dialog stating 
"Warning - could not install some modules: ModuleA - The module named
ModuleB was needed and not found."

All I find in the logs is "Warning - could not install some modules:
            ModuleA - The module named ModuleB was needed and not found."

Note that when I run/debug the ModuleA project from the IDE it opens a
NetBeans instance and runs just fine and works as expected when ModuleB is
present and also when it is not present.

It seems like the process of loading of ModuleA in Netbeans IDE when running
normally does some additional checks which prevents the module from loading. 

So where is the magic sauce ? If I understood what Netbeans is doing when
loading the module I could try and figure it out. My modules do not contain
any class member properties or statics so just loading the module should not
trigger any errors. It seems almost like the Netbeans module loader is
re-checking my imports, so how do I tell it that I know what I am doing do
not worry ?

ps. This is similar to the case described here 
http://netbeans-org.1045718.n5.nabble.com/Optional-module-dependency-td3027893.html



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html

 

Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

cobusve
Yes I did consider the service provider, but since the other module is not
under my control that option does not work, as I would have to convince the
vendor to ship their interface as a separate module.

What you describe with the SystemClass Loader is exactly what I did to make
it work using reflection, but I generally try to avoid reflection like the
plague.

I was hoping that I was missing some secret sauce, that I am just not using
OpenIDE-Module-Recommends  correctly, because from the description that is
exactly what I need.

From the Modules API documentation "Moreover there is also
OpenIDE-Module-Recommends which is even weaker version as it creates a
conditional dependency - e.g. enables the module providing the token only if
it is available, however if it is not, no dependency is broken."

So this seemed like it will do exactly what I need - load the dependency
when it exists and continue if it does not, and it does this when installing
the module, but when you activate the module it fails activation, which gets
me only halfway. If only the activation also paid attention to the
OpenIDE-Module-Recommends ?



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html
Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

Graeme
It's a bit of a hack and probably breaks all kinds of NB best practices and only works once the application is installed (you can't run from within the IDE) but I did get  something that seems to fit your original request working.

I've posted a blog entry that describes the approach in detail along with a video of the application in action.

http://gingleby.com/2017/11/08/netbeans-application-with-optional-module/

Going back to the Service Provider approach:

I know you said ServiceProvider wouldn't work because your other Module is from a vendor but depending on the number of classes you want to interact with and the complexity of those classes you might be able to use ServiceProvider as a proxy.

In other words, define a service interface in Module I.   Define a service implementation in Module B (which has a dependency  on Module V - your vendor Module and Module I).  The class in Module B simply invokes the methods on the vendor class from Module V.

Now your App (Module A with a dependency on Module I) should be able to invoke code from Module B which in turn invokes the vendor code in Module V.

...or is your issue one where you have two vendor libraries that can use each other and Module A requires actual instances of the Module V classes to work?


-----Original Message-----
From: cobusve [mailto:[hidden email]]
Sent: Tuesday, November 07, 2017 11:04 AM
To: [hidden email]
Subject: [platform-dev] Re: Optional Module Dependency

Yes I did consider the service provider, but since the other module is not under my control that option does not work, as I would have to convince the vendor to ship their interface as a separate module.

What you describe with the SystemClass Loader is exactly what I did to make it work using reflection, but I generally try to avoid reflection like the plague.

I was hoping that I was missing some secret sauce, that I am just not using OpenIDE-Module-Recommends  correctly, because from the description that is exactly what I need.

From the Modules API documentation "Moreover there is also OpenIDE-Module-Recommends which is even weaker version as it creates a conditional dependency - e.g. enables the module providing the token only if it is available, however if it is not, no dependency is broken."

So this seemed like it will do exactly what I need - load the dependency when it exists and continue if it does not, and it does this when installing the module, but when you activate the module it fails activation, which gets me only halfway. If only the activation also paid attention to the OpenIDE-Module-Recommends ?



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html

Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

Emilian Bold-2
In reply to this post by cobusve
Cobus, please use the [hidden email] mailing list
as this one is going away.

The whole point of the module system is you don't get (or have to
handle yourself) NoClassDefFoundError. So, wanting something like

try { ModBClass  foo = new  ModBClass();}
catch (NoClassDefFoundError) ...

is... not good.

What you want is to Lookup a given service and maybe get a null. So,
the problem is how to get a service for that.

Look into creating an eager (bridge) module which depends on module B
and implements a Service (defined in module A or another module). Then
lookup your service and handle the null.

BTW: OpenIDE-Module-Provides/OpenIDE-Module-Requires/OpenIDE-Module-Needs/OpenIDE-Module-Recommends
work on *tokens* not classes. It's unfortunate that a popular NetBeans
Platform book uses class names instead of tokens since it leads people
to believe these manifest tags are for something else.


--emi


On Tue, Nov 7, 2017 at 6:02 PM, cobusve <[hidden email]> wrote:

> Yes I did consider the service provider, but since the other module is not
> under my control that option does not work, as I would have to convince the
> vendor to ship their interface as a separate module.
>
> What you describe with the SystemClass Loader is exactly what I did to make
> it work using reflection, but I generally try to avoid reflection like the
> plague.
>
> I was hoping that I was missing some secret sauce, that I am just not using
> OpenIDE-Module-Recommends  correctly, because from the description that is
> exactly what I need.
>
> From the Modules API documentation "Moreover there is also
> OpenIDE-Module-Recommends which is even weaker version as it creates a
> conditional dependency - e.g. enables the module providing the token only if
> it is available, however if it is not, no dependency is broken."
>
> So this seemed like it will do exactly what I need - load the dependency
> when it exists and continue if it does not, and it does this when installing
> the module, but when you activate the module it fails activation, which gets
> me only halfway. If only the activation also paid attention to the
> OpenIDE-Module-Recommends ?
>
>
>
> --
> Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html
Reply | Threaded
Open this post in threaded view
|

Re: Optional Module Dependency

cobusve
In reply to this post by Graeme
Thanks Graeme,

I was trying to do exactly this, thanks for the detailed write-up !

Cobus



--
Sent from: http://netbeans-org.1045718.n5.nabble.com/Netbeans-RCP-Platform-Users-Open-API-f3018772.html