Remove JavaFX JPMS enforcement
mike at plan99.net
Mon Apr 20 14:44:23 UTC 2020
Possibly - I posted this because, being ultimately still a product of the
Java group at Oracle, I'm sceptical JavaFX will become *less* dependent on
the module system when the trend has been to use it more.
So there are at least two usability problems:
1 - needing additional downloads and new JVM flags to use JavaFX as modules
rather than ordinary JARs
2 - needing to open packages to JavaFX so it can reflect over them (not a
problem if your app runs on the classpath, but can hit you the moment you
use a component that's been modularised)
The first one has a few workarounds/solutions but what I do is go with the
flow and prepare my own JDK using jlink, which has JavaFX baked in like it
did before. I use a variant on this script:
The output is a JDK directory I can point my IDE at. It's seen as a normal
JDK, but like in Java 8 JavaFX is now fully baked in and available by
default. Because it's already on the module path no special JVM flags are
Probably someone (me?) should upload JDKs for each platform that are "fully
baked" like this.
That leaves the second problem, for which there's no good solution with the
current JFX API. Dependency injectors fundamentally don't mix well with
JPMS. Using Lookup objects is a backwards compatible addition that would
remove part of the pain of using modules with JavaFX because you'd no
longer need to remember to add special incantations to a module-info.java to
enable reflection - incantations which might change between JFX versions as
reflection uses are added or changed.
On Mon, Apr 20, 2020 at 15:06:16, Michael Paus <mp at jugs.org> wrote:
> This is deviating quite a bit from the original issue of this thread,
> isn't it?
> As a side note: MethodHandles are not supported by GraalVM native image
> and so this would probably collide with the attempts to get JavaFX running
> on Android/iOS.
> Am 20.04.20 um 11:28 schrieb Mike Hearn:
> With respect to reflection, it seems like the module system really wants
> you to use Lookup capabilities rather than "open" modules to reflection.
> That is, JFX could be changed to use
> var objects = FXMLLoader.load(MethodHandles.lookup(), new URL("...."));
> The semantics of a Lookup are that it grants whoever holds the object the
> same access rights as whoever created it. Thus if an object creates a
> Lookup and gives it to a framework, that framework can access anything the
> object could itself access.
> The lookup object would then be used to do reflection rather than the
> classical reflection API. With this change the API would guide you to a
> form that always works, regardless of module configuration.
> Due to its nature as a GUI toolkit JFX often needs to reflect over user
> code. It may be worth considering a deeper upgrade in which a Lookup object
> is provided during application startup, and passed in to the framework e.g.
> the Application class. Lookup objects can be 'teleported' so JFX components
> that wish to work with user GUI code generically can then fetch a Lookup
> from a central place. However, this wouldn't allow overriding of access
> control (i.e. FXMLLoader that takes such a lookup and teleports it to the
> right class for access, wouldn't be able to access private fields, because
> the original place where the lookup was created also couldn't).
More information about the openjfx-dev