From alex.buckley at oracle.com Tue Jul 6 17:43:05 2021 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 6 Jul 2021 10:43:05 -0700 Subject: [External] : Re: Annotation Dependencies and Requires Static Transitive In-Reply-To: References: <353f78cf-6e41-9906-b3d3-ffbf76868b14@oracle.com> Message-ID: <5b29de72-71ce-de4d-8d93-90a53abea77a@oracle.com> Presumably this is a javac lint warning about how types referenced from an exported API (e.g., the return type of an exported public method) should themselves be exported. It's hard to tell from https://docs.oracle.com/en/java/javase/16/docs/specs/man/javac.html#option-Xlint-custom exactly which kind of warning it is, but `exports` is plausible. Types of annotations on the exported API should probably be excluded from that lint check, what ever the retention policy of those annotation types. (This feels like something that's come up before...) Alex On 6/7/2021 4:45 AM, Anand Beh wrote: > Thanks to you both for the advice. > > Following on your suggestions, Caffeine changed to "requires static". > However, javac now produces a warning about the lack of transitivity: > > warning: [exports] class Nullable in module > org.checkerframework.checker.qual is not indirectly exported using > requires transitive > > Is this a bug in javac or is it anything we should be worried about? > > Regards, > Anand > > On 6/3/21, Alex Buckley wrote: >> Even without `transitive`, requiring modules with `static` means that >> anyone who habitually builds their entire stack from source will still >> need the errorprone and checker-qual modules at compile time. >> >> There are no "run-time only" dependencies in module declarations, unless >> services come into play, which is not realistic here. As Remi said, >> `requires static` is your best bet. Annotation types that are exported >> by a third party such as Google, in order for people to annotate their >> personal codebases, are not really an API that those personal codebases >> need to export -- any fourth party program that wishes to inspect the >> annotations in your codebase needs to arrange its own dependency on the >> annotation types from the third party. >> >> Alex >> >> On 6/3/2021 1:10 PM, Anand Beh wrote: >>> Hello, >>> >>> The cache library Caffeine recently added a full module descriptor. It >>> has no runtime dependencies, but it depends on metadata annotations >>> from checker-qual and errorprone, for example @NotNull and >>> @CanIgnoreReturnValue. The module looks like this: >>> module com.github.benmanes.caffeine { >>> exports com.github.benmanes.caffeine.cache; >>> exports com.github.benmanes.caffeine.cache.stats; >>> >>> requires static transitive com.google.errorprone.annotations; >>> requires static transitive org.checkerframework.checker.qual; >>> } >>> >>> The annotations are not required at runtime, hence static. They're >>> visibly placed on public methods and return types, so that API clients >>> can benefit from them for the purposes of annotation-based null >>> analysis, kotlin interop, etc. As the annotations are part of the API, >>> they're marked transitive. >>> >>> However, the "transitive" aspect imposes some requirements on users. I >>> am wondering if there is a more correct way to declare these >>> annotation dependencies than static transitive. >>> >>> One user would like to avoid the presence of these annotations at >>> compile-time. For reference, here's the relevant discussion: >>> https://urldefense.com/v3/__https://github.com/ben-manes/caffeine/issues/535__;!!GqivPVa7Brio!P53mZvzj_tIsON7Z_5P-tzQ-IH1xOgXbL9XWhtMKgoiJj97GfzXgrsvPc8Z27rHccoc$ >>> >>> I'm not a maintainer of caffeine, though I was involved in its >>> modularization. >>> >>> Regards, >>> Anand >>> >> From gunnar at hibernate.org Thu Jul 22 19:23:45 2021 From: gunnar at hibernate.org (Gunnar Morling) Date: Thu, 22 Jul 2021 21:23:45 +0200 Subject: Portable retrieval of resource bundles across module path and class path Message-ID: Hi all, I'm trying to figure out how a modular application should handle cross-module resource bundle look-ups, supporting running on both the module path and the class path. At a first look, resource bundle semantics in the two modes are at odds with each other: * When running on the classpath, all modules (or JARs, I should say) would have to provide their bundles in one and the same package, so ResourceBundle.getBundle() will pick them all up * When running on the module path, this would lead to split package issues, so each module has to use a distinct package and a ResourceBundleProvider which exposes the module's bundles So what I ended up doing is using the distinct package approach with RBP to make things work when running on the module path. When running on the class path, I'm using a ResourceBundleControlProvider whose returned Control adjusts bundle names to match the package naming pattern used in the different modules. Is this the recommended approach for solving the issue of making resource bundles in a modular application functional on module and class path? Or is there a simpler approach to achieve the same? Thanks a lot, --Gunnar From mandy.chung at oracle.com Thu Jul 22 22:30:56 2021 From: mandy.chung at oracle.com (Mandy Chung) Date: Thu, 22 Jul 2021 15:30:56 -0700 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: References: Message-ID: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> On 7/22/21 12:23 PM, Gunnar Morling wrote: > Hi all, > > I'm trying to figure out how a modular application should handle > cross-module resource bundle look-ups, supporting running on both the > module path and the class path. At a first look, resource bundle semantics > in the two modes are at odds with each other: > > * When running on the classpath, all modules (or JARs, I should say) would > have to provide their bundles in one and the same package, so > ResourceBundle.getBundle() will pick them all up > * When running on the module path, this would lead to split package issues, > so each module has to use a distinct package and a ResourceBundleProvider > which exposes the module's bundles > > So what I ended up doing is using the distinct package approach with RBP to > make things work when running on the module path. When running on the class > path, I'm using a ResourceBundleControlProvider whose returned Control > adjusts bundle names to match the package naming pattern used in the > different modules. > > Is this the recommended approach for solving the issue of making resource > bundles in a modular application functional on module and class path? Or is > there a simpler approach to achieve the same? I assume the class path is running on JDK <= 8, right?? Otherwise This is a reasonable approach for the resource bundles to load from both class path and module path when the resource bundles of a given name is packaged in multiple modules/JARs. We considered extending the default ResourceBundle.Control implementation to search with a repackaged bundle name as AbstractResourceBundleProvider::toBundleName in addition to the current default Control::toBundleName.? This incurs higher lookup cost (e.g. when it fails with the search of p.foo.Resource_, it will search p.foo..Resource.).? What you have is reasonable. Mandy From Alan.Bateman at oracle.com Fri Jul 23 06:25:25 2021 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 23 Jul 2021 07:25:25 +0100 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> Message-ID: <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> On 22/07/2021 23:30, Mandy Chung wrote: > > I assume the class path is running on JDK <= 8, right? Otherwise > > This is a reasonable approach for the resource bundles to load from > both class path and module path when the resource bundles of a given > name is packaged in multiple modules/JARs. > > We considered extending the default ResourceBundle.Control > implementation to search with a repackaged bundle name as > AbstractResourceBundleProvider::toBundleName in addition to the > current default Control::toBundleName.? This incurs higher lookup cost > (e.g. when it fails with the search of p.foo.Resource_, it will > search p.foo..Resource.).? What you have is reasonable. > > Mandy I agree. Also just to point out that the ResourceBundle javadoc has a "Resource Bundles and Named Modules" section to outline the options for deployed resource bundles as modules. For the migration scenario where the resources are in .properties format then the simplest may be to just deploy the JAR files on the module path where they will be treated as automatic modules.? There are no split package issues unless the resources have been compiled as .class files. -Alan From gunnar at hibernate.org Fri Jul 23 11:17:18 2021 From: gunnar at hibernate.org (Gunnar Morling) Date: Fri, 23 Jul 2021 13:17:18 +0200 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> Message-ID: Thanks a lot for your replies, Mandy and Alan! > I assume the class path is running on JDK <= 8, right? Otherwise Is there something missing after "Otherwise"? In fact, I'm looking for a way to run this - Java 1.8 on classpath - Java 9+ on classpath - Java 9+ on module path As I've learned by now, ResourceBundleControlProvider implementations on Java 1.8 will only be loaded via the extension mechanism, which often is impractical to use. So it seems I'll need to amend my solution described above to pass in the custom Control explicitly to ResourceBundle.getBundle(). I could use the ResourceBundleControlProvider in a MR JAR, but there seems not much of an advantage to doing that. > For the migration scenario where the resources are in .properties format then the simplest may be to just deploy the JAR files on the module path where they will be treated as automatic modules. In the scenario I have in mind (for educational purposes mainly) the JAR files contain the properties file as well code and should be usable as "proper" (i.e. non-automatic) modules as well as on the classpath. > There are no split package issues unless the resources have been compiled as .class files. That's very interesting, it's not what I observe. Having the *.properties in one and the same package in multiple modules triggers an error upon start-up: java.lang.LayerInstantiationException: Package dev.morling.greeter.fr in both module dev.morling.greeter.german and module dev.morling.greeter.french Here's the listing of the incriminating "German" JAR, note how only a single file is in that "fr" package: jar -tf german/target/resourceloading-test-german-1.0-SNAPSHOT.jar META-INF/MANIFEST.MF META-INF/ dev/ dev/morling/ dev/morling/greeter/ dev/morling/greeter/de/ dev/morling/greeter/de/internal/ dev/morling/greeter/fr/ META-INF/maven/ META-INF/maven/dev.morling.resourceloadingtest/ META-INF/maven/dev.morling.resourceloadingtest/resourceloading-test-german/ dev/morling/greeter/de/internal/GermanGreetingMessagesProvider.class ---> triggers conflict with the "french" module: dev/morling/greeter/fr/GreetingMessages_de.properties <--- META-INF/maven/dev.morling.resourceloadingtest/resourceloading-test-german/pom.xml META-INF/maven/dev.morling.resourceloadingtest/resourceloading-test-german/pom.properties module-info.class Anything obvious I'm missing here? I could push the complete example to a repo on GitHub if it helps. Thanks again, --Gunnar Am Fr., 23. Juli 2021 um 08:25 Uhr schrieb Alan Bateman < Alan.Bateman at oracle.com>: > On 22/07/2021 23:30, Mandy Chung wrote: > > > > I assume the class path is running on JDK <= 8, right? Otherwise > > > > This is a reasonable approach for the resource bundles to load from > > both class path and module path when the resource bundles of a given > > name is packaged in multiple modules/JARs. > > > > We considered extending the default ResourceBundle.Control > > implementation to search with a repackaged bundle name as > > AbstractResourceBundleProvider::toBundleName in addition to the > > current default Control::toBundleName. This incurs higher lookup cost > > (e.g. when it fails with the search of p.foo.Resource_, it will > > search p.foo..Resource.). What you have is reasonable. > > > > Mandy > I agree. Also just to point out that the ResourceBundle javadoc has a > "Resource Bundles and Named Modules" section to outline the options for > deployed resource bundles as modules. For the migration scenario where > the resources are in .properties format then the simplest may be to just > deploy the JAR files on the module path where they will be treated as > automatic modules. There are no split package issues unless the > resources have been compiled as .class files. > > -Alan > From Alan.Bateman at oracle.com Fri Jul 23 13:04:43 2021 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 23 Jul 2021 14:04:43 +0100 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> Message-ID: <7a27db46-6131-ec52-2188-7d43aa64b00c@oracle.com> On 23/07/2021 12:17, Gunnar Morling wrote: > : > > > For the migration scenario where the resources are in .properties > format then the simplest may be to just deploy the JAR files on the > module path where they will be treated as automatic modules. > > In the scenario I have in mind (for educational purposes mainly) the > JAR files contain the properties file as well code and should be > usable as "proper" (i.e. non-automatic) modules as well as on the > classpath. > > > There are no split package issues unless the resources have been > compiled as .class files. > > That's very interesting, it's not what I observe. Having the > *.properties in one and the same package in multiple modules triggers > an error upon start-up: I should have been clearer that the "no split package issues" comment was in the context of automatic modules where you "move" an existing JAR file containing .properties files from the class path to the module path. The .class files in the JAR file are used to determine the set of packages in the automatic module so if there are no .class files then it doesn't have any packages. That said, I'm surprised by the exception message as suggests there must be dev.morling.greeter.fr classes or resources? in the dev.morling.greeter.german module. I think I'd need to see the output of `jar --file= --describe-module` to be sure. -Alan From gunnar at hibernate.org Fri Jul 23 15:58:18 2021 From: gunnar at hibernate.org (Gunnar Morling) Date: Fri, 23 Jul 2021 17:58:18 +0200 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: <7a27db46-6131-ec52-2188-7d43aa64b00c@oracle.com> References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> <7a27db46-6131-ec52-2188-7d43aa64b00c@oracle.com> Message-ID: Am Fr., 23. Juli 2021 um 15:05 Uhr schrieb Alan Bateman < Alan.Bateman at oracle.com>: > On 23/07/2021 12:17, Gunnar Morling wrote: > > : > > > > > For the migration scenario where the resources are in .properties > > format then the simplest may be to just deploy the JAR files on the > > module path where they will be treated as automatic modules. > > > > In the scenario I have in mind (for educational purposes mainly) the > > JAR files contain the properties file as well code and should be > > usable as "proper" (i.e. non-automatic) modules as well as on the > > classpath. > > > > > There are no split package issues unless the resources have been > > compiled as .class files. > > > > That's very interesting, it's not what I observe. Having the > > *.properties in one and the same package in multiple modules triggers > > an error upon start-up: > > I should have been clearer that the "no split package issues" comment > was in the context of automatic modules where you "move" an existing JAR > file containing .properties files from the class path to the module > path. The .class files in the JAR file are used to determine the set of > packages in the automatic module so if there are no .class files then it > doesn't have any packages. > > That said, I'm surprised by the exception message as suggests there must > be dev.morling.greeter.fr classes or resources in the > dev.morling.greeter.german module. I think I'd need to see the output of > `jar --file= --describe-module` to be sure. > Yes, there is such resource which I had created for demo purposes (see the jar -tf output above): dev/morling/greeter/fr/GreetingMessages_de.properties Here's the output you requested: jar --describe-module --file german/target/resourceloading-test-german-1.0-SNAPSHOT.jar dev.morling.greeter.german at 1.0-SNAPSHOT jar:file:///.../resource-loading-test/german/target/resourceloading-test-german-1.0-SNAPSHOT.jar!/module-info.class requires dev.morling.greeter.base requires java.base mandated provides dev.morling.greeter.spi.GreetingMessagesProvider with dev.morling.greeter.de.internal.GermanGreetingMessagesProvider contains dev.morling.greeter.de.internal Interestingly, the dev.morling.greeter.fr package of the GreetingMessages_de.properties resource file isn't listed there, but it does trigger the split package error later on. Based on what you say, I take it that split package error *is* expected in this situation, it' surprising though to not see the package listed in the output of --describe-module. If you wanted to reproduce this yourself, the code is here: https://github.com/gunnarmorling/resource-bundle-test/tree/split-package Just run "mvn clean install" on JDK 9+, then "mvn exec:exec -pl :resourceloading-test-runner" for running the application, which should fail. Thanks, --Gunnar > -Alan > From Alan.Bateman at oracle.com Fri Jul 23 16:53:40 2021 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 23 Jul 2021 17:53:40 +0100 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> <7a27db46-6131-ec52-2188-7d43aa64b00c@oracle.com> Message-ID: <5228681a-84c2-b521-28e7-d35c48bc3da0@oracle.com> On 23/07/2021 16:58, Gunnar Morling wrote: > : > > > Yes, there is such resource which I had created for demo purposes (see > the jar -tf? output above): > > dev/morling/greeter/fr/GreetingMessages_de.properties > > Here's the output you requested: > > jar --describe-module --file > german/target/resourceloading-test-german-1.0-SNAPSHOT.jar > dev.morling.greeter.german at 1.0-SNAPSHOT > jar:file:///.../resource-loading-test/german/target/resourceloading-test-german-1.0-SNAPSHOT.jar!/module-info.class > requires dev.morling.greeter.base > requires java.base mandated > provides dev.morling.greeter.spi.GreetingMessagesProvider with > dev.morling.greeter.de.internal.GermanGreetingMessagesProvider > contains dev.morling.greeter.de.internal > > Interestingly, the dev.morling.greeter.fr > > package of the GreetingMessages_de.properties resource file isn't > listed there, but it does trigger the split package error later on. > Based on what you say, I take it that split package error *is* > expected in this situation, it' surprising though to not see the > package listed in the output of --describe-module. > > If you wanted to reproduce this yourself, the code is here: > > https://github.com/gunnarmorling/resource-bundle-test/tree/split-package > > > Just run "mvn clean install" on JDK 9+, then "mvn exec:exec -pl > :resourceloading-test-runner" for running the application, which > should fail. > Are you sure this always puts dev/morling/greeter/fr/GreetingMessages_de.properties into resourceloading-test-german-1.0-SNAPSHOT.jar? I'm quite sure the JAR file above doesn't have the fr resource but the JAR file in your previous mail seems to include it. In any case I think this discussion comes down to how the set of packages for an explicit module is determined. As explicit modules encapsulate their resources by default then it's the set of package derived from the non-directory entries that map to legal package names. This may be determined at packaging time by the "jar" tool that records the set of the packages in the ModulePackages class file attribute, or at run-time by scanning the contents of the JAR file. (We need to do a better job of specifying that [1]).? So it's different to automatic modules where they is no encapsulation and only the .class files are used to determine the set of packages. -Alan [1] https://bugs.openjdk.java.net/browse/JDK-8230298 From gunnar at hibernate.org Fri Jul 23 17:23:00 2021 From: gunnar at hibernate.org (Gunnar Morling) Date: Fri, 23 Jul 2021 19:23:00 +0200 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: <5228681a-84c2-b521-28e7-d35c48bc3da0@oracle.com> References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> <7a27db46-6131-ec52-2188-7d43aa64b00c@oracle.com> <5228681a-84c2-b521-28e7-d35c48bc3da0@oracle.com> Message-ID: > Are you sure this always puts dev/morling/greeter/fr/GreetingMessages_de.properties into > resourceloading-test-german-1.0-SNAPSHOT.jar? I'm quite sure the JAR file above doesn't > have the fr resource but the JAR file in your previous mail seems to include it. Yes, I'm quite sure, unless I'm doing something really stupid :) Here's the steps for reproducing: git clone git at github.com:gunnarmorling/resource-bundle-test.git git checkout split-package cd resource-bundle-test mvn clean install jar -tf german/target/resourceloading-test-german-1.0-SNAPSHOT.jar jar --describe-module --file german/target/resourceloading-test-german-1.0-SNAPSHOT.jar jar -tf shows the resource dev/morling/greeter/fr/GreetingMessages_de.properties, but jar --describe-module doesn't show the dev.morling.greeter.fr package. > I think this discussion comes down to how the set of packages for an explicit module is determined. Agreed, and I think I got my answers. I'll try and do a quick blog post about this topic, I haven't seen much discussion of ResourceBundleProvider for instance. Thanks a lot, --Gunnar Am Fr., 23. Juli 2021 um 18:54 Uhr schrieb Alan Bateman < Alan.Bateman at oracle.com>: > On 23/07/2021 16:58, Gunnar Morling wrote: > > : > > > Yes, there is such resource which I had created for demo purposes (see the > jar -tf output above): > > dev/morling/greeter/fr/GreetingMessages_de.properties > > Here's the output you requested: > > jar --describe-module --file > german/target/resourceloading-test-german-1.0-SNAPSHOT.jar > dev.morling.greeter.german at 1.0-SNAPSHOT > jar:file:///.../resource-loading-test/german/target/resourceloading-test-german-1.0-SNAPSHOT.jar!/module-info.class > requires dev.morling.greeter.base > requires java.base mandated > provides dev.morling.greeter.spi.GreetingMessagesProvider with > dev.morling.greeter.de.internal.GermanGreetingMessagesProvider > contains dev.morling.greeter.de.internal > > Interestingly, the dev.morling.greeter.fr > > package of the GreetingMessages_de.properties resource file isn't listed > there, but it does trigger the split package error later on. Based on what > you say, I take it that split package error *is* expected in this > situation, it' surprising though to not see the package listed in the > output of --describe-module. > > If you wanted to reproduce this yourself, the code is here: > > > https://github.com/gunnarmorling/resource-bundle-test/tree/split-package > > > Just run "mvn clean install" on JDK 9+, then "mvn exec:exec -pl > :resourceloading-test-runner" for running the application, which should > fail. > > Are you sure this always puts > dev/morling/greeter/fr/GreetingMessages_de.properties into > resourceloading-test-german-1.0-SNAPSHOT.jar? I'm quite sure the JAR file > above doesn't have the fr resource but the JAR file in your previous mail > seems to include it. > > In any case I think this discussion comes down to how the set of packages > for an explicit module is determined. As explicit modules encapsulate their > resources by default then it's the set of package derived from the > non-directory entries that map to legal package names. This may be > determined at packaging time by the "jar" tool that records the set of the > packages in the ModulePackages class file attribute, or at run-time by > scanning the contents of the JAR file. (We need to do a better job of > specifying that [1]). So it's different to automatic modules where they is > no encapsulation and only the .class files are used to determine the set of > packages. > > -Alan > > [1] https://bugs.openjdk.java.net/browse/JDK-8230298 > > > From Alan.Bateman at oracle.com Fri Jul 23 19:00:02 2021 From: Alan.Bateman at oracle.com (Alan Bateman) Date: Fri, 23 Jul 2021 20:00:02 +0100 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> <7a27db46-6131-ec52-2188-7d43aa64b00c@oracle.com> <5228681a-84c2-b521-28e7-d35c48bc3da0@oracle.com> Message-ID: On 23/07/2021 18:23, Gunnar Morling wrote: > : > > Yes, I'm quite sure, unless I'm doing something really stupid :) > Here's the steps for reproducing: > > git clone?git at github.com:gunnarmorling/resource-bundle-test.git > git checkout split-package > cd resource-bundle-test > mvn clean install > jar -tf german/target/resourceloading-test-german-1.0-SNAPSHOT.jar > jar --describe-module --file > german/target/resourceloading-test-german-1.0-SNAPSHOT.jar > > jar -tf shows the > resource?dev/morling/greeter/fr/GreetingMessages_de.properties, but > jar --describe-module doesn't show the dev.morling.greeter.fr > > package. I wasn't able to duplicate this and don't immediately see how how this project ends up with GreetingMessages_de.properties in dev/morling/greeter/fr. > > > I think this discussion comes down to how the set of packages for an > explicit module is determined. > > Agreed, and I think I got my answers. I'll try and do a quick blog > post about this topic, I haven't seen much discussion of > ResourceBundleProvider for instance. > ResourceBundleProvider is an advanced feature and most projects will likely get by by including the resources with the application. It's only when you separate them and wish to deploy the translations as modules that you need to know about this feature. -Alan From mandy.chung at oracle.com Fri Jul 23 19:13:42 2021 From: mandy.chung at oracle.com (Mandy Chung) Date: Fri, 23 Jul 2021 12:13:42 -0700 Subject: Portable retrieval of resource bundles across module path and class path In-Reply-To: References: <27fc0411-54de-879b-a1d3-d32e3a1c06c5@oracle.com> <4f14fc9b-fca1-f6cb-d536-e2456a0a2dad@oracle.com> Message-ID: On 7/23/21 4:17 AM, Gunnar Morling wrote: > Thanks a lot?for your replies, Mandy and Alan! > > > I assume the class path is running on JDK <= 8, right? Otherwise > > Is there something missing after "Otherwise"? It was a typo (I should have taken it out). > In fact, I'm looking for a way to run this > > - Java 1.8 on classpath > - Java 9+ on classpath > - Java 9+ on module path > > As I've learned by now, ResourceBundleControlProvider implementations > on Java 1.8 will only be loaded via the extension mechanism, which > often is impractical to use. So it seems I'll need to amend my > solution described above to pass in the custom Control explicitly to > ResourceBundle.getBundle(). I could use the > ResourceBundleControlProvider in a MR JAR, but there seems not much of > an advantage to doing that. > > > For the migration scenario where the resources are in .properties > format then the simplest may be to just deploy the JAR files on the > module path where they will be treated as automatic modules. > Right, this is indeed the simplest approach if the JAR file contain resource bundles in .properties format and no .class files in that package.? i.e. you can keep the resource bundles in `dev/morling/greeter` and deploy them as automatic modules. > In the scenario I have in mind (for educational purposes mainly) the > JAR files contain the properties file as well code and should be > usable as "proper" (i.e. non-automatic) modules as well as on the > classpath. It's common to have the resources packaged in separate JARs from the code and also an application includes all resources.?? This educational purpose demo shows an advanced feature. > > > There are no split package issues unless the resources have been > compiled as .class files. > > That's very interesting, it's not what I observe. Having the > *.properties in one and the same package in multiple modules triggers > an error upon start-up: > > ? ??java.lang.LayerInstantiationException: Package > dev.morling.greeter.fr > > in both module dev.morling.greeter.german and module > dev.morling.greeter.french this looks a little suspicious.?? GreetingMessages_de.properties should be expected in dev.morling.greeter. Mandy