Re: IllegalAccessException trying to load a ResourceBundle in 9u181

2018-02-12 Thread mandy chung



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

2018-02-12 Thread Rony G. Flatscher
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-02-12 Thread mark . reinhold
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-02-12 Thread mark . reinhold
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

2018-02-12 Thread Nicolai Parlog
 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

2018-02-12 Thread Nicolai Parlog
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

2018-02-12 Thread Mark Raynsford
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