Extending java.base module
Hi Jigsaw experts, as you might or might not know, we have an own JDK implementation with some extension code that is quite interwoven with the jdk. Now I'm looking into how this coding can be spread into a good module structure for jdk9. And I'm not a crack yet on using the module system though I've read quite a bit into the spec documentation available so far;-) The first point for me is that we have to place some of our coding in the java.base module as we used to add private fields and methods to basic classes such as java.lang.Thread or java.lang.Exception. However, I don't want to have so much of our stuff in java.base and rather think that it should live in its own module. So the question here is if it is possible to call code of other modules from java.base, e.g. via the Service Provider interface? I see that I can define a service in java.base and specify some "uses" statement in module-info. But will my implementation of such a service from other modules be available to java.base? Also I'm contemplating about this requirement: I have a class which I would need somewhere in java.base but I'd also like to export it in the public API of my own extension module. So, if I create the class in java.base, I'm not allowed to export this class publicly, unqualified, right? But when I have it living in my extension module, then java.base would not see it. What can I do? Probably create some inherited class in my extension module that extends from the java.base impl and export this?? I'm hoping that those are easy questions for you and you can give me some helpful answers. Thanks a lot in advance!! Best regards Christoph
Re: Extending java.base module
Disclaimer: I am not a jigsaw expert. The provides/uses mechanism is certainly more formal, but you can also do http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d282c1a8d20b. --Max On 02/15/2017 04:36 PM, Langer, Christoph wrote: Hi Jigsaw experts, as you might or might not know, we have an own JDK implementation with some extension code that is quite interwoven with the jdk. Now I'm looking into how this coding can be spread into a good module structure for jdk9. And I'm not a crack yet on using the module system though I've read quite a bit into the spec documentation available so far;-) The first point for me is that we have to place some of our coding in the java.base module as we used to add private fields and methods to basic classes such as java.lang.Thread or java.lang.Exception. However, I don't want to have so much of our stuff in java.base and rather think that it should live in its own module. So the question here is if it is possible to call code of other modules from java.base, e.g. via the Service Provider interface? I see that I can define a service in java.base and specify some "uses" statement in module-info. But will my implementation of such a service from other modules be available to java.base? Also I'm contemplating about this requirement: I have a class which I would need somewhere in java.base but I'd also like to export it in the public API of my own extension module. So, if I create the class in java.base, I'm not allowed to export this class publicly, unqualified, right? But when I have it living in my extension module, then java.base would not see it. What can I do? Probably create some inherited class in my extension module that extends from the java.base impl and export this?? I'm hoping that those are easy questions for you and you can give me some helpful answers. Thanks a lot in advance!! Best regards Christoph
Re: Extending java.base module
> On 15 Feb 2017, at 08:51, Weijun Wang wrote: > > Disclaimer: I am not a jigsaw expert. > > The provides/uses mechanism is certainly more formal, but you can also do > http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d282c1a8d20b. This is, at best, a hack. The use of Services is a better approach, where possible. -Chris.
RE: Extending java.base module
Hi Chris, Max, thanks for your quick answers. So the service approach seems to fit quite well. But can I assume that my service implementation will be available already at "bootstrap time" of the JDK? E.g. if I need to register/reach my service already at the early stages of JVM initialization, e.g. when a class java.lang.Thread gets initialized, can I assume a service from my extension module would be available? Thanks, Christoph > -Original Message- > From: Chris Hegarty [mailto:chris.hega...@oracle.com] > Sent: Mittwoch, 15. Februar 2017 10:04 > To: Weijun Wang > Cc: Langer, Christoph ; jigsaw- > d...@openjdk.java.net > Subject: Re: Extending java.base module > > > > On 15 Feb 2017, at 08:51, Weijun Wang wrote: > > > > Disclaimer: I am not a jigsaw expert. > > > > The provides/uses mechanism is certainly more formal, but you can also do > http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d282c1a8d20b. > > This is, at best, a hack. The use of Services is a better approach, where > possible. > > -Chris.
Re: Extending java.base module
On 15/02/2017 08:36, Langer, Christoph wrote: Hi Jigsaw experts, as you might or might not know, we have an own JDK implementation with some extension code that is quite interwoven with the jdk. Now I'm looking into how this coding can be spread into a good module structure for jdk9. And I'm not a crack yet on using the module system though I've read quite a bit into the spec documentation available so far;-) The first point for me is that we have to place some of our coding in the java.base module as we used to add private fields and methods to basic classes such as java.lang.Thread or java.lang.Exception. However, I don't want to have so much of our stuff in java.base and rather think that it should live in its own module. So the question here is if it is possible to call code of other modules from java.base, e.g. via the Service Provider interface? I see that I can define a service in java.base and specify some "uses" statement in module-info. But will my implementation of such a service from other modules be available to java.base? Also I'm contemplating about this requirement: I have a class which I would need somewhere in java.base but I'd also like to export it in the public API of my own extension module. So, if I create the class in java.base, I'm not allowed to export this class publicly, unqualified, right? But when I have it living in my extension module, then java.base would not see it. What can I do? Probably create some inherited class in my extension module that extends from the java.base impl and export this?? I'm hoping that those are easy questions for you and you can give me some helpful answers. Yes, services is the way to do this. The jdk.net module is one example, there are several others. The other thing to be aware of is the module-info.java.extra files to augment the module declarations during the build, I suspect you'll end up using that. -Alan
Re: Extending java.base module
On 15/02/2017 8:03 PM, Langer, Christoph wrote: Hi Chris, Max, thanks for your quick answers. So the service approach seems to fit quite well. But can I assume that my service implementation will be available already at "bootstrap time" of the JDK? E.g. if I need to register/reach my service already at the early stages of JVM initialization, e.g. when a class java.lang.Thread gets initialized, can I assume a service from my extension module would be available? I'm pretty sure the answer to that will be No! Thread is one of the earlier classes to be initialized, the module system is initialized much later. David - Thanks, Christoph -Original Message- From: Chris Hegarty [mailto:chris.hega...@oracle.com] Sent: Mittwoch, 15. Februar 2017 10:04 To: Weijun Wang Cc: Langer, Christoph ; jigsaw- d...@openjdk.java.net Subject: Re: Extending java.base module On 15 Feb 2017, at 08:51, Weijun Wang wrote: Disclaimer: I am not a jigsaw expert. The provides/uses mechanism is certainly more formal, but you can also do http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d282c1a8d20b. This is, at best, a hack. The use of Services is a better approach, where possible. -Chris.
Re: Extending java.base module
On 15/02/2017 12:10, David Holmes wrote: On 15/02/2017 8:03 PM, Langer, Christoph wrote: Hi Chris, Max, thanks for your quick answers. So the service approach seems to fit quite well. But can I assume that my service implementation will be available already at "bootstrap time" of the JDK? E.g. if I need to register/reach my service already at the early stages of JVM initialization, e.g. when a class java.lang.Thread gets initialized, can I assume a service from my extension module would be available? I'm pretty sure the answer to that will be No! Thread is one of the earlier classes to be initialized, the module system is initialized much later. That's right as only classes in java.base can be loaded during startup. I don't know what services that Christoph is thinking of but hopefully they can be deferred until the VM is initialized. -Alan
Re: Extending java.base module
> > E.g. if I need to register/reach my service already at the early stages of > JVM initialization, e.g. when a class java.lang.Thread gets initialized, > can I assume a service from my extension module would be available? > No. At that time only java.base classes can be loaded. If you look at the comments in the initPhase# methods in System, it gives some good info about when things are initialized. http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/classes/java/lang/System.java#l1850 /Michael
RE: Extending java.base module
Hi, thanks all for your very helpful comments. So I see that I cannot rely on my Service implementation at an early stage. But I can imagine that I query for the service provider and if it's not there I have to be able to live without it. The question that remains is, when I query the ServiceLoader for my impl at a later time, then I would find it registered, right? I assume that if my module specifies "provides with ", the provider will automatically be registered once the module is loaded. Can you confirm that? Thanks Christoph > -Original Message- > From: Alan Bateman [mailto:alan.bate...@oracle.com] > Sent: Mittwoch, 15. Februar 2017 13:22 > To: David Holmes ; Langer, Christoph > ; Chris Hegarty ; > Weijun Wang > Cc: jigsaw-dev@openjdk.java.net > Subject: Re: Extending java.base module > > > > On 15/02/2017 12:10, David Holmes wrote: > > On 15/02/2017 8:03 PM, Langer, Christoph wrote: > >> Hi Chris, Max, > >> > >> thanks for your quick answers. So the service approach seems to fit > >> quite well. > >> > >> But can I assume that my service implementation will be available > >> already at "bootstrap time" of the JDK? E.g. if I need to > >> register/reach my service already at the early stages of JVM > >> initialization, e.g. when a class java.lang.Thread gets initialized, > >> can I assume a service from my extension module would be available? > > > > I'm pretty sure the answer to that will be No! Thread is one of the > > earlier classes to be initialized, the module system is initialized > > much later. > That's right as only classes in java.base can be loaded during startup. > I don't know what services that Christoph is thinking of but hopefully > they can be deferred until the VM is initialized. > > -Alan
Re: Extending java.base module
On 15/02/2017 13:21, Langer, Christoph wrote: Hi, thanks all for your very helpful comments. So I see that I cannot rely on my Service implementation at an early stage. But I can imagine that I query for the service provider and if it's not there I have to be able to live without it. The question that remains is, when I query the ServiceLoader for my impl at a later time, then I would find it registered, right? I assume that if my module specifies "provides with ", the provider will automatically be registered once the module is loaded. Can you confirm that? Yes. If you look in areas like JMX or networking then you'll see lots of examples where "extensions" are deployed as service providers. These should help you get started. -Alan
Re: Extending java.base module
Hi Max, I'm not an jigsaw either, but wouldn't your solution break a tool like jlink? In other words, if an application uses your code and the developer uses jlink to create a run-time image, wouldn't that image fail to execute his application because jlink fails to see that java.base depends on java.security.jgss in that special case? Thanks, Volker On Wed, Feb 15, 2017 at 9:51 AM, Weijun Wang wrote: > Disclaimer: I am not a jigsaw expert. > > The provides/uses mechanism is certainly more formal, but you can also do > http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d282c1a8d20b. > > --Max > > > On 02/15/2017 04:36 PM, Langer, Christoph wrote: >> >> Hi Jigsaw experts, >> >> as you might or might not know, we have an own JDK implementation with >> some extension code that is quite interwoven with the jdk. >> >> Now I'm looking into how this coding can be spread into a good module >> structure for jdk9. And I'm not a crack yet on using the module system >> though I've read quite a bit into the spec documentation available so far;-) >> >> The first point for me is that we have to place some of our coding in the >> java.base module as we used to add private fields and methods to basic >> classes such as java.lang.Thread or java.lang.Exception. However, I don't >> want to have so much of our stuff in java.base and rather think that it >> should live in its own module. So the question here is if it is possible to >> call code of other modules from java.base, e.g. via the Service Provider >> interface? I see that I can define a service in java.base and specify some >> "uses" statement in module-info. But will my implementation of such a >> service from other modules be available to java.base? >> >> Also I'm contemplating about this requirement: I have a class which I >> would need somewhere in java.base but I'd also like to export it in the >> public API of my own extension module. So, if I create the class in >> java.base, I'm not allowed to export this class publicly, unqualified, >> right? But when I have it living in my extension module, then java.base >> would not see it. What can I do? Probably create some inherited class in my >> extension module that extends from the java.base impl and export this?? >> >> I'm hoping that those are easy questions for you and you can give me some >> helpful answers. >> >> Thanks a lot in advance!! >> >> Best regards >> Christoph >> >
Re: Extending java.base module
Hi Volker, On 15/02/17 15:52, Volker Simonis wrote: Hi Max, I'm not an jigsaw either, but wouldn't your solution break a tool like jlink? In other words, if an application uses your code and the developer uses jlink to create a run-time image, wouldn't that image fail to execute his application because jlink fails to see that java.base depends on java.security.jgss in that special case? In that specific case it's not java.base that depends on java.security.jgss, but the application itself. So I would expect the application code to either require java.security.jgss, or some higher level module for that itself requires java.security.jgss, or jlink to be run with command line options that explicitly add java.security.jgss to the image. best regards, -- daniel Thanks, Volker
Re: Extending java.base module
On 15/02/2017 16:01, Daniel Fuchs wrote: In that specific case it's not java.base that depends on java.security.jgss, but the application itself. So I would expect the application code to either require java.security.jgss, or some higher level module for that itself requires java.security.jgss, or jlink to be run with command line options that explicitly add java.security.jgss to the image. java.security.jgss exports an API so it will be resolved by default when the initial class is loaded from the class path. In addition, it provides a SecurityProvider implementation and so will be resolved because java.base `uses java.security.Provider`. For the jlink case then you are right, it needs someone to know that the application might need to do SPNEGO authentication. In any case, it's an example of how not to do things, and hopefully it will be cleaned up at some point. -Alan
Re: Extending java.base module
On Wed, Feb 15, 2017 at 5:16 PM, Alan Bateman wrote: > On 15/02/2017 16:01, Daniel Fuchs wrote: > >> >> In that specific case it's not java.base that depends >> on java.security.jgss, but the application itself. >> >> So I would expect the application code to either require >> java.security.jgss, or some higher level module for that >> itself requires java.security.jgss, or jlink to be run with >> command line options that explicitly add java.security.jgss >> to the image. > > java.security.jgss exports an API so it will be resolved by default when the > initial class is loaded from the class path. In addition, it provides a > SecurityProvider implementation and so will be resolved because java.base > `uses java.security.Provider`. For the jlink case then you are right, it > needs someone to know that the application might need to do SPNEGO > authentication. > > In any case, it's an example of how not to do things, and hopefully it will > be cleaned up at some point. > Daniel, Alan, thanks for the clarification. I didn't wanted to blame anybody - just looking for good arguments to prevent such code in our version of the JDK :) > -Alan > >
Re: Extending java.base module
On Wed, Feb 15, 2017 at 5:20 PM, Volker Simonis wrote: > > On Wed, Feb 15, 2017 at 5:16 PM, Alan Bateman wrote: > > On 15/02/2017 16:01, Daniel Fuchs wrote: > > > >> > >> In that specific case it's not java.base that depends > >> on java.security.jgss, but the application itself. > >> > >> So I would expect the application code to either require > >> java.security.jgss, or some higher level module for that > >> itself requires java.security.jgss, or jlink to be run with > >> command line options that explicitly add java.security.jgss > >> to the image. > > > > java.security.jgss exports an API so it will be resolved by default when the > > initial class is loaded from the class path. In addition, it provides a > > SecurityProvider implementation and so will be resolved because java.base > > `uses java.security.Provider`. For the jlink case then you are right, it > > needs someone to know that the application might need to do SPNEGO > > authentication. > > > > In any case, it's an example of how not to do things, and hopefully it will > > be cleaned up at some point. > > > While digging deeper into this topic, I found other such examples (and you can easily find more by searching for "Class.forName" in the base module :) sun.text.bidi.BidiBase$TextAttributeConstants (which is in the base module) has the following static initializer: // Make sure to load the AWT's TextAttribute class before using the constants, if any. static { try { Class.forName("java.awt.font.TextAttribute", true, null); } catch (ClassNotFoundException e) {} } static final JavaAWTFontAccess jafa = SharedSecrets.getJavaAWTFontAccess(); which is clearly another implicit dependency from java.base to java.desktop which contains java.awt.font.TextAttribute There's yet another such implicit dependency from java.base to jdk.net in sun.net.ext.ExtendedSocketOptions which has the following static initializer: static { try { // If the class is present, it will be initialized which // triggers registration of the extended socket options. Class c = Class.forName("jdk.net.ExtendedSocketOptions"); } catch (ClassNotFoundException e) { // the jdk.net module is not present => no extended socket options instance = new NoExtendedSocketOptions(); } } So I'm wondering if these all are examples of "how not to do things" which will be cleaned up eventually or are if there other reasons that this cleanup hasn't been done until now. I can imagine that if all the current, implicit dependencies would have been resolved by using services, service binding could lead to a much bigger dependency graph for the base module which would probably include most of the modules in the jdk. Not sure if this could have an negative performance impact on startup time? Wouldn't it be a good idea to have a list of all this implicit dependencies somewhere (preferable in JBS) with a short comment for each of them (like "should be fixed by using services", "will leave as is because it's required too early during initialization", "should remove dependency by refactoring the code", etc..) Thank you and best regards, Volker > > Daniel, Alan, thanks for the clarification. I didn't wanted to blame > anybody - just looking for good arguments to prevent such code in our > version of the JDK :) > > > -Alan > > > >