Re: IllegalAccessException trying to load a ResourceBundle in 9u181
On 2/12/18 12:36 PM, Vitaly Davidovich wrote: Hi all, I'm not sure if core-libs is the right mailing list for jigsaw/modules questions these days (rather than jigsaw-dev), so please feel free to forward this there if it's the more appropriate list. cc'ing jigsaw-dev I have the following code carried over from java 8 (actually much earlier than that, but that's beside the point): final Resource rb = ResourceBundle.getBundle("sun.security.util.AuthResources"); Resource bundle follows the same encapsulation rule as described in Module::getResourceAsStream [1] except that a resource bundle is considered as a resource regardless of its format. ResourceBundle.getBundle(String baseName) finds the specified resource bundle from the caller's module. It will first search the resource bundle local in the caller's module (via Module::getResourceAsStream) and then using the caller's class loader to search for the resource (via ClassLoader::getResourceAsStream). Since the caller is unnamed module in your case, for it to access "sun.security.util.AuthResources", java.base/sun.security.util has to be open unconditionally and there is no CLI option to do that. If you call ResourceBundle.getBundle("sun.security.util.AuthResources", Object.class.getModule()) specifying the module of the resource bundle, then you can break the encapsulation by `--add-opens java.base/sun.security.util=ALL-UNNAMED` I'm a bit surprised that you depend on JDK internal resource bundle. Can you help us understand why you use it? Mandy [1] https://download.java.net/java/jdk10/docs/api/java/util/ResourceBundle.html#getBundle(java.lang.String,java.util.Locale,java.lang.Module)
Strange observation: MethodHandle.invokeWithArguments() would not work, whereas Method.invoke() would with the very same arguments
In the process of adapting pure reflective code (a Rexx-Java bridge) to use MethodHandles on Java 9 instead, everything seems to be working out so far. In principle all invocations on the Java side are carried out by first using java.lang.reflect (Field, Method, Constructor) using the supplied arguments (if the arguments can be coerced to the respective parameterTypes it gets selected for invocation) and if a candidate is found an appropriate MethodHandle gets created, which then gets used to invoke the operation supplying the coerced arguments, if any. Over the weekend I finalized the basic changes and started to test against a set of sample/demo applications. --- While testing a rather complex one (an adaption of the JavaFX address book example enhanced with a BarChart, [1]), that exhibits a very strange behavior: when setting the values for the CategoryAxis supplying an ObservableList of the month names in the current Locale, using a MethodHandle and invoking it with invokeWithArguments() would yield (debug output): // // // RexxReflectJava9.processMethod(), ARRIVED: -> [INVOKE], tmpMethod=[public final void javafx.scene.chart.CategoryAxis.setCategories(javafx.collections.ObservableList)]: method=[SETCATEGORIES] in object=[rru.rexxArgs[1]="javafx.scene.chart.CategoryAxis@83278e1"/rru.bean="CategoryAxis[id=xAxis, styleClass=axis]"] // // // RexxReflectJava9.processMethod(), coercedArgs=[[[Ljava.lang.String;@57cfe770]].getClass().toString()=class [Ljava.lang.Object;, parameterTypes=[interface javafx.collections.ObservableList].getClass().toString()=class [Ljava.lang.Class;:, rru.funcArgs=[[[Ljava.lang.String;@57cfe770]].getClass().toString()=class [Ljava.lang.Object; // // :( RexxReflectJava9.processMethod(), MethodType for Method [public final void javafx.scene.chart.CategoryAxis.setCategories(javafx.collections.ObservableList)]: "(ObservableList)void" // // :( RexxReflectJava9.processMethod(): INSTANCE, mh.bindTo("CategoryAxis[id=xAxis, styleClass=axis]/class javafx.scene.chart.CategoryAxis").invokeWithArguments(...) // :) :) RexxReflectJava9.processMethod(), MethodHandle "MethodHandle(CategoryAxis,ObservableList)void" invocation caused a Throwable: java.lang.ClassCastException: java.base/[Ljava.lang.String; cannot be cast to java.base/java.lang.String The supplied ObservableList argument represents the month names and was created with the help of "javafx.collections.FXCollections.observableList()" and then using its "addAll(monthNames)" method to add the String array values returned by DateFormatSymbols.getMonths() to the list. The supplied argument array "rru.funcArgs" will be coerced according to the reflected "parameterTypes" array yielding the "coercedArgs" array; using java.util.Arrays.deepToString() gives: // // // RexxReflectJava9.processMethod(), coercedArgs=[[[Ljava.lang.String;@57cfe770]].getClass().toString()=class [Ljava.lang.Object;, parameterTypes=[interface javafx.collections.ObservableList].getClass().toString()=class [Ljava.lang.Class;:, rru.funcArgs=[[[Ljava.lang.String;@57cfe770]].getClass().toString()=class [Ljava.lang.Object; --- The story is much longer but after quite long debugging sessions, I turned on reflective invoke via tmpMethod instead of invoking the corresponding MethodHandle, which (surprisingly) works. Then, in the next step doing the same invocation via the corresponding MethodHandle immediately after the reflective invocation, allows that invocation to execute successfully as well! Please note, the supplied coerced argument is in both cases the same! Coercion occurs according to the "parameterTypes" returned by java.lang.reflect.Method which also is used for creating the MethodType in order to use a publicLookup.findVirtual(...). Or with other words: the coerced argument will be identical for both invocation types! Another strange observation in the success case is as follows: when using reflective invocation by default (and then only invoking the MethodHandle in the special case that the method "setCategories" is to be executed) the coerced argument supplied to java.util.Arrays.deepToString() will list the monthnames: // // // RexxReflectJava9.processMethod(), ARRIVED: -> [INVOKE], tmpMethod=[public final void javafx.scene.chart.CategoryAxis.setCategories(javafx.collections.ObservableList)]: method=[SETCATEGORIES] in object=[rru.rexxArgs[1]="javafx.scene.chart.CategoryAxis@2d809949"/rru.bean="CategoryAxis[id=xAxis, styleClass=axis]"] // // // RexxReflectJava9.processMethod(), coercedArgs=[[January, February, March, April, May, June, July, August, September, October, November, December, ]].getClass().toString()=class [Ljava.lang.Object;, parameterTypes=[interface
Re: Signing jlink code for macOS on other platforms
2018/2/12 3:44:07 -0800, Mark Raynsford: > ... > > Are there any plans to implement anything that's capable of signing > macOS binaries and resources in a platform-independent way so that > jlink-produced distributions can work without warnings? No. > Is that even a > reasonable thing to request? I've no idea how "private" Apple keep > their signing implementation. It's certainly reasonable, but as you suggest it would require an implementation of Apple's signing algorithm that runs on non-macOS systems. I have no idea if such a thing exists or is even possible. - Mark
Re: RFR JDK-8170114 jimage extract to not an empty directory overwrites content of the directory
2018/2/11 23:10:46 -0800, Michal Vala: > On 02/10/2018 11:25 AM, Alan Bateman wrote: >> ... >> >> I think the `jimage extract --dir ` scenario >> needs >> discussion. If is a non-directory file then jimage has to >> fail, >> I don't expect disagreement on that. For the case where it is an existing >> directory then the options seem to be: >> >> 1. Extract into the existing directory (existing JDK 9 and JDK 10 behavior) >> 2. Fail if it's not empty (your patch) >> 3. Fail if it exists (Mandy's mail, the motivation being to keep it >> consistent >> with jlink) >> >> I view `jimage extract --dir ` as being similar to `unzip -d ` so >> I >> don't think existing behavior (#1) is incorrect, the only issue is that it >> silently overrides files whereas unzip will prompt before overriding (unless >> you >> specify -o). The `jar` tool, and legacy `tar` tool side with `jimage` and >> are >> happy to silently replace existing files. >> >> What would you think about focusing on the override case instead of >> disallowing >> extracting into an existing non-empty directory? I realize this is more work >> as >> it means deciding on whether to prompt, warn or fail. It also means thinking >> about the equivalent of unzip -o to allowing existing files be replaced. > > Unzip prompts user for individual files and I'm not sure whether it's a good > option here. Maybe prompt user at the beginning that directory is not empty > and > there is a risk that files there might be overwritten continue y/n? CLI tools that prompt the user are difficult to use in scripts, so I advise against that. jimage is a diagnostic tool meant for rare and specialized use. I think its current behavior (extract into an existing directory) is fine, and I can imagine use cases where that might actually be desired. - Mark
Accessing dependency version information
Hi! I think recording module version information is a really underappreciated feature in Java 9+. The module's own version shows up in many places, which I like. I think it could be added to `java --show-module-resolution`, too. It is much harder to access the versions of the dependencies against which a module was compiled. I thought I'd like it when it showed up in `jar --describe-module`, but I can see why "requires org.lib@1.2" is too easy to misinterpret. Maybe another way could be found to make this information available on the command line (i.e. without having to use `ModuleDeclaration`). so long ... Nicolai -- PGP Key: http://keys.gnupg.net/pks/lookup?op=vindex=0xCA3BAD2E9CCCD509 Web: http://codefx.org a blog about software development https://www.sitepoint.com/java high-quality Java/JVM content http://do-foss.de Free and Open Source Software for the City of Dortmund Twitter: https://twitter.com/nipafx
Re: Loading resource bundles across module boundaries
No matter what I do, there's always one document I didn't look at. :/ As usual, thank you very much! On 11.02.2018 21:48, Alan Bateman wrote: > > > On 11/02/2018 15:31, Nicolai Parlog wrote: >> : >> I interpreted this to mean that, without registering services, named >> modules can only load bundles from themselves. But in my experiments I >> could also load resource bundles from other modules as long as the >> package containing them was open. >> >> Did I make a mistake? Did I misinterpret the Javadoc? Is that behavior >> buggy? >> > The behavior is correct but isn't clearly covered in the Java SE 9 > javadoc. Mandy has improved the javadoc for Java SE 10 [1] so it's much > clearer and covers all the scenarios. > > -Alan > > [1] > https://download.java.net/java/jdk10/docs/api/java/util/ResourceBundle.html > -- PGP Key: http://keys.gnupg.net/pks/lookup?op=vindex=0xCA3BAD2E9CCCD509 Web: http://codefx.org a blog about software development https://www.sitepoint.com/java high-quality Java/JVM content http://do-foss.de Free and Open Source Software for the City of Dortmund Twitter: https://twitter.com/nipafx
Signing jlink code for macOS on other platforms
Hello! As a long time Java developer, I've only ever had to deal with signing jar files. I can obviously sign jar files once on whatever platform I choose to use to build the code, and then distribute the jars to all platforms. Build once, run everywhere, etc. However, now that jlink exists, as a developer I have to deal with signing platform-specific executables. For example, if I distribute a macOS application produced with jlink, that executable will produce a large warning message: http://ataxia.io7m.com/2018/02/12/warning.png Now obviously in the past, the system JRE was signed and so I'd give my users a jar file, they'd run the jar file using the signed JRE, and everything would work. With jlink, it's now my responsibility to sign the executables I produce. The code signing tools for macOS are evidently not available for any platform other than macOS, meaning that I now can't just build the code for all platforms on Linux if I want to use jlink (even though jlink is capable of producing embedded JREs for all of the platforms I want to support); at least part of the build would have to take place on macOS to sign the final result. This is pretty awful! Are there any plans to implement anything that's capable of signing macOS binaries and resources in a platform-independent way so that jlink-produced distributions can work without warnings? Is that even a reasonable thing to request? I've no idea how "private" Apple keep their signing implementation. -- Mark Raynsford | http://www.io7m.com