Sorry for the delay in responding.

I added a simple test program to the JBS bug that shows the same behavior as the application and also an evaluation of the bug.

The short version is that JavaFX beans is (mostly) working as expected, except for the misleading exception message. In JDK 9 it is required that any object that is reflected on by JavaFX beans, specifically the items passed to TableView, which are accessed via a PropertyValueFactory, will need to be in a package that is exported unconditionally. In JDK 10 we can look into relaxing this requirement such that the package only needs to be exported to javafx.beans.

I do think we need to make the exception message less confusing in JDK 9 and also document the requirement in the appropriate places (at least in TableView and probably in a couple of javafx.beans.property.adapter classes).

Comments?

-- Kevin


Mandy Chung wrote:
Hi Trisha,

Thanks for the report and stack trace.  I created
https://bugs.openjdk.java.net/browse/JDK-8177566 for further
investigation.

Mandy


On Mar 24, 2017, at 2:34 PM, Trisha Gee <trisha....@gmail.com> wrote:

Hi,

I was chatting to Alex Buckley at DevoxxUS about my experiences migrating a
project to using Java 9 modules (specifically, this project:
https://github.com/trishagee/sense-nine) and mentioned some surprising
behaviour in a module that uses JavaFX.  I've been asked to send the
details so people can take a look at it.

My module-info.java is here:
https://github.com/trishagee/sense-nine/blob/master/src/com.mechanitis.demo.sense.client/module-info.java
Note that I have to export two additional packages (mood and user), and I
did not expect (or really want) to.  This is because I was getting this
error if I did not:

java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:547)
at
javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:482)
at
javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:381)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:547)
at
java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:912)
Caused by: java.lang.RuntimeException: Exception in Application start method
at
javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:982)
at
javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:200)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.RuntimeException: *java.lang.IllegalAccessException:
class sun.reflect.misc.Trampoline cannot access class
com.mechanitis.demo.sense.client.user.TwitterUser (in module
com.mechanitis.demo.sense.client) because module
com.mechanitis.demo.sense.client does not export
com.mechanitis.demo.sense.client.user to unnamed module @779d6cc6*
at
javafx.base/com.sun.javafx.property.PropertyReference.getProperty(PropertyReference.java:200)
at
javafx.controls/javafx.scene.control.cell.PropertyValueFactory.getCellDataReflectively(PropertyValueFactory.java:145)
at
javafx.controls/javafx.scene.control.cell.PropertyValueFactory.call(PropertyValueFactory.java:119)
at
javafx.controls/javafx.scene.control.cell.PropertyValueFactory.call(PropertyValueFactory.java:98)
at
javafx.controls/javafx.scene.control.TableColumn.getCellObservableValue(TableColumn.java:579)
at
javafx.controls/javafx.scene.control.TableColumn.getCellObservableValue(TableColumn.java:564)
at
javafx.controls/javafx.scene.control.TableCell.updateItem(TableCell.java:645)
at
javafx.controls/javafx.scene.control.TableCell.indexChanged(TableCell.java:468)
at
javafx.controls/javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116)
at
javafx.controls/javafx.scene.control.skin.TableRowSkinBase.updateCells(TableRowSkinBase.java:534)
at
javafx.controls/javafx.scene.control.skin.TableRowSkinBase.<init>(TableRowSkinBase.java:159)
at
javafx.controls/javafx.scene.control.skin.TableRowSkin.<init>(TableRowSkin.java:89)
at
javafx.controls/javafx.scene.control.TableRow.createDefaultSkin(TableRow.java:212)
at
javafx.controls/javafx.scene.control.Control.doProcessCSS(Control.java:895)
at javafx.controls/javafx.scene.control.Control.access$000(Control.java:83)
at
javafx.controls/javafx.scene.control.Control$1.doProcessCSS(Control.java:89)
at
javafx.controls/com.sun.javafx.scene.control.ControlHelper.processCSSImpl(ControlHelper.java:67)
at
javafx.graphics/com.sun.javafx.scene.NodeHelper.processCSS(NodeHelper.java:147)
at javafx.graphics/javafx.scene.Node.processCSS(Node.java:9356)
at javafx.graphics/javafx.scene.Node.applyCss(Node.java:9443)
at
javafx.controls/javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1697)
at
javafx.controls/javafx.scene.control.skin.VirtualFlow.getCell(VirtualFlow.java:1674)
at
javafx.controls/javafx.scene.control.skin.VirtualFlow.getCellLength(VirtualFlow.java:1781)
at
javafx.controls/javafx.scene.control.skin.VirtualFlow.computeViewportOffset(VirtualFlow.java:2618)
at
javafx.controls/javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1242)
at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1226)
at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1233)
at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1233)
at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1233)
at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:585)
at javafx.graphics/javafx.scene.Scene.preferredSize(Scene.java:1767)
at javafx.graphics/javafx.scene.Scene$2.preferredSize(Scene.java:389)
at
javafx.graphics/com.sun.javafx.scene.SceneHelper.preferredSize(SceneHelper.java:66)
at javafx.graphics/javafx.stage.Window$12.invalidated(Window.java:1092)
at
javafx.base/javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
at
javafx.base/javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:145)
at javafx.graphics/javafx.stage.Window.setShowing(Window.java:1180)
at javafx.graphics/javafx.stage.Window.show(Window.java:1195)
at javafx.graphics/javafx.stage.Stage.show(Stage.java:267)
at
com.mechanitis.demo.sense.client/com.mechanitis.demo.sense.client.Dashboard.start(Dashboard.java:45)
at
javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:928)
at
javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
at
javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at
javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
at
javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native
Method)
at
javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:189)
... 1 more
Caused by: java.lang.IllegalAccessException: class
sun.reflect.misc.Trampoline cannot access class
com.mechanitis.demo.sense.client.user.TwitterUser (in module
com.mechanitis.demo.sense.client) because module
com.mechanitis.demo.sense.client does not export
com.mechanitis.demo.sense.client.user to unnamed module @779d6cc6
at
java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:423)
at
java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:414)
at
java.base/jdk.internal.reflect.Reflection.ensureMemberAccess(Reflection.java:112)
at
java.base/java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:632)
at
java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:624)
at java.base/java.lang.reflect.Method.invoke(Method.java:539)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:72)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:547)
at java.base/sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:261)
at
javafx.base/com.sun.javafx.property.PropertyReference.getProperty(PropertyReference.java:198)
... 48 more

When I discovered this I was a bit stumped about what was in the unnamed
module, given this appears to be JavaFX code causing this.

I'm running this from inside IntelliJ IDEA, this is the command it's
calling:  "C:\Program Files\Java\jdk-9\bin\java"
-Djava.util.logging.config.file=logging.properties
-javaagent:C:\Users\Trisha\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\171.3780.107\lib\idea_rt.jar=54310:C:\Users\Trisha\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\171.3780.107\bin
-Dfile.encoding=UTF-8 -p
C:\Users\Trisha\Projects\trishagee\sense-nine\out\production\com.mechanitis.demo.sense.client;C:\Users\Trisha\Projects\trishagee\sense-nine\out\production\com.mechanitis.demo.sense.service;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\websocket\javax-websocket-server-impl\9.4.1.v20170120\javax-websocket-server-impl-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-annotations\9.4.1.v20170120\jetty-annotations-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-plus\9.4.1.v20170120\jetty-plus-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-webapp\9.4.1.v20170120\jetty-webapp-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-xml\9.4.1.v20170120\jetty-xml-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-util\9.4.1.v20170120\jetty-util-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-servlet\9.4.1.v20170120\jetty-servlet-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-security\9.4.1.v20170120\jetty-security-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-server\9.4.1.v20170120\jetty-server-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-http\9.4.1.v20170120\jetty-http-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-io\9.4.1.v20170120\jetty-io-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-jndi\9.4.1.v20170120\jetty-jndi-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\javax\annotation\javax.annotation-api\1.2\javax.annotation-api-1.2.jar;C:\Users\Trisha\.m2\repository\org\ow2\asm\asm\5.1\asm-5.1.jar;C:\Users\Trisha\.m2\repository\org\ow2\asm\asm-commons\5.1\asm-commons-5.1.jar;C:\Users\Trisha\.m2\repository\org\ow2\asm\asm-tree\5.1\asm-tree-5.1.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\websocket\javax-websocket-client-impl\9.4.1.v20170120\javax-websocket-client-impl-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\websocket\websocket-client\9.4.1.v20170120\websocket-client-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\jetty-client\9.4.1.v20170120\jetty-client-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\websocket\websocket-common\9.4.1.v20170120\websocket-common-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\websocket\websocket-api\9.4.1.v20170120\websocket-api-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\javax\websocket\javax.websocket-api\1.0\javax.websocket-api-1.0.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\websocket\websocket-server\9.4.1.v20170120\websocket-server-9.4.1.v20170120.jar;C:\Users\Trisha\.m2\repository\org\eclipse\jetty\websocket\websocket-servlet\9.4.1.v20170120\websocket-servlet-9.4.1.v20170120.jar
-m
com.mechanitis.demo.sense.client/com.mechanitis.demo.sense.client.Dashboard

Thanks,
Trisha

Reply via email to