Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux: load openjfx when exist #93

Closed
wants to merge 3 commits into from

Conversation

miurahr
Copy link
Member

@miurahr miurahr commented Apr 27, 2021

When java is 11 and openjfx is specified by OPENJFX_CLASSPATH
automatically load openjfx as module.
This help plugin which use javafx.swing GUI component working.

Current distribution with JRE bundles AdoptOpenJDK 8 that does not support JavaFX.

When user downloads OmegaT distribution without JRE, and use java environment on Linux,
there may be a OpenJDK 11 and it can be with OpenJFX.

This modification support the situation.

Signed-off-by: Hiroshi Miura [email protected]

When java is 11 and openjfx is specified by OPENJFX_CLASSPATH
automatically load openjfx as module.
This help plugin which use javafx.swing GUI component working.

Signed-off-by: Hiroshi Miura <[email protected]>
@miurahr
Copy link
Member Author

miurahr commented Apr 28, 2021

OmegaT-Browser is an one that use OpenJFX.

@miurahr
Copy link
Member Author

miurahr commented May 13, 2021

This modification is necessary because OpenJFX's Swing implementation access internal class of Swing. It should be loaded as module when launching java, otherwise when omegat-browser plugin load, java report class-not-found.

@amake
Copy link
Member

amake commented May 21, 2021

I'm kind of confused about OPENJFX_CLASSPATH.

This is not a standard envar, is it? The user must manually set this?

If the user has to manually set something anyway, why not just have the user pass the correct arguments to the launch script? Like

./OmegaT --module-path /path/to/whatever --add-modules=javafx.base,javafx.controls,javafx.swing,javafx.web

If that doesn't work because those args need to come earlier in the invocation, then we could add a JAVA_OPTS variable to the script, and the user can do

JAVA_OPTS="--module-path /path/to/whatever --add-modules=javafx.base,javafx.controls,javafx.swing,javafx.web" ./OmegaT

@miurahr
Copy link
Member Author

miurahr commented May 22, 2021

User need to set an environment variable OPENJFX_CLASSPATH by hand for OmegaT, not standard variable.

Previous stable versions of Linux distribution (Debian/Ubuntu 18.04, Fedora, OpenSUSE) released with OpenJDK 8 and OpenJFX11, , and because Java8 is not modular, OpenJFX is installed in JRE lib directory. So user don't need to know a hack discussed here.

Since recent distro such as Ubuntu 20.04 has OpenJDK 11, which is modular, then OpenJFX is placed separate directory.
It is OK to add cumbersome options to launcher command line for developer, but it will make ordinary user, please forget whether Linux users are ordinary or not 👯 , feel tired or at least confused.

Allowing loading OpenJFX is enough for OmegaT itself, and it is easy that plugin author help their users to install openjfx and set environment variable .
Related discussion: yoursdearboy/omegat-browser#14

There may be another story for Windows and macOS users, but I don't know the way to solve.
Related discussion: yoursdearboy/omegat-browser#23

@amake
Copy link
Member

amake commented May 23, 2021

Thanks for the additional information.

My main concerns are:

  1. I would prefer that OmegaT not have to know anything about OpenJFX, since OpenJFX is not required for OmegaT and is only needed for a specific plugin.
  2. It seems to me that having to define OPENJFX_CLASSPATH is already difficult. If something difficult is required no matter what, then maybe there is a solution that solves my concern (1) without changing the difficulty very much.

How is the user expected to determine the correct value of OPENJFX_CLASSPATH for their system?

Also, can you see if the changes I pushed work for you? I did some cleanup but I can't really test whether I broke anything.

@miurahr
Copy link
Member Author

miurahr commented May 23, 2021

At first I see an issue at OmegaT-Browser plugin, I've pushed a build configuration to bundle OpenJFX with OmegaT-Browser plugin. It works for build but not works for user. It is because the plugin use openjfx-swing that is not work just by bundle openjfx native library with plugin.

It is a story why I propose here a minimal addition.

It seems to me that having to define OPENJFX_CLASSPATH is already difficult. If something difficult is required no matter what, then maybe there is a solution that solves my concern (1) without changing the difficulty very much.

Yes, you are right. The issue is one in a specific plugin.

@yoursdearboy Can you guide your users to run the plugin with necessary argument for omegat, or guide your users to use specific Java runtime that support OpenJFX natively?

I'd like to close here without merge, but the discussion would help @yoursdeearboy and other java developers.

@amake
Copy link
Member

amake commented May 23, 2021

You don't have to close yet. If this really is the most reasonable solution then I'm ok with it; I just haven't yet understood why other solutions are worse.

@amake
Copy link
Member

amake commented May 25, 2021

I am trying to learn more about the omegat-browser plugin so I can better understand the tradeoffs.

  1. I installed the openjfx11 package with MacPorts. It installs to $JAVA_HOME/lib

  2. I put the latest release of omegat-browser into my OmegaT plugins folder

  3. I ended up eventually getting the plugin to load correctly with the following invocation:

    java --module-path "$(printf "$JAVA_HOME/lib/javafx.%s.jar:" base controls swing web graphics media)" \
      --add-modules javafx.base,javafx.controls,javafx.swing,javafx.web,javafx.graphics,javafx.media \
      -jar /opt/local/share/java/OmegaT/OmegaT.jar

    (OmegaT also installed with MacPorts)

Thoughts:

  • If the installation directory for OpenJFX is not predictable across systems, I think it will be extremely difficult for users to figure out the correct arguments
  • The modules suggested in this PR were not sufficient; I had to add javafx.graphics and javafx.media
  • It seems to me that the only reasonable UX for a plugin like omegat-browser is to bundle OpenJFX with the plugin, and in addition provide a launch script
  • However that probably won't work well if there are multiple plugins that use OpenJFX. The only "nice" solution to that is for OmegaT to bundle OpenJFX, but I don't really want to do that because it's heavy and apparently not even properly available for OpenJDK 8(?)

@miurahr
Copy link
Member Author

miurahr commented Jul 4, 2021

How to provide OpenJFX as a plugin

  • However that probably won't work well if there are multiple plugins that use OpenJFX. The only "nice" solution to that is for OmegaT to bundle OpenJFX, but I don't really want to do that because it's heavy and apparently not even properly available for OpenJDK 8(?)

We can learn a partial solution from JOSM project; Java OpenStreetMap editor.
https://josm.openstreetmap.de/

It resolves the issue with

  • Handle plugin dependencies
  • Handle platform dependencies
  • Provide OpenJFX plugins for windows, macOS and linux.

It realizes the "nice" solution.

refs

  • introduce native and virtual plugins using new Plugin-Platform and Plugin-Provides manifest entries
  • Use case: javafx-windows, javafx-osx and javafx-unixoid are three native plugins providing the virtual javafx plugin on which other plugins can depend
  • add new plugin property Minimum-Java-Version
  • make PluginClassLoader extend DynamicURLClassLoader so that plugins can add URLs to it
  • Early load plugin
    When specified as early load, it load very early stage of application startup.

It may not be a perfect but worth.

Another big issue

One of big barriers is a Swing-OpenJfx binding.

https://stackoverflow.com/a/55876672

The important part of that stack trace is the last Caused by:, which is:

Caused by: java.lang.IllegalAccessError: superclass access check failed: class com.sun.javafx.embed.swing.SwingNodeHelper (in unnamed module @0x412b4fb) cannot access class com.sun.javafx.scene.NodeHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene to unnamed module @0x412b4fb

This says there's a class, named SwingNodeHelper, in the "unnamed module" which extends a class, named NodeHelper, present in the javafx.graphics module. The javafx.graphics module, however, does not export this superclass (more specifically, the package to which the superclass belongs) to the "unnamed module". This leads to the IllegalAccessError when trying to load the SwingNodeHelper class.

@miurahr
Copy link
Member Author

miurahr commented Sep 15, 2021

There is only a browser plugin which use OpenJFX, I'd like to close here and the issue should be resolved in browser plugin.
They can bundle omegat launcher and OpenJFX libraries for their usres.

@miurahr miurahr closed this Sep 15, 2021
miurahr added a commit to miurahr/omegat that referenced this pull request Sep 25, 2021
@miurahr miurahr deleted the topic-load-openjfx-early branch February 12, 2022 04:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants