-
Notifications
You must be signed in to change notification settings - Fork 418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't find ResourceBundle with JPMS #1420
Comments
Thank you for raising this! Looking at the javadoc for Resource Bundles in Named Modules, and ResourceBundleProvider, no, this is currently not yet supported in picocli as of version 4.6.1. I am not opposed to adding support for this. One thing to note is that in order to continue to only require Java 5 or higher at runtime, adding support for resource bundles in modules will require the use of reflection. It is likely that only the A potential issue is that picocli currently only requires Java 8 or higher to build the project. When running in continuous integration environments, picocli is built and all tests are executed on Java versions 8-16. Do you think you will be able to provide a pull request for this? |
I'm so sorry, but I not know picocli inside out to send a pull request.
I'm not sure if this will work with picocli, but how about using a multi release jar files and including picocli for java8 and picocli for java9 and higher in single jar file? |
This is the smallest gradle project that can reproduce this issue. unzip, cd and run:
|
Thank you for providing the sample project.
Understood, no problem. Let's leave this ticket open for someone who is willing to work on it. |
Of course. no problem too. Thank you. |
Interested in seeing this issue moving forward. How can we keep backward compatibility while supporting Java 9+ and modules? |
JPMS is not backward compatibility. upgrade path called --illegal-access option was removed in java17, but you can still use multi-release-jar. |
Might be much to ask to use MR-JARs as most of picocli is implemented as an annotation with embedded types. For this to work the class responsible for loading resources would have to move to a top level class, then a Java9+ compatible implementation may be placed in |
Mhh, divide into smaller milestones step by step. |
I’m assuming that the programmatic API (only the annotations give errors?) |
Yes. Using the programmatic API works with modules. |
FWIW These are the changes I had to make to Jarviz to turn it into a full modular CLI kordamp/jarviz@fd21b1f |
My initial thoughts on solving this would be:
Thoughts? Note to self: relevant documentation below:
|
👍
I suppose this will work as long as the module is open to |
True; that bit is already documented . |
@aalmiray @tasogare3710 Good news: What is needed is:
module mymodule {
requires info.picocli;
// Open this package for reflection to external frameworks.
opens mycommandpackage;
// THE BELOW DOES NOT WORK!
// The below syntax results in MissingResourceException: Can't find bundle for base name XXX
// opens mycommandpackage to info.picocli; // AVOID THIS
} |
Strange, as I do have an explicit opens to |
@aalmiray I thought you got it to work by calling the programmatic API? (So you are calling |
That is correct. I'm using the programmatic API form within the same module. |
Yes, so calling the programmatic API always works regardless of module stuff. What I am talking about is, in order to get the @tasogare3710 can you try to see if that resolves the issue for you also? |
@remkop
It looks like same as this issue. |
@tasogare3710 I tried the example project you attached to this ticket, and if I change the // picocli_i18n_test\app\src\main\java\module-info.java
module picotest {
requires java.base;
requires info.picocli;
opens picotest; // <--- this was missing
} The output:
I confirmed this works with either picocli 4.6.1 or 4.7.1.
No more I will update the picocli User Manual for Module Configuration accordingly. What is still unclear is why |
I'm sorry, my mistake. But that mistake not relevant this issue, so forget it.
this direct cause of this isssue. This call is same as It's strange it runs without problems if you use |
In short, have to find ResourceBundle from picotest module, but
|
@tasogare3710 Sorry but I disagree with your analysis. I tried what you suggested, but even calling This I added a sample subproject to the picocli repo. It has two JPMS modules, one CLI app that contains a resource bundle and one that tests the app and tests loading the resource bundle. That last test uses various APIs to load the resource bundle and none of them worked unless the module-info had |
It is because the caller of method is incorrect; there is a issue with the codebase that calls getBundle. |
@tasogare3710 I don't understand...
I believe I have evidence that disproves your hypothesis: This is the code for one of the tests, it does not use reflection and it clearly uses the correct // this test lives in the app-it module
@Test
public void testLoadBundleModular() throws Exception {
// the JpmsModularApp class lives in the app module
Module module = JpmsModularApp.class.getModule(); // this is the app module
// the picocli/test_jpms/modular_app/messages.properties file lives in the app module
ResourceBundle bundle = ResourceBundle.getBundle("picocli.test_jpms.modular_app.messages", module);
System.out.println(bundle);
System.out.println(bundle.getString("usage.headerHeading"));
} Now, this test only works if the
So it seems to me that it is necessary to have Are you suggesting that there is a way to make |
This is not my analysis but module mechanism. java8 and unconditionally open module do not protect a resource from this case. the MissingResourceException is caused by a security check failure in the open module. There seems to be a misunderstanding. |
There also seems to be some misunderstanding about reflection: ResourceBundle uses reflection, and JLS also describes it as follows https://docs.oracle.com/javase/specs/jls/se9/html/jls-7.html#jls-7.7.2
|
The first version of this comment sounded more defensive than I intended. Sorry about that; let me delete it and try again. Sorry @tasogare3710 I have trouble understanding your last few comments. This was the original problem statement:
I believe I provided a solution:
There are some tests (1 and 2) that I believe prove this solution works. After that, I did not understand your replies. 😅 Can you clarify if the proposed solution meets your requirements, or if there are further requirements? |
* add section Resource Bundles in JPMS Modules * add section JPMS Modules Internationalization (link)
I updated the user manual: |
ResourceBundle fails to load if the ResourceBundle is specified using the resourceBundle element of the CommandLine.Command annotation.
info.picocli/CommandLine$Model$Messages#createBundle is calling ResourceBundle#getBundle(String), so it seems to be looking for ResourceBundle from info.picocli module. Is there a way to specify the module in which the ResourceBundle or to use the ResourceBundleProvider?
The text was updated successfully, but these errors were encountered: