Use classes in unnamed module that are also contained in a JDK platform/runtime module

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Use classes in unnamed module that are also contained in a JDK platform/runtime module

Langer, Christoph
Hi experts,

probably this was already asked or discussed here but I don't find an exact answer for my type of issue, so I'm asking again.

I have some piece of software that we ship as a jar file and which will hence run on a JDK 9 in the unnamed module. However, this jar file contains a package that is also contained in our JDK image in a module that is always part of the runtime. So, when my app wants to use one of these classes, I get a java.lang.IllegalAccessError because the class is not exported from the runtime module to my app. And, also if I have a class in that package which is not part of the runtime module, I get a java.lang.NoClassDefFoundError because probably the package is loaded from the runtime module.

As I don't want to maintain 2 copies of the same code just to have different package names, I'm wondering if I could solve this somehow by implementing my own class loader for the app that would first try to load these classes from the classpath before delegating to the default application class loader. Would that work? I also did some googling on implementing a non-delegating class loader but to me that seems not so easy and has pitfalls. Is there a good reference or even something in the JDK that I could subclass?

Thanks
Christoph

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Use classes in unnamed module that are also contained in a JDK platform/runtime module

Alan Bateman
On 04/07/2017 08:02, Langer, Christoph wrote:
> Hi experts,
>
> probably this was already asked or discussed here but I don't find an exact answer for my type of issue, so I'm asking again.
>
> I have some piece of software that we ship as a jar file and which will hence run on a JDK 9 in the unnamed module. However, this jar file contains a package that is also contained in our JDK image in a module that is always part of the runtime. So, when my app wants to use one of these classes, I get a java.lang.IllegalAccessError because the class is not exported from the runtime module to my app. And, also if I have a class in that package which is not part of the runtime module, I get a java.lang.NoClassDefFoundError because probably the package is loaded from the runtime module.
>
> As I don't want to maintain 2 copies of the same code just to have different package names, I'm wondering if I could solve this somehow by implementing my own class loader for the app that would first try to load these classes from the classpath before delegating to the default application class loader. Would that work? I also did some googling on implementing a non-delegating class loader but to me that seems not so easy and has pitfalls.
Yes, that should work.

An alternative is to patch the module (with --patch-module) with the
additional classes in the JAR file. This assumes of course that the
contents of the JAR file are indeed a compatible superset.


> Is there a good reference or even something in the JDK that I could subclass?
>
The trampoline code in sun.reflect.misc.MethodUtil is roughly in this
area but might be too specialized. There may be some test code that you
could use - one example is in the patch for JDK-8183503 which is
currently waiting for review on hotspot-runtime-dev [1].

-Alan.

[1]
http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2017-July/023841.html
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Use classes in unnamed module that are also contained in a JDK platform/runtime module

Alex Buckley
In reply to this post by Langer, Christoph
Hi Christoph,

On 7/4/2017 12:02 AM, Langer, Christoph wrote:
> I have some piece of software that we ship as a jar file and which
> will hence run on a JDK 9 in the unnamed module. However, this jar
> file contains a package that is also contained in our JDK image in a
> module that is always part of the runtime.

It would be remiss of me if I didn't ask for some details about why this
scenario has arisen. From "always part of the runtime", I would have
guessed the package is in java.base, but you also mention "our JDK
image" so perhaps the package is in a module that SAP always jlinks in?

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Use classes in unnamed module that are also contained in a JDK platform/runtime module

Langer, Christoph
Hi Alex,

> On 7/4/2017 12:02 AM, Langer, Christoph wrote:
> > I have some piece of software that we ship as a jar file and which
> > will hence run on a JDK 9 in the unnamed module. However, this jar
> > file contains a package that is also contained in our JDK image in a
> > module that is always part of the runtime.
>
> It would be remiss of me if I didn't ask for some details about why this
> scenario has arisen. From "always part of the runtime", I would have
> guessed the package is in java.base, but you also mention "our JDK
> image" so perhaps the package is in a module that SAP always jlinks in?

Thanks for your interest in the details. Here it is: We have a separate module that exposes an augmenting SAP specific API which is publicly exported. This module is part of our JDK image. And it in turn pulls a few other modules with the implementing classes and packages. And then we ship a few tools and services apart from the JDK. Some of these are Eclipse based, some of these are standalone. And parts of these tools use the basic classes which are also observable in the JDK. But they need to be there as our tooling should run on any JDK, not only ours.

I think Eclipse-wise we are good, at least when Eclipse runs on Java 8. With the Eclipse classloading, we get the classes out of the plugins. However, since Eclipse is not really mature yet for Java 9, I didn't test there so far. And for the standalone apps, I probably need to look into implementing some custom classloader. I'll try with Alan's suggestions (thanks Alan) but didn't find the time yet.

Thanks & Best regards
Christoph

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Use classes in unnamed module that are also contained in a JDK platform/runtime module

Alex Buckley
On 7/6/2017 11:37 PM, Langer, Christoph wrote:

>> On 7/4/2017 12:02 AM, Langer, Christoph wrote:
>>> I have some piece of software that we ship as a jar file and
>>> which will hence run on a JDK 9 in the unnamed module. However,
>>> this jar file contains a package that is also contained in our
>>> JDK image in a module that is always part of the runtime.
>>
>> It would be remiss of me if I didn't ask for some details about why
>> this scenario has arisen. From "always part of the runtime", I
>> would have guessed the package is in java.base, but you also
>> mention "our JDK image" so perhaps the package is in a module that
>> SAP always jlinks in?
>
> Thanks for your interest in the details. Here it is: We have a
> separate module that exposes an augmenting SAP specific API which is
> publicly exported. This module is part of our JDK image.

The default set of root modules for the unnamed module is specified by
JEP 261 rather than a JSR, but I guess the SAP JDK implementation uses
the same default set as the OpenJDK implementation. Then, since your
separate module exports a package without qualification, the separate
module is in the default set.

You could mark the separate module as DoNotResolveByDefault so that it
is observable *but not readable* by the unnamed module which holds your
JAR file's tool classes + copies of SAP-specific API/impl classes.

Or, given that the JAR file is meant to be cross-JDK and so should never
be aware of the separate module, your tool's launch script could make
the separate module unobservable (--limit-modules).

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Use classes in unnamed module that are also contained in a JDK platform/runtime module

Langer, Christoph
Hi Alex,

> On 7/6/2017 11:37 PM, Langer, Christoph wrote:
> >> On 7/4/2017 12:02 AM, Langer, Christoph wrote:
> >>> I have some piece of software that we ship as a jar file and
> >>> which will hence run on a JDK 9 in the unnamed module. However,
> >>> this jar file contains a package that is also contained in our
> >>> JDK image in a module that is always part of the runtime.
> >>
> >> It would be remiss of me if I didn't ask for some details about why
> >> this scenario has arisen. From "always part of the runtime", I
> >> would have guessed the package is in java.base, but you also
> >> mention "our JDK image" so perhaps the package is in a module that
> >> SAP always jlinks in?
> >
> > Thanks for your interest in the details. Here it is: We have a
> > separate module that exposes an augmenting SAP specific API which is
> > publicly exported. This module is part of our JDK image.
>
> The default set of root modules for the unnamed module is specified by
> JEP 261 rather than a JSR, but I guess the SAP JDK implementation uses
> the same default set as the OpenJDK implementation. Then, since your
> separate module exports a package without qualification, the separate
> module is in the default set.

Exactly, this is how it is designed.

> You could mark the separate module as DoNotResolveByDefault so that it
> is observable *but not readable* by the unnamed module which holds your
> JAR file's tool classes + copies of SAP-specific API/impl classes.
>
> Or, given that the JAR file is meant to be cross-JDK and so should never
> be aware of the separate module, your tool's launch script could make
> the separate module unobservable (--limit-modules).

OK, this maybe is a good idea to try. When I'm running my JDK-independent tool on top of our VM, then this public API is not used and probably neither of its dependents. I'll test that.

Thanks a lot for your consulting.

Best regards
Christoph

Loading...