I need a bit more time to think about it, but the fact that JavaFX need
to access your application class to construct the instance and call the
init, start, etc., methods is not an implementation detail. It is the
specified behavior. And no, unlike ServiceProvider, there is no special
power that the javafx.graphics module has.
So the short answer is that this is likely something we will fix by
documenting it.
I'll take a look at the case with no main method, though. That might be
a bug.
-- Kevin
Sander Mak wrote:
Hi David,
Thanks for the quick response. Here is a small sample project:
https://bitbucket.org/sandermak/javafx-application/src, the compilerun.sh can
be used to start the app. I already alluded to the solution you propose in the
original post. Indeed, when exporting the class that extends Application
(qualified to javafx.graphics or not, both will do) it works.
However, is such an application class really something I want to export to
other modules? Of course using a qualified export the scope can be restricted
to the javafx.graphics module, and that's what I ended up doing. In general, I
think it's interesting that many frameworks want reflective access to what are
essentially internal implementation classes. Spring comes to mind, you'd want
to export interfaces but not Spring bean implementation classes, even though
the framework needs access to instantiate them. As has been discussed before on
this list, ServiceLoader has a special super-power in this regard, and I sort
of expected JavaFX Application handling to have that same superpower for
instantiating the Application class.
One more follow-up question: when I remove the main() method that invokes launch
(see here:
https://bitbucket.org/sandermak/javafx-application/diff/src/applicationmodule/application/Main.java?diff2=fca74ffbc28d&at=without-main),
the following error comes up (build 9-ea+106-jigsaw-nightly-h4498-20160221):
Error: Main method not found in class application.Main, please define the main
method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
On JDK8 the same code runs fine. What's going on there?
Thanks,
Sander
On 23 Feb 2016, at 22:46, David Hill
<david.h...@oracle.com<mailto:david.h...@oracle.com>> wrote:
On 2/23/16, 3:37 PM, Sander Mak wrote:
Hi,
Sander,
we may not have tested Jigsaw with the path you are trying to take here.
Certainly the common path of a class extending Application will launch
properly, and I have been trudging through our test cases working on some odder
paths. What I have not been doing in these paths is dealing with a new module,
though I would think that would behave similarly to the unnamed module.
It could be that your added complexity here has not been properly dealt with in
our FX code.
Do you have a "simple" test case that shows this error?
Looking at the exception I see a lot of stuff going on, and it is hard to see
the root right away.
With modules, we have to add read edge code in certain spots when our code has
to reach out of the module to a module it does not already know about.
This is the hint here:
(in module javafx.graphics) cannot access class
javamodularity.easytext.gui.Main (in module javamodularity.easytext.gui)
Our FX module javafx.graphics cannot see into your module.
The question becomes one of where, and order of operations.
Dave
When trying to run a module with a main class that extends
javafx.application.Application, the following exception is thrown by the VM:
Exception in thread "main" java.lang.RuntimeException: Unable to construct
Application instance: class javamodularity.easytext.gui.Main
at
com.sun.javafx.application.LauncherImpl.launchApplication1(javafx.graphics@9-ea/LauncherImpl.java:926)
at
com.sun.javafx.application.LauncherImpl.lambda$launchApplication$140(javafx.graphics@9-ea/LauncherImpl.java:220)
at java.lang.Thread.run(java.base@9-ea/Thread.java:804)
Caused by: java.lang.IllegalAccessException: class
com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot
access class javamodularity.easytext.gui.Main (in module
javamodularity.easytext.gui) because module javamodularity.easytext.gui does
not export javamodularity.easytext.gui to module javafx.graphics
at
sun.reflect.Reflection.throwIllegalAccessException(java.base@9-ea/Reflection.java:465)
at
sun.reflect.Reflection.throwIllegalAccessException(java.base@9-ea/Reflection.java:456)
at sun.reflect.Reflection.ensureMemberAccess(java.base@9-ea/Reflection.java:98)
at
java.lang.reflect.AccessibleObject.slowCheckMemberAccess(java.base@9-ea/AccessibleObject.java:370)
at
java.lang.reflect.AccessibleObject.checkAccess(java.base@9-ea/AccessibleObject.java:362)
at
java.lang.reflect.Constructor.newInstance(java.base@9-ea/Constructor.java:435)
at
com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$146(javafx.graphics@9-ea/LauncherImpl.java:838)
at
com.sun.javafx.application.PlatformImpl.lambda$runAndWait$160(javafx.graphics@9-ea/PlatformImpl.java:351)
at
com.sun.javafx.application.PlatformImpl.lambda$null$158(javafx.graphics@9-ea/PlatformImpl.java:320)
at java.security.AccessController.doPrivileged(java.base@9-ea/Native Method)
at
com.sun.javafx.application.PlatformImpl.lambda$runLater$159(javafx.graphics@9-ea/PlatformImpl.java:319)
at
com.sun.glass.ui.InvokeLaterDispatcher$Future.run(javafx.graphics@9-ea/InvokeLaterDispatcher.java:96)
This can be solved by adding a (qualified) export in the module-info of the
module I'm trying to run (inspired by the helpful error message, nice!):
exports javamodularity.easytext.gui to javafx.graphics;
However, that's not really a satisfactory solution. Looks like LauncherImpl
also needs to setup a readability relation on-the-fly, with the caveat that the
class extending Application must always be exported by the application
developer for this to work. Is this the solution we can expect, or are there
any other plans for this situation?
Regards,
Sander
--
David Hill<david.h...@oracle.com<mailto:david.h...@oracle.com>>
Java Embedded Development
"A man's feet should be planted in his country, but his eyes should survey the
world."
-- George Santayana (1863 - 1952)