From stephan.herrmann at berlin.de Tue Jul 10 15:56:02 2018 From: stephan.herrmann at berlin.de (Stephan Herrmann) Date: Tue, 10 Jul 2018 17:56:02 +0200 Subject: Does --add-exports imply --add-reads?? Message-ID: <2ab44131-7762-0433-ae9f-41bb8d911474@berlin.de> Hi, Given these sources: src/mod.one/module-info.java //--- module mod.one { requires transitive java.sql; } //--- src/mod.one/p/X.java //--- package p; public class X { public static java.sql.Connection getConnection() { return null; } } //--- src/mod.two/module-info.java //--- module mod.two { requires java.sql; } //--- src/mod.two/q/Y.java //--- package q; public class Y { java.sql.Connection con = p.X.getConnection(); } //--- Javac accepts the program when invoked like this: $ javac -d bin -source 9 --module-source-path src --add-exports mod.one/p=mod.two \ src/mod.one/module-info.java src/mod.one/p/X.java \ src/mod.two/module-info.java src/mod.two/q/Y.java How come javac allows Y.java to access p.X, although mod.two does not read mod.one? Is javac interpreting --add-exports to imply an additional --add-reads? best, Stephan From naman_nigam at rediffmail.com Tue Jul 10 18:06:49 2018 From: naman_nigam at rediffmail.com (Naman Nigam) Date: Tue, 10 Jul 2018 23:36:49 +0530 Subject: Does --add-exports imply --add-reads?? In-Reply-To: <2ab44131-7762-0433-ae9f-41bb8d911474@berlin.de> References: <2ab44131-7762-0433-ae9f-41bb8d911474@berlin.de> Message-ID: Well, this looks similar to what the increasing readability section in JEP-261 reads. As a consequence, code in the source module will be able to access types in > a package of the target module at both compile time and run time if that > package is exported via an exports clause in the source module's > declaration, an invocation of the Module::addExports method > , > or an instance of the --add-exports option Another doubt, if it could add to the current context, would be, what does the term "invocation of an unrestricted form" precisely mean in the document? Regards Naman Nigam On Tue, Jul 10, 2018 at 9:26 PM Stephan Herrmann wrote: > Hi, > > Given these sources: > > src/mod.one/module-info.java > //--- > module mod.one { > requires transitive java.sql; > } > //--- > > src/mod.one/p/X.java > //--- > package p; > public class X { > public static java.sql.Connection getConnection() { > return null; > } > } > //--- > > src/mod.two/module-info.java > //--- > module mod.two { > requires java.sql; > } > //--- > > src/mod.two/q/Y.java > //--- > package q; > public class Y { > java.sql.Connection con = p.X.getConnection(); > } > //--- > > Javac accepts the program when invoked like this: > > $ javac -d bin -source 9 --module-source-path src --add-exports > mod.one/p=mod.two \ > src/mod.one/module-info.java src/mod.one/p/X.java \ > src/mod.two/module-info.java src/mod.two/q/Y.java > > How come javac allows Y.java to access p.X, although mod.two does not read > mod.one? > > Is javac interpreting --add-exports to imply an additional --add-reads? > > best, > Stephan > From Alan.Bateman at oracle.com Wed Jul 11 08:18:17 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Wed, 11 Jul 2018 09:18:17 +0100 Subject: Does --add-exports imply --add-reads?? In-Reply-To: <2ab44131-7762-0433-ae9f-41bb8d911474@berlin.de> References: <2ab44131-7762-0433-ae9f-41bb8d911474@berlin.de> Message-ID: <87e41b74-c906-3fa2-a52f-4dedbd262a3c@oracle.com> There seems to be a javac bug here, I've created the following to track it: ??? https://bugs.openjdk.java.net/browse/JDK-8207032 -Alan On 10/07/2018 16:56, Stephan Herrmann wrote: > Hi, > > Given these sources: > > src/mod.one/module-info.java > //--- > module mod.one { > ??????? requires transitive java.sql; > } > //--- > > src/mod.one/p/X.java > //--- > package p; > public class X { > ??????? public static java.sql.Connection getConnection() { > ??????????????? return null; > ??????? } > } > //--- > > src/mod.two/module-info.java > //--- > module mod.two { > ??????? requires java.sql; > } > //--- > > src/mod.two/q/Y.java > //--- > package q; > public class Y { > ?? java.sql.Connection con = p.X.getConnection(); > } > //--- > > Javac accepts the program when invoked like this: > > $ javac -d bin -source 9 --module-source-path src --add-exports > mod.one/p=mod.two \ > ?? src/mod.one/module-info.java src/mod.one/p/X.java \ > ?? src/mod.two/module-info.java src/mod.two/q/Y.java > > How come javac allows Y.java to access p.X, although mod.two does not > read mod.one? > > Is javac interpreting --add-exports to imply an additional --add-reads? > > best, > Stephan From david.lloyd at redhat.com Thu Jul 12 14:37:51 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 12 Jul 2018 09:37:51 -0500 Subject: Module "java.se" is now missing from the boot layer Message-ID: In the most recent EA, calling ModuleLayer.boot().findModule("java.se") now appears to return an empty Optional, which is a change in behavior compared to 9/10 AFAICT. However the module does appear in the output of "java --list-modules". -- - DML From david.lloyd at redhat.com Thu Jul 12 14:40:39 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 12 Jul 2018 09:40:39 -0500 Subject: Module "java.se" is now missing from the boot layer In-Reply-To: References: Message-ID: It does work if you manually add "java.se" to the command line via "--add-modules" though. Was this an intentional change? On Thu, Jul 12, 2018 at 9:37 AM David Lloyd wrote: > > In the most recent EA, calling > ModuleLayer.boot().findModule("java.se") now appears to return an > empty Optional, which is a change in behavior compared to 9/10 AFAICT. > > However the module does appear in the output of "java --list-modules". > -- > - DML -- - DML From david.lloyd at redhat.com Thu Jul 12 14:43:50 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 12 Jul 2018 09:43:50 -0500 Subject: Module "java.se" is now missing from the boot layer In-Reply-To: References: Message-ID: I guess this was a result of: > The webrev with the proposed changes is here: > http://cr.openjdk.java.net/~alanb/8197532/webrev/ > > The CSR for the change is linked from the bug. The only behavioral > impact is that the "java.se" aggregator module is not resolved resolved > (at least not unless there is an API-exporting or service provider > module in the run-time image that requires java.se). Which makes sense *except* that in this case I'm launching in classpath mode. Do we want java.se to be unresolved by default in this case? (Sorry for the rambling thread, I'm juggling a few things here) On Thu, Jul 12, 2018 at 9:40 AM David Lloyd wrote: > > It does work if you manually add "java.se" to the command line via > "--add-modules" though. Was this an intentional change? > On Thu, Jul 12, 2018 at 9:37 AM David Lloyd wrote: > > > > In the most recent EA, calling > > ModuleLayer.boot().findModule("java.se") now appears to return an > > empty Optional, which is a change in behavior compared to 9/10 AFAICT. > > > > However the module does appear in the output of "java --list-modules". > > -- > > - DML > > > > -- > - DML -- - DML From david.lloyd at redhat.com Thu Jul 12 14:56:09 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 12 Jul 2018 09:56:09 -0500 Subject: Module "java.se" is now missing from the boot layer In-Reply-To: References: Message-ID: I see now that the original change applied to classpath mode. I'm going to go have some caffeine now, thanks. On Thu, Jul 12, 2018 at 9:43 AM David Lloyd wrote: > > I guess this was a result of: > > > The webrev with the proposed changes is here: > > http://cr.openjdk.java.net/~alanb/8197532/webrev/ > > > > The CSR for the change is linked from the bug. The only behavioral > > impact is that the "java.se" aggregator module is not resolved resolved > > (at least not unless there is an API-exporting or service provider > > module in the run-time image that requires java.se). > > Which makes sense *except* that in this case I'm launching in > classpath mode. Do we want java.se to be unresolved by default in > this case? > > (Sorry for the rambling thread, I'm juggling a few things here) > On Thu, Jul 12, 2018 at 9:40 AM David Lloyd wrote: > > > > It does work if you manually add "java.se" to the command line via > > "--add-modules" though. Was this an intentional change? > > On Thu, Jul 12, 2018 at 9:37 AM David Lloyd wrote: > > > > > > In the most recent EA, calling > > > ModuleLayer.boot().findModule("java.se") now appears to return an > > > empty Optional, which is a change in behavior compared to 9/10 AFAICT. > > > > > > However the module does appear in the output of "java --list-modules". > > > -- > > > - DML > > > > > > > > -- > > - DML > > > > -- > - DML -- - DML From webczat_200 at poczta.onet.pl Sat Jul 14 13:00:31 2018 From: webczat_200 at poczta.onet.pl (=?UTF-8?Q?Micha=c5=82_Zegan?=) Date: Sat, 14 Jul 2018 15:00:31 +0200 Subject: ClassLoader.getResources vs Module.getResourceAsStream Message-ID: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> Hello. When reading docs for jdk9 and jdk10 it seems that those methods work in a bit different way when it goes to encapsulation: Module.getResourceAsStream will retrieve the resource without a problem if a package is opened to the caller module, probably including the fact that it will find a resource when the calling module is the same as one represented by the module object. But, ClassLoader.getResources and other resource methods seem to require unconditional package open. Why? I don't quite understand that distinction. From Alan.Bateman at oracle.com Sat Jul 14 15:31:14 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sat, 14 Jul 2018 16:31:14 +0100 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> Message-ID: <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> On 14/07/2018 14:00, Micha? Zegan wrote: > Hello. > When reading docs for jdk9 and jdk10 it seems that those methods work in > a bit different way when it goes to encapsulation: > Module.getResourceAsStream will retrieve the resource without a problem > if a package is opened to the caller module, probably including the fact > that it will find a resource when the calling module is the same as one > represented by the module object. > But, ClassLoader.getResources and other resource methods seem to require > unconditional package open. > Why? I don't quite understand that distinction. ClassLoaders, especially in a delegation chain, have no notion of "who" is trying to locate the resource. The ClassLoader.getResourceXXX methods are also not final. All told, the ClassLoader.getResourceXXX cannot reliably support qualified opens so this is why they are specified to only locate resources in modules when the package is open to all modules. The general guideline is to use Class or Module getResourceXXX when you want to locate a resource in your own module or another specific module. Use ClassLoader.getResourceXXX when you want to search the class path. If you follow that then it makes it a lot easier to migrate existing code to modules. -Alan From webczat_200 at poczta.onet.pl Sat Jul 14 15:38:02 2018 From: webczat_200 at poczta.onet.pl (=?UTF-8?Q?Micha=c5=82_Zegan?=) Date: Sat, 14 Jul 2018 17:38:02 +0200 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> Message-ID: What is then a recommendation for searching for all resources with name x that i can access? Something like load all configuration including some kind of extensions. I cannot list resources easily. W dniu 14.07.2018 o?17:31, Alan Bateman pisze: > On 14/07/2018 14:00, Micha? Zegan wrote: >> Hello. >> When reading docs for jdk9 and jdk10 it seems that those methods work in >> a bit different way when it goes to encapsulation: >> Module.getResourceAsStream will retrieve the resource without a problem >> if a package is opened to the caller module, probably including the fact >> that it will find a resource when the calling module is the same as one >> represented by the module object. >> But, ClassLoader.getResources and other resource methods seem to require >> unconditional package open. >> Why? I don't quite understand that distinction. > ClassLoaders, especially in a delegation chain, have no notion of "who" > is trying to locate the resource. The ClassLoader.getResourceXXX methods > are also not final. All told, the ClassLoader.getResourceXXX cannot > reliably support qualified opens so this is why they are specified to > only locate resources in modules when the package is open to all modules. > > The general guideline is to use Class or Module getResourceXXX when you > want to locate a resource in your own module or another specific module. > Use ClassLoader.getResourceXXX when you want to search the class path. > If you follow that then it makes it a lot easier to migrate existing > code to modules. > > -Alan From Alan.Bateman at oracle.com Sat Jul 14 15:53:08 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Sat, 14 Jul 2018 16:53:08 +0100 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> Message-ID: On 14/07/2018 16:38, Micha? Zegan wrote: > What is then a recommendation for searching for all resources with name > x that i can access? Something like load all configuration including > some kind of extensions. I cannot list resources easily. > Services is the cleaner way to do this kind of thing, esp. if you have flexibility to change the code and move away from legacy ClassLoader getResources. -Alan From webczat_200 at poczta.onet.pl Sat Jul 14 15:58:53 2018 From: webczat_200 at poczta.onet.pl (=?UTF-8?Q?Micha=c5=82_Zegan?=) Date: Sat, 14 Jul 2018 17:58:53 +0200 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> Message-ID: <796832dc-18e4-cb7c-8e61-9e750ae4457f@poczta.onet.pl> It is a completely new code. It is not modularized for now because some dependencies are not modularized, but I want it to be compatible to ease later modularization. My actual goal is to load xml files defining and configuring some factories, from all modules that contain them. Not sure how would you do that with services? W dniu 14.07.2018 o?17:53, Alan Bateman pisze: > On 14/07/2018 16:38, Micha? Zegan wrote: >> What is then a recommendation for searching for all resources with name >> x that i can access? Something like load all configuration including >> some kind of extensions. I cannot list resources easily. >> > Services is the cleaner way to do this kind of thing, esp. if you have > flexibility to change the code and move away from legacy ClassLoader > getResources. > > -Alan From sander.mak at luminis.eu Mon Jul 16 06:52:41 2018 From: sander.mak at luminis.eu (Sander Mak) Date: Mon, 16 Jul 2018 06:52:41 +0000 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: <796832dc-18e4-cb7c-8e61-9e750ae4457f@poczta.onet.pl> References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> <796832dc-18e4-cb7c-8e61-9e750ae4457f@poczta.onet.pl> Message-ID: In that case you'd expose the factories through the services mechanism (`provides com.acme.api.MyWidgetFactory with com.acme.factories.XmlBasedWidgetFactory` in the module descriptor). Or, if you must expose the XML itself to the outside world rather than the factories, you can create a service that offers the XML as String or InputStream. Each module then has an implementation reading its own encapsulated XML. The former approach is preferable IMO. Note that you can also use the services mechanism without module descriptors by placing text files in META-INF/services (https://docs.oracle.com/javase/tutorial/ext/basics/spi.html). However, if your code isn't a reusable library itself, you can also choose to modularize your own code and depend on non-modularized dependencies through their automatic module name (http://branchandbound.net/blog/java/2017/12/automatic-module-name/). Sander On 14 Jul 2018, at 17:58, Micha? Zegan > wrote: It is a completely new code. It is not modularized for now because some dependencies are not modularized, but I want it to be compatible to ease later modularization. My actual goal is to load xml files defining and configuring some factories, from all modules that contain them. Not sure how would you do that with services? W dniu 14.07.2018 o 17:53, Alan Bateman pisze: On 14/07/2018 16:38, Micha? Zegan wrote: What is then a recommendation for searching for all resources with name x that i can access? Something like load all configuration including some kind of extensions. I cannot list resources easily. Services is the cleaner way to do this kind of thing, esp. if you have flexibility to change the code and move away from legacy ClassLoader getResources. -Alan From forax at univ-mlv.fr Mon Jul 16 08:09:22 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 16 Jul 2018 10:09:22 +0200 (CEST) Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> <796832dc-18e4-cb7c-8e61-9e750ae4457f@poczta.onet.pl> Message-ID: <2037297630.105562.1531728562532.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Sander Mak" > ?: "jigsaw-dev" > Envoy?: Lundi 16 Juillet 2018 08:52:41 > Objet: Re: ClassLoader.getResources vs Module.getResourceAsStream > In that case you'd expose the factories through the services mechanism > (`provides com.acme.api.MyWidgetFactory with > com.acme.factories.XmlBasedWidgetFactory` in the module descriptor). Or, if you > must expose the XML itself to the outside world rather than the factories, you > can create a service that offers the XML as String or InputStream. Each module > then has an implementation reading its own encapsulated XML. The former > approach is preferable IMO. > > Note that you can also use the services mechanism without module descriptors by > placing text files in META-INF/services > (https://docs.oracle.com/javase/tutorial/ext/basics/spi.html). However, if your > code isn't a reusable library itself, you can also choose to modularize your > own code and depend on non-modularized dependencies through their automatic > module name > (http://branchandbound.net/blog/java/2017/12/automatic-module-name/). > You have to do both, each service declared in a module-info MUST be declared in META-INF/services too because you can use a modular jar in the classpath as a plain old jar. Alan, we should patch jar to warn when there is a module-info.class that declare services with no corresponding META-INF/services. > Sander > R?mi > On 14 Jul 2018, at 17:58, Micha? Zegan > > wrote: > > It is a completely new code. It is not modularized for now because some > dependencies are not modularized, but I want it to be compatible to ease > later modularization. > My actual goal is to load xml files defining and configuring some > factories, from all modules that contain them. Not sure how would you do > that with services? > > W dniu 14.07.2018 o 17:53, Alan Bateman pisze: > On 14/07/2018 16:38, Micha? Zegan wrote: > What is then a recommendation for searching for all resources with name > x that i can access? Something like load all configuration including > some kind of extensions. I cannot list resources easily. > > Services is the cleaner way to do this kind of thing, esp. if you have > flexibility to change the code and move away from legacy ClassLoader > getResources. > > -Alan From scolebourne at joda.org Mon Jul 16 10:06:43 2018 From: scolebourne at joda.org (Stephen Colebourne) Date: Mon, 16 Jul 2018 11:06:43 +0100 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> Message-ID: In my experience (as I've written before), ClassLoader.getResources is perhaps the biggest pain point I've experienced in trying to move beyond Java 8. The method seems to have been very widely used, and IMO was considered to be preferred over Class.getResourceXxx. And it is very confusing to use once modules come into play. There is no simple replacement for the ability to search for resources across jar files. Module.getResourceXxx cannot be used as it only returns one resource from the unamed module, when there could be many (and the docs are no particularly clear on what they do). This is very inconvenient. Returning a stream instead of a URL also typically involves wider code change to adopt. In addition, many projects are still on Java 8, so can't use java.lang.Module anyway. ServiceLoader is completely the wrong solution for config files. Its far too heavyweight. My solution (which I think is pretty horrible) has been to move config files to be under META-INF. Old location: org/joda/convert New location: META-INF/org/joda/convert Its backwards incompatible to downstream users, but at least it works with ClassLoader.getResources Given there are no good solutions to normal coding problems, I can't help feeling that Jigsaw didn't get resource access quite right. Stephen On 14 July 2018 at 16:31, Alan Bateman wrote: > On 14/07/2018 14:00, Micha? Zegan wrote: >> >> Hello. >> When reading docs for jdk9 and jdk10 it seems that those methods work in >> a bit different way when it goes to encapsulation: >> Module.getResourceAsStream will retrieve the resource without a problem >> if a package is opened to the caller module, probably including the fact >> that it will find a resource when the calling module is the same as one >> represented by the module object. >> But, ClassLoader.getResources and other resource methods seem to require >> unconditional package open. >> Why? I don't quite understand that distinction. > > ClassLoaders, especially in a delegation chain, have no notion of "who" is > trying to locate the resource. The ClassLoader.getResourceXXX methods are > also not final. All told, the ClassLoader.getResourceXXX cannot reliably > support qualified opens so this is why they are specified to only locate > resources in modules when the package is open to all modules. > > The general guideline is to use Class or Module getResourceXXX when you want > to locate a resource in your own module or another specific module. Use > ClassLoader.getResourceXXX when you want to search the class path. If you > follow that then it makes it a lot easier to migrate existing code to > modules. > > -Alan From Alan.Bateman at oracle.com Mon Jul 16 10:47:19 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 16 Jul 2018 11:47:19 +0100 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> Message-ID: On 16/07/2018 11:06, Stephen Colebourne wrote: > In my experience (as I've written before), ClassLoader.getResources is > perhaps the biggest pain point I've experienced in trying to move > beyond Java 8. The method seems to have been very widely used, and IMO > was considered to be preferred over Class.getResourceXxx. And it is > very confusing to use once modules come into play. Class.getResourceXXX is the better choice when locating ones own resources, ClassLoader.getResourceXX is for searching for a resource in other components, the ClassLoader provide some context on where to search. There are of course libraries that were using ClassLoader to locate their own resources and those cases may need some changes in the event that the code is migrated to an explicit module and the resources are encapsulated. If they aren't encapsulated then the existing code using the ClassLoader methods will work of course. > > There is no simple replacement for the ability to search for resources > across jar files. The ClassLoader resources and getResources method work as before and will locate resources in modular JARs when the resources are not encapsulated. > Module.getResourceXxx cannot be used as it only > returns one resource from the unamed module, when there could be many > (and the docs are no particularly clear on what they do). This is very > inconvenient. Module.getResourceXXX works with named modules too. -Alan From Alan.Bateman at oracle.com Mon Jul 16 10:49:31 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 16 Jul 2018 11:49:31 +0100 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: <2037297630.105562.1531728562532.JavaMail.zimbra@u-pem.fr> References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> <796832dc-18e4-cb7c-8e61-9e750ae4457f@poczta.onet.pl> <2037297630.105562.1531728562532.JavaMail.zimbra@u-pem.fr> Message-ID: <1150c5a4-e338-2d77-955e-c0ec66b422ff@oracle.com> On 16/07/2018 09:09, Remi Forax wrote: > : > > Alan, we should patch jar to warn when there is a module-info.class that declare services with no corresponding META-INF/services. > I'll create an issue in JIRA for that. As things stands, the `jar` tool does some sanity checks but it doesn't catch the case where the legacy services configuration file doesn't match the module declaration. That said, it probably needs the equivalent in one or more Maven plugins as they are likely using the java.util.jar API rather than the `jar` tool. -Alan From bear.amade at gmail.com Mon Jul 16 13:08:23 2018 From: bear.amade at gmail.com (Bernard Amade) Date: Mon, 16 Jul 2018 15:08:23 +0200 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> Message-ID: <3E5536AC-EC07-49F5-9B7D-FD6318D38462@gmail.com> > > ServiceLoader is completely the wrong solution for config files. Its > far too heavyweight. > after java 8 the case of internationalisation is the worst case of resource handling: - creating diverse resource files (for different cultural contexts) means they might be spread along different jars (you receive an app in your country - that uses a strange language- ... then you create a specific deployment jar and add it to the app) - since it is impossible to have the same "directory" (oups I mean "package") in different modules/jars it is required to create a special code to find the real directory this is super-clumsy! please find a simpler approach ! (even if it entails exceptions to some principles) thanks From Alan.Bateman at oracle.com Mon Jul 16 13:49:38 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 16 Jul 2018 14:49:38 +0100 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: <3E5536AC-EC07-49F5-9B7D-FD6318D38462@gmail.com> References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> <3E5536AC-EC07-49F5-9B7D-FD6318D38462@gmail.com> Message-ID: On 16/07/2018 14:08, Bernard Amade wrote > after java 8 > the case of internationalisation is the worst case of resource handling: > - creating diverse resource files (for different cultural contexts) means they might be spread along different jars > (you receive an app in your country - that uses a strange language- ... then you create a specific deployment jar and add it to the app) > - since it is impossible to have the same "directory" (oups I mean "package") in different modules/jars it is required to create a special code to find the real directory > this is super-clumsy! > please find a simpler approach ! (even if it entails exceptions to some principles) This sounds like a complaint about ResourceBundle. Best to start a new thread if you have issues or suggestions for how it can be improved. Also keep in mind that a huge effort went into getting ResourceBundle to work with modules and there are several options for deploying translations in different JAR files or modules (esp. if these translation are .properties files rather than compiled resources). The options are detailed in the ResourceBundle javadoc [1]. -Alan [1] https://download.java.net/java/early_access/jdk11/docs/api/java.base/java/util/ResourceBundle.html From webczat_200 at poczta.onet.pl Mon Jul 16 18:49:49 2018 From: webczat_200 at poczta.onet.pl (=?UTF-8?Q?Micha=c5=82_Zegan?=) Date: Mon, 16 Jul 2018 20:49:49 +0200 Subject: ClassLoader.getResources vs Module.getResourceAsStream In-Reply-To: References: <644a8624-9392-cc27-6613-d24e34d82815@poczta.onet.pl> <75f4e2d9-3823-8287-cb7e-c89566783b07@oracle.com> <796832dc-18e4-cb7c-8e61-9e750ae4457f@poczta.onet.pl> Message-ID: <2b663e96-e6ef-e4c8-8ff7-cef3169c30b5@poczta.onet.pl> Well, these are not stateless factories that you register as a service and then discover to later use them to create some objects. Those are factories that implement a specific algorithm like crypto algorithm, or that are adapters for a crypto library like for JCA, in the second case one factory class can be used to create many factories for many algorithms depending on properties set on them. Concrete algo instances are created when needed by connection objects. That is why I cannot register them as some kind of services, i need configuration to be able to define what algorithms are supported using what factory class with what configuration for each algorithm, and this would be ugly to do in code. And I would actually like for this mechanism to also load some extensions, like secondary files in other jars/modules that may register other algorithms that are not registered by core, using builtin or extension factory classes. I currently want to put that in META-INF that seems to be non-encapsulated. W dniu 16.07.2018 o?08:52, Sander Mak pisze: > In that case you'd expose the factories through the services mechanism (`provides com.acme.api.MyWidgetFactory with com.acme.factories.XmlBasedWidgetFactory` in the module descriptor). Or, if you must expose the XML itself to the outside world rather than the factories, you can create a service that offers the XML as String or InputStream. Each module then has an implementation reading its own encapsulated XML. The former approach is preferable IMO. > > Note that you can also use the services mechanism without module descriptors by placing text files in META-INF/services (https://docs.oracle.com/javase/tutorial/ext/basics/spi.html). However, if your code isn't a reusable library itself, you can also choose to modularize your own code and depend on non-modularized dependencies through their automatic module name (http://branchandbound.net/blog/java/2017/12/automatic-module-name/). > > Sander > > On 14 Jul 2018, at 17:58, Micha? Zegan > wrote: > > It is a completely new code. It is not modularized for now because some > dependencies are not modularized, but I want it to be compatible to ease > later modularization. > My actual goal is to load xml files defining and configuring some > factories, from all modules that contain them. Not sure how would you do > that with services? > > W dniu 14.07.2018 o 17:53, Alan Bateman pisze: > On 14/07/2018 16:38, Micha? Zegan wrote: > What is then a recommendation for searching for all resources with name > x that i can access? Something like load all configuration including > some kind of extensions. I cannot list resources easily. > > Services is the cleaner way to do this kind of thing, esp. if you have > flexibility to change the code and move away from legacy ClassLoader > getResources. > > -Alan > > From luke.hutch at gmail.com Thu Jul 19 01:13:36 2018 From: luke.hutch at gmail.com (Luke Hutchison) Date: Wed, 18 Jul 2018 19:13:36 -0600 Subject: ModuleLayer#layers() and Configuration#configurations() produces non-topological ordering In-Reply-To: References: <4273c33e-ce53-ae7d-f24e-7c986a292299@oracle.com> Message-ID: Hi Alan, I was just wondering if you could please comment on this issue I raised: On Mon, Jun 25, 2018 at 6:00 PM Luke Hutchison wrote: > I'm assuming that since more than one module may define classes in the > same package, it is possible to have the same class defined multiple times > in different layers. Therefore, if the intent of specifying that DFS should > be used for module resolution is that class definitions in shallower layers > should mask definitions of the same class in deeper layers, then > topological ordering does in fact matter -- because otherwise, as shown in > the example I gave, it is possible for deeper layers to be reached before > shallower layers. > My specific questions are: (1) Is it indeed possible for a class to be defined multiple times (potentially differently) in different module layers, using the same fully-qualified class name; and (2) If this is possible, are the intended semantics in this case for the class definition in descendant (child) layers to mask the class definition in ancestral (parent) layers -- similarly to how a class definition found earlier in the traditional classpath will mask other definitions of the same class later in the classpath? From david.lloyd at redhat.com Thu Jul 19 14:14:45 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 19 Jul 2018 09:14:45 -0500 Subject: 8197532: Re-examine policy for the default set of modules when compiling or running code on the class path In-Reply-To: <7e22b9a3-8e01-53d3-90e5-ee32f832b140@oracle.com> References: <7e22b9a3-8e01-53d3-90e5-ee32f832b140@oracle.com> Message-ID: I've run into a problem with the change in java.se resolution. There is, from what I can tell, no way to add the java.se module to the runtime that doesn't also break on Java 8. The "jdk.module.*" properties are blocked off so that approach doesn't work. Any recommendations? What about a way for the class path to express dependencies without having to be a module? On Tue, Jun 19, 2018 at 3:32 AM Alan Bateman wrote: > > > JEP 261 details how the default set of root modules is computed when > compiling code in the unnamed module or when running code and the main > class is loaded from the class path. I'd like to re-visit this policy > for JDK 11 with two motivations: > > 1. If jlink is used to create a run-time image that contains java.se and > other API-exporting java.* modules that aren't in Java SE then these > other modules will not be resolved by default when using this run-time > image to compile or run code on the class path. > > 2. The policy in JEP 261 was crafted to ensure that the java.corba and > Java EE modules are not resolved by default. These modules are proposed > to be removed in Java SE 11 (and were removed for the first build of JDK > 11) so the need to exclude these modules goes away. > > The proposal is to change the policy so that the default set of root > modules for the unnamed module is simply "the observable modules on the > upgrade module path or among the system modules that exports at least > one package, without qualification". > > As the policy is JDK-specific it means there aren't any specification > changes. The only docs change is to non-normative text in > java.lang.module's package description. > > Changing the policy requires small changes to both compile-time and > run-time. In addition we have the jlink "system modules" plugin that > implements this policy to generate the code used at run-time to > reconstitute the module descriptors for the default modules. > > Testing: For the most part, running the existing tests is sufficient as > the tests exercise all APIs and are mostly in the unnamed module. To > test the java.se plus other java.* modules, a new test is added that > creates a run-time image with "java.se" and a module named "java.json" > that exports an API. The resulting run-time image is used to compile and > code in the unnamed module (the JEP 330 support for single-file programs > makes this easy). > > The webrev with the proposed changes is here: > http://cr.openjdk.java.net/~alanb/8197532/webrev/ > > The CSR for the change is linked from the bug. The only behavioral > impact is that the "java.se" aggregator module is not resolved resolved > (at least not unless there is an API-exporting or service provider > module in the run-time image that requires java.se). > > -Alan -- - DML From Alan.Bateman at oracle.com Thu Jul 19 15:03:41 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 19 Jul 2018 16:03:41 +0100 Subject: 8197532: Re-examine policy for the default set of modules when compiling or running code on the class path In-Reply-To: References: <7e22b9a3-8e01-53d3-90e5-ee32f832b140@oracle.com> Message-ID: <4f3297e3-5a35-a603-815c-1669f46f69b8@oracle.com> On 19/07/2018 15:14, David Lloyd wrote: > I've run into a problem with the change in java.se resolution. There > is, from what I can tell, no way to add the java.se module to the > runtime that doesn't also break on Java 8. I think you need to explain what you are doing. JDK 8 doesn't know anything about modules or the "java.se" aggregator module. Is it possible that this is code that wants to fail if run on a run-time image that doesn't contain "java.se"? -Alan > The "jdk.module.*" > properties are blocked off so that approach doesn't work. > > Any recommendations? What about a way for the class path to express > dependencies without having to be a module? > From david.lloyd at redhat.com Thu Jul 19 15:27:32 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 19 Jul 2018 10:27:32 -0500 Subject: 8197532: Re-examine policy for the default set of modules when compiling or running code on the class path In-Reply-To: <4f3297e3-5a35-a603-815c-1669f46f69b8@oracle.com> References: <7e22b9a3-8e01-53d3-90e5-ee32f832b140@oracle.com> <4f3297e3-5a35-a603-815c-1669f46f69b8@oracle.com> Message-ID: On Thu, Jul 19, 2018 at 10:03 AM Alan Bateman wrote: > > On 19/07/2018 15:14, David Lloyd wrote: > > I've run into a problem with the change in java.se resolution. There > > is, from what I can tell, no way to add the java.se module to the > > runtime that doesn't also break on Java 8. > I think you need to explain what you are doing. JDK 8 doesn't know > anything about modules or the "java.se" aggregator module. Is it > possible that this is code that wants to fail if run on a run-time image > that doesn't contain "java.se"? When running on Java 9 or later, this code relies on being able to reference java.se, and more importantly, all of the modules that it includes, which worked OK on 9 and 10 but fails on 11. When running on Java 8, it uses the default parent class loader to load the relevant classes and resources. -- - DML From Alan.Bateman at oracle.com Thu Jul 19 18:12:35 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Thu, 19 Jul 2018 19:12:35 +0100 Subject: 8197532: Re-examine policy for the default set of modules when compiling or running code on the class path In-Reply-To: References: <7e22b9a3-8e01-53d3-90e5-ee32f832b140@oracle.com> <4f3297e3-5a35-a603-815c-1669f46f69b8@oracle.com> Message-ID: On 19/07/2018 16:27, David Lloyd wrote: > : > When running on Java 9 or later, this code relies on being able to > reference java.se, and more importantly, all of the modules that it > includes, which worked OK on 9 and 10 but fails on 11. When running > on Java 8, it uses the default parent class loader to load the > relevant classes and resources. > I think this needs a bit more context. The first part seems to be about enumerating the modules in java.se which doesn't need java.se in the boot layer. I can't quite connect that to the second part which seems to be about the default class loader for delegation (which didn't change in JDK 9 so I can't see the 8 vs. 9 issue). Is this something with the JBoss module system where it wants to do direct delegation to the modules in the boot layer? -Alan From webczat_200 at poczta.onet.pl Sat Jul 21 15:43:51 2018 From: webczat_200 at poczta.onet.pl (=?UTF-8?Q?Micha=c5=82_Zegan?=) Date: Sat, 21 Jul 2018 17:43:51 +0200 Subject: method handles and open packages Message-ID: <2ad9dd01-593e-7039-62d1-783560ec736e@poczta.onet.pl> Hello, If I use reflection, I can access every member of every package in a module if a module opens such package, and that includes private members. What, however, about using method handles for that purpose? Also, if you have a class in module a that wants to deserialize data to objects of classes in module b, then should module b open a package with those classes to a, or maybe, give the deserializer it's lookup object, in order for it to be able to access members of non exported non opened packages? It is for the case where the deserializer is called by the module b. Also I assume that I do not need access to non public members of classes, like I deserialize using public setters always. From forax at univ-mlv.fr Sat Jul 21 17:27:50 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 21 Jul 2018 17:27:50 +0000 Subject: method handles and open packages In-Reply-To: <2ad9dd01-593e-7039-62d1-783560ec736e@poczta.onet.pl> References: <2ad9dd01-593e-7039-62d1-783560ec736e@poczta.onet.pl> Message-ID: <50A6280D-DED1-479B-B541-CCB9120FB0D6@univ-mlv.fr> Hi, On July 21, 2018 3:43:51 PM UTC, "Micha? Zegan" wrote: >Hello, >If I use reflection, I can access every member of every package in a >module if a module opens such package, and that includes private >members. >What, however, about using method handles for that purpose? https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.html#privateLookupIn-java.lang.Class-java.lang.invoke.MethodHandles.Lookup- >Also, if you have a class in module a that wants to deserialize data to >objects of classes in module b, then should module b open a package >with >those classes to a, or maybe, give the deserializer it's lookup object, >in order for it to be able to access members of non exported non opened >packages? It is for the case where the deserializer is called by the >module b. Also I assume that I do not need access to non public members >of classes, like I deserialize using public setters always. R?mi -- Sent from my Android device with K-9 Mail. Please excuse my brevity. From webczat_200 at poczta.onet.pl Sat Jul 21 19:44:23 2018 From: webczat_200 at poczta.onet.pl (=?UTF-8?Q?Micha=c5=82_Zegan?=) Date: Sat, 21 Jul 2018 21:44:23 +0200 Subject: method handles and open packages In-Reply-To: <50A6280D-DED1-479B-B541-CCB9120FB0D6@univ-mlv.fr> References: <2ad9dd01-593e-7039-62d1-783560ec736e@poczta.onet.pl> <50A6280D-DED1-479B-B541-CCB9120FB0D6@univ-mlv.fr> Message-ID: <6dd59d1b-0f1e-eb30-78d7-fe0d61dab9ae@poczta.onet.pl> I would also believe that the unreflect methods would work for this case too if the reflected version had access checks already suppressed. W dniu 21.07.2018 o?19:27, Remi Forax pisze: > Hi, > > On July 21, 2018 3:43:51 PM UTC, "Micha? Zegan" wrote: >> Hello, >> If I use reflection, I can access every member of every package in a >> module if a module opens such package, and that includes private >> members. >> What, however, about using method handles for that purpose? > > https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.html#privateLookupIn-java.lang.Class-java.lang.invoke.MethodHandles.Lookup- > >> Also, if you have a class in module a that wants to deserialize data to >> objects of classes in module b, then should module b open a package >> with >> those classes to a, or maybe, give the deserializer it's lookup object, >> in order for it to be able to access members of non exported non opened >> packages? It is for the case where the deserializer is called by the >> module b. Also I assume that I do not need access to non public members >> of classes, like I deserialize using public setters always. > > R?mi > > > From forax at univ-mlv.fr Sat Jul 21 20:09:08 2018 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Sat, 21 Jul 2018 22:09:08 +0200 (CEST) Subject: method handles and open packages In-Reply-To: <6dd59d1b-0f1e-eb30-78d7-fe0d61dab9ae@poczta.onet.pl> References: <2ad9dd01-593e-7039-62d1-783560ec736e@poczta.onet.pl> <50A6280D-DED1-479B-B541-CCB9120FB0D6@univ-mlv.fr> <6dd59d1b-0f1e-eb30-78d7-fe0d61dab9ae@poczta.onet.pl> Message-ID: <1870261527.1603434.1532203748114.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Micha? Zegan" > ?: "Remi Forax" , "jigsaw-dev" > Envoy?: Samedi 21 Juillet 2018 21:44:23 > Objet: Re: method handles and open packages > I would also believe that the unreflect methods would work for this case > too if the reflected version had access checks already suppressed. yes, right ! if the signature of the method is fully known, you can use privateLookupIn, if you have only partial information and need other info (like an annotation, using a naming convention, etc) to find the method, then unreflect* is the way to go. R?mi > > W dniu 21.07.2018 o?19:27, Remi Forax pisze: >> Hi, >> >> On July 21, 2018 3:43:51 PM UTC, "Micha? Zegan" >> wrote: >>> Hello, >>> If I use reflection, I can access every member of every package in a >>> module if a module opens such package, and that includes private >>> members. >>> What, however, about using method handles for that purpose? >> >> https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.html#privateLookupIn-java.lang.Class-java.lang.invoke.MethodHandles.Lookup- >> >>> Also, if you have a class in module a that wants to deserialize data to >>> objects of classes in module b, then should module b open a package >>> with >>> those classes to a, or maybe, give the deserializer it's lookup object, >>> in order for it to be able to access members of non exported non opened >>> packages? It is for the case where the deserializer is called by the >>> module b. Also I assume that I do not need access to non public members >>> of classes, like I deserialize using public setters always. >> >> R?mi >> >> From david.lloyd at redhat.com Thu Jul 26 12:21:10 2018 From: david.lloyd at redhat.com (David Lloyd) Date: Thu, 26 Jul 2018 07:21:10 -0500 Subject: 8197532: Re-examine policy for the default set of modules when compiling or running code on the class path In-Reply-To: References: <7e22b9a3-8e01-53d3-90e5-ee32f832b140@oracle.com> <4f3297e3-5a35-a603-815c-1669f46f69b8@oracle.com> Message-ID: On Thu, Jul 19, 2018 at 1:12 PM Alan Bateman wrote: > > On 19/07/2018 16:27, David Lloyd wrote: > > : > > When running on Java 9 or later, this code relies on being able to > > reference java.se, and more importantly, all of the modules that it > > includes, which worked OK on 9 and 10 but fails on 11. When running > > on Java 8, it uses the default parent class loader to load the > > relevant classes and resources. > > > I think this needs a bit more context. The first part seems to be about > enumerating the modules in java.se which doesn't need java.se in the > boot layer. I can't quite connect that to the second part which seems to > be about the default class loader for delegation (which didn't change in > JDK 9 so I can't see the 8 vs. 9 issue). Is this something with the > JBoss module system where it wants to do direct delegation to the > modules in the boot layer? Right JBoss Modules loads and depends on JPMS modules by name. So without the ability to load java.se by default from a classpath JAR, I can't boot the same way on Java 8 as I do on Java 9 anymore. I'm thinking about a workaround where we no longer use java.se as a default dependency, but that's a compatibility breaker so it needs a "clever" solution. It would be nicer if I could just select modules to add from my boot JAR manifest (or some other similar solution that is implicitly ignored on Java 8). -- - DML From jonathan.gibbons at oracle.com Thu Jul 26 23:42:33 2018 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Thu, 26 Jul 2018 16:42:33 -0700 Subject: Improving module source path for javac and javadoc Message-ID: <1b252359-2428-e5c8-cea4-ae7242dde727@oracle.com> There has been some recent discussion over the use of the javac and javadoc `--module-source-path` options (and the lack of adequate documentation thereof). To help provide content for documentation, I created some examples, based on the use cases in the recent discussions, and came up against some issues that led me to some ideas for improving the way that the module source path for `javac` and `javadoc` can be set. As background, I note that the `--module-source-path` option was designed very early on in what is now the design of Jigsaw. It was designed when the collective mindset was about single instances of non-repeatable options, and it had to support the JDK source structure. It was also designed before the rewrite of the JDK build system that allowed much more flexibility in terms of computing and setting options. The module source path also has to support the ability to have a "leaky"[^1] path for the directories that provide the source for a single module, while maintaining the strong encapsulation that is desired for the overall set of modules on the module path. Because of all that, it has a relatively complicated syntax. It was intended to provide flexibility for a variety of use cases, and for the most part it succeeds, at the cost of some unfamiliar complexity. That being said, it has always made one fundamental assumption that prevents a category of use cases: the assumption is that there will always be a directory named for the module in the overall path for any directory containing source for the module. For example, the directory `my.module` in the following file tree for a module named `my.module`: /my/library/my.module/src/share/classes/module-info.java my/classes/C.java The problem arises when working with a set of modules that do not follow that file naming convention, which is now seen to arise for some folk when working on modularizing existing libraries. Curiously, the problem is less likely to arise with `javac`, because when compiling such a set of modules, you can compile the modules one at a time "bottom-up", using single-module mode and `--source-path`, placing all previously compiled modules on the module path with `--module-path`. But with `javadoc`, you are more likely to want to present the _source_ for all modules together to the tool, to be able to build a single documentation bundle for the overall set of modules. You can almost workaround the problem by (ab)using `--patch-module`, which allows you to specify a path to override the contents of a module, and for `javac` and? `javadoc`, you can put source in the patch path as well as classes. But `--patch-module` cannot be used to add arbitrary modules: any module being patched must also exist somewhere on the main module path. That workaround hints at a solution, and a corresponding follow-up discussion on naming. Proposal ======== Allow the module source path to be specified in a manner similar to the `--patch-module`. The argument to `--patch-module` is of the form: ???? `=` ( )* This would allow a specific path to be specified for the source code? of any individual module.? In the same way as for `--patch-module`, different values could be specified for different modules. Whether or not to add a new option or modify the existing option is discussed separately, later. Whatever the name of the option, it would be a repeatable option that can be specified once for each module to be compiled, allowing a standard (package-oriented) source path to be specified for each module. This is just a proposal about the syntactic form of how the module source path is specified; there is no change to the underlying semantics of the module source path. In particular, the effect in relation to any other options specifying the locations of modules (including `patch-module`) is not affected. Given the arcane nature of the value of the existing option, it is possible that we might wish to eliminate the existing mechanism over a suitable period of time. It has served its purpose, but the new proposal is a better, simpler replacement. The internal implementation for such a proposal is already supported at the API level: see [StandardJavaFileManager.setLocation][setLocation]. This API was added relatively late in JDK 9, to solve what was essentially the same problem, as encountered by IDEs wanting to configure a file manager through the API.? (This proposal can be viewed as surfacing that API to the command-line option.) Dropping the Old Form --------------------- While the existing form is concise for compilation environments with lots of modules, and with many source directories contributing to each module (such as shared source, platform-specific source, and generated source), that advantage is diminished in environments with only a few simple modules, which is the more common case. It may be that most users would prefer to always use the new form: while more verbose, it is conceptually much simpler and closer to existing mechanisms, like plain old source paths and the patch module path. The primary beneficiary of the existing form is the JDK build itself, but it should not be a big task to convert it to use the new form of the option if we should eventually decide the drop the old form. Naming ------ How should we provide such new functionality? 1. A new option, alongside `--module-source-path` 2. Allow an alternate syntax for the existing `--module-source-path` option Using a new option clearly provides the maximum isolation from the existing option at the cost of giving up on the obvious name for an improved option. The justification for the second choice is that the name is an obvious one and it is highly unlikely that any existing use of the `--module-source-path` option begins with `=`. The existing syntax and the proposed new syntax are sufficiently distinct that we could introduce the new form, and support both, until such time that we choose to retire the old form. ------ [^1]: "leaky": a convenient term used to describe the semantics of a traditional source path or classpath, such that the content of a container early in the path may hide like-named content later in the path. [setLocation]: https://docs.oracle.com/javase/9/docs/api/javax/tools/StandardJavaFileManager.html#setLocationForModule-javax.tools.JavaFileManager.Location-java.lang.String-java.util.Collection- From mandy.chung at oracle.com Fri Jul 27 20:12:06 2018 From: mandy.chung at oracle.com (mandy chung) Date: Fri, 27 Jul 2018 13:12:06 -0700 Subject: [12] RFR JDK-8202941: GenModuleInfoSource build tool does not detect missing semicolons Message-ID: <384079a7-6fb4-b733-7c24-0d0973b68035@oracle.com> GenModuleInfoSource build tool augments module-info.java to include platform-specific qualified exports/opens and uses/provides services. This fixes the build tool to catch syntax errors as closely as javac does. The build tool remains to allow duplicated provides until JDK-8208463 is resolved. http://cr.openjdk.java.net/~mchung/jdk12/webrevs/8202941/webrev.00/ Mandy From erik.joelsson at oracle.com Fri Jul 27 20:40:13 2018 From: erik.joelsson at oracle.com (Erik Joelsson) Date: Fri, 27 Jul 2018 13:40:13 -0700 Subject: [12] RFR JDK-8202941: GenModuleInfoSource build tool does not detect missing semicolons In-Reply-To: <384079a7-6fb4-b733-7c24-0d0973b68035@oracle.com> References: <384079a7-6fb4-b733-7c24-0d0973b68035@oracle.com> Message-ID: <769efac5-5395-f3dc-92cb-99f0d093edbd@oracle.com> Build change looks good. /Erik On 2018-07-27 13:12, mandy chung wrote: > GenModuleInfoSource build tool augments module-info.java to include > platform-specific qualified exports/opens and uses/provides services. > This fixes the build tool to catch syntax errors as closely as javac > does. The build tool remains to allow duplicated provides until > JDK-8208463 is resolved. > > http://cr.openjdk.java.net/~mchung/jdk12/webrevs/8202941/webrev.00/ > > Mandy From milendyankov at gmail.com Mon Jul 30 17:16:17 2018 From: milendyankov at gmail.com (Milen Dyankov) Date: Mon, 30 Jul 2018 19:16:17 +0200 Subject: override module with an alternative implementation in the child layer Message-ID: In response to a question posted on this list [1] some time ago, Alan Bateman stated "You can override *any* module (except java.base) with an alternative implementation in the child layer". Is that true for the standard JDK modules? If so, is there any documentation / code samples that explains how? The obvious naive approach to load standard module in a layer: ModuleFinder finder = ModuleFinder.ofSystem(); ModuleLayer bootLayer = ModuleLayer.boot(); Configuration cf = bootLayer.configuration().resolve(finder, ModuleFinder.of(), Set.of("java.sql")); ClassLoader scl = ClassLoader.getSystemClassLoader(); ModuleLayer layer1 = bootLayer.defineModulesWithOneLoader(cf, scl); results in Exception in thread "main" java.lang.LayerInstantiationException: Class loader (instance of): jdk/internal/loader/Loader tried to define prohibited package name: java.util.logging Regards, Milen [1] http://jigsaw-dev.1059479.n5.nabble.com/Whitelisting-modules-in-layers-td5717573.html#a5717574 From Alan.Bateman at oracle.com Mon Jul 30 18:17:23 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Mon, 30 Jul 2018 11:17:23 -0700 Subject: override module with an alternative implementation in the child layer In-Reply-To: References: Message-ID: On 30/07/2018 10:16, Milen Dyankov wrote: > In response to a question posted on this list [1] some time ago, Alan > Bateman stated "You can override *any* module (except java.base) with an > alternative implementation in the child layer". Is that true for the > standard JDK modules? If so, is there any documentation / code samples that > explains how? > The previous thread didn't get into this but the other restriction is that you can't contain modules that export java.* APIs in custom layers (javax.* APIs are not an issue). I don't have time to give a detailed reply just now but look for the following in the javadoc of the ModuleLayer defineModulesXXX methods: "In addition, a layer cannot be created if the configuration contains a module named "java.base", a configuration contains a module with a package named "java" or a package name starting with "java.", or the function to map a module name to a class loader returns null or the platform class loader" -Alan. From milendyankov at gmail.com Mon Jul 30 18:41:31 2018 From: milendyankov at gmail.com (Milen Dyankov) Date: Mon, 30 Jul 2018 20:41:31 +0200 Subject: override module with an alternative implementation in the child layer In-Reply-To: References: Message-ID: Thank you Alan, that is what I originally thought. It's just your comment in the other thread made me think there may be a possibility I was not aware of. So am I right to assume that any application server like software is expected to always run on top of all standard JDK modules that export "java.*" packages? I mean, say there is an application server that runs on top of "minimal" JPMS created with jlink. If the base layer of that application server does not have "java.sql" for example, there is essentially no way for it to load it dynamically, when a JAR or WAR that needs it is deployed, correct? On Mon, Jul 30, 2018 at 8:17 PM Alan Bateman wrote: > On 30/07/2018 10:16, Milen Dyankov wrote: > > In response to a question posted on this list [1] some time ago, Alan > > Bateman stated "You can override *any* module (except java.base) with an > > alternative implementation in the child layer". Is that true for the > > standard JDK modules? If so, is there any documentation / code samples > that > > explains how? > > > The previous thread didn't get into this but the other restriction is > that you can't contain modules that export java.* APIs in custom layers > (javax.* APIs are not an issue). I don't have time to give a detailed > reply just now but look for the following in the javadoc of the > ModuleLayer defineModulesXXX methods: > > "In addition, a layer cannot be created if the configuration contains a > module named "java.base", a configuration contains a module with a > package named "java" or a package name starting with "java.", or the > function to map a module name to a class loader returns null or the > platform class loader" > > -Alan. > > -- http://about.me/milen From Alan.Bateman at oracle.com Tue Jul 31 12:20:02 2018 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Tue, 31 Jul 2018 05:20:02 -0700 Subject: override module with an alternative implementation in the child layer In-Reply-To: References: Message-ID: <2b7560e0-1c40-36b6-b832-3a815b937515@oracle.com> On 30/07/2018 11:41, Milen Dyankov wrote: > : > > So am I right to assume that any application server like software is > expected to always run on top of all standard JDK modules that export > "java.*" packages? I mean, say there is an application server that runs on > top of "minimal" JPMS created with jlink. If the base layer of that > application server does not have "java.sql" for example, there is > essentially no way for it to load it dynamically, when a JAR or WAR that > needs it is deployed, correct? > One thing to say is the restriction on the java.* class name space is rooted in security and has been in the Java SE API specification for many releases. The VM enforcement around this goes back to JDK 1.2 at least. The specification was relaxed in Java SE 9 to allow java.* classes be defined to the platform class loader but going further, to allow java.* classes be defined by other class loaders, would require significant effort. Aside from java.base, there are 7 modules in Java SE with java.* APIs: java.datatransfer java.desktop java.instrument java.logging java.management java.net.http java.prefs java.rmi java.sql The long standing specified restriction on the java.* class name space and the matching restrictions in the ModuleLayer API, mean that you cannot load (or override) these 7 modules in a child layer created by defineModulesXXX APIs. In your case, the main application (container / app server) doesn't transitively require java.sql so this module is not in the boot layer. It can't dynamically load it (because it contains a java.* classes) so it has ensure that the above 7 modules are in the boot layer in order to support dynamically loading of application modules that might require one or more of these modules. In JEP 261 we document --add-modules ALL-DEFAULT for this purpose: "As a special case at run time, if is ALL-DEFAULT then the default set of root modules for the unnamed module, as defined above, is added to the root set. This is useful when the application is a container that hosts other applications which can, in turn, depend upon modules not required by the container itself." Could you use that? -Alan From milendyankov at gmail.com Tue Jul 31 13:33:51 2018 From: milendyankov at gmail.com (Milen Dyankov) Date: Tue, 31 Jul 2018 15:33:51 +0200 Subject: override module with an alternative implementation in the child layer In-Reply-To: <2b7560e0-1c40-36b6-b832-3a815b937515@oracle.com> References: <2b7560e0-1c40-36b6-b832-3a815b937515@oracle.com> Message-ID: Thank you for the clarification Alan, it seams ALL-DEFAULT does not work with jlink but that is OK as I can easily find those modules while running my assembly tool and pass the list to jlink. The only difference between what I find and what you posted (I assume 7 was a typo as your list contains 9 modules) is that there seems to be no ` java.net.http` module (at least not among the 99 modules shipped in 10.0.1 that I'm experimenting with) Thanks for your help. It's much appreciated. On Tue, Jul 31, 2018 at 2:20 PM Alan Bateman wrote: > On 30/07/2018 11:41, Milen Dyankov wrote: > > : > > > > So am I right to assume that any application server like software is > > expected to always run on top of all standard JDK modules that export > > "java.*" packages? I mean, say there is an application server that runs > on > > top of "minimal" JPMS created with jlink. If the base layer of that > > application server does not have "java.sql" for example, there is > > essentially no way for it to load it dynamically, when a JAR or WAR that > > needs it is deployed, correct? > > > One thing to say is the restriction on the java.* class name space is > rooted in security and has been in the Java SE API specification for > many releases. The VM enforcement around this goes back to JDK 1.2 at > least. The specification was relaxed in Java SE 9 to allow java.* > classes be defined to the platform class loader but going further, to > allow java.* classes be defined by other class loaders, would require > significant effort. > > Aside from java.base, there are 7 modules in Java SE with java.* APIs: > > java.datatransfer > java.desktop > java.instrument > java.logging > java.management > java.net.http > java.prefs > java.rmi > java.sql > > The long standing specified restriction on the java.* class name space > and the matching restrictions in the ModuleLayer API, mean that you > cannot load (or override) these 7 modules in a child layer created by > defineModulesXXX APIs. > > In your case, the main application (container / app server) doesn't > transitively require java.sql so this module is not in the boot layer. > It can't dynamically load it (because it contains a java.* classes) so > it has ensure that the above 7 modules are in the boot layer in order to > support dynamically loading of application modules that might require > one or more of these modules. In JEP 261 we document --add-modules > ALL-DEFAULT for this purpose: > > "As a special case at run time, if is ALL-DEFAULT then the > default set of root modules for the unnamed module, as defined above, is > added to the root set. This is useful when the application is a > container that hosts other applications which can, in turn, depend upon > modules not required by the container itself." > > Could you use that? > > -Alan > -- http://about.me/milen