Building dynamic Java Module System layers to integrate JavaFX 11 in Equinox

One of the most fundamental features of the e(fx)clipse runtime is to integrate JavaFX into the Equinox OSGi-Container and even a running Eclipse IDE.

We currently support the following setups:

  • JavaFX 8
  • JavaFX 9/10
  • JavaFX 11

and the integration for all those versions is a bit different. I don’t want to go into details but starting with JavaFX-11 we need to spin up a new Java-Module-System-Layer at runtime because we can not assume JavaFX being part of the JRE running your OSGi-Container (Eclipse IDE).

Since JavaFX-9 we spin up a dynamic layer to implement JavaFX-SWT-Integration and we adapted that logic for JavaFX-11 to load all JavaFX-11 modules.

The code we have works like this

and it works prefectly fine until someone like ControlsFX comes along and does not play by the rules trying to load classes from unexported packages like com.sun.javafx.runtime.VersionInfo.

The standard answer from ControlsFX to fix that problem temporarily is to force the module-system to export them using –add-exports=javafx.base/com.sun.javafx.runtime=ALL-UNNAMED.

Unfortunately this workaround does not work in our case because the command-line flag only allows to modify modules of the Boot-Layer but not those created in dynamic ones like those we construct inside our JavaFX-OSGi integration.

I was investigating yesterday how one could fix this problem but could not come up with a good solution (one that does not call into internals of the module system) until I tweeted

about it and Tom Watson (one of the maintainers of Equinox) pointed me into the right direction.

So the solution is

and now I have to think how we expose that to in our OSGi-Integration.

This entry was posted in Uncategorized. Bookmark the permalink.

6 Responses to Building dynamic Java Module System layers to integrate JavaFX 11 in Equinox

  1. Mordechai Meisels says:

    This doesn’t solve what you can’t say `–`. Looks like has a hardcoded block to this behaviour, otherwise, I’d be glad if you can point me to how to do this.

    • Tom Schindl says:

      I’m not sure what you are aiming at for me the code from this blog works perfectly fine – do you get an exception when trying to build your own Module-Layer?

      • My bad I didn’t explain myself enough. So say you have a module in the new layer that needs access to a package but that package is in the boot layer, in such a case I think we’re out of luck.

        Using command-line flags won’t work since that target module doesn’t exist, and using a controller will not work either as it disallows exporting from the parent module.

        one solution which I haven’t tried could be to add a dummy module with the same name of the target module and put that in the boot layer just to satisfy the JVM flag, then shadow that boot dummy module in the child layer.

        SO again, your code works but still doesn’t solve one issue.

      • Tom Schindl says:

        Ok now i got it – you want to expose a package explicitly to one module in another layer – this sounds like a fair use case to me. Did you ever asked at the openjdk mailing list?

      • Tom Schindl says:

        I’ve subscribed myself to that issue and comment there

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.