1

I have a jar file that runs fine from the Windows 10 command line, but is not working on my desktop Ubuntu 18.04 command line. The file was exported from Eclipse as a jar, and copied to Ubuntu. The project has about 30 classes over a half dozen packages. I've done some renaming in order to simplify things for this question.

This is the command used to run the jar:

java -jar myproject.jar

On Ubuntu, I get the error "Could not find or load main class com.a.b.LaunchThis"

Following are some of the things I've tried, based on suggestions from many similar posts. Sorry if this is a duplicate, but I couldn't find a workable answer.

I verified that the current Java is 1.8 using the commands:

$ update-alternatives --config java

and

$ java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1~18.04-b09)
OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)

(I also verified that the program runs using java 8 on Windows.)

I ran the following check, which displays all the files, and confirmed that com/a/b/LaunchThis.class exists and is spelled exactly the same way.

java tj myproject.jar

The manifest seems correct.

Manifest-Version: 1.0
Main-Class: com.a.b.LaunchThis

I also tried unpacking the jar and running the program directly from the folder /myproject which contains both /com and META-INF. That should work, shouldn't it?

java com.a.b.LaunchThis
java com/a/b/LaunchThis
java com.a.b/LaunchThis

And from one level outside the myproject folder:

java myproject/com/a/b/LaunchThis
java myproject.com.a.b/LaunchThis
java myproject.com.a.b.LaunchThis
java myproject/com.a.b.LaunchThis

I am not totally clear on when the syntax requires . or /. The package command in "LaunchThis" which holds the main entry point is the following:

package com.a.b;

And in each of the above iterations I also tried including "-cp myproject.jar" as an option.

Always the exact same error message.

To be careful about not having a typo in the above, I first ran the ls command to make sure the file could be found (then edited this line to create the variants).

ls myproject.com.a.b.LaunchThis.class

Any suggestions as to what else to try?

For grins, running with Java11 gets this response:

Error: Could not find or load main class com.a.b.LaunchThis
Caused by: java.lang.NoClassDefFoundError: javafx/event/EventHandler

This makes some sense, because Java11 does not include JavaFX. But Java 8 does include EventHandler. It's been a part of Java since JavaFX 2.

UPDATE: I made two "Hello world" jars, one with and one without JavaFX on an Ubuntu installation of Eclipse running OpenJDK 8. To get the version with JavaFX to run, I downloaded the Oracle JDK 1.8, and linked to /lib/etc/jfxrt.jar as an "external jar" library. Both programs run in Eclipse but only the non-FX jar works. The FX jar gives exactly the same error message.

I think this pretty much establishes my problem to be one of not having JavaFX as part of OpenJDK 8.

My plan is to now try out two solutions: (1) copying the Oracle jfxrt.jar into the OpenJDK lib, (2) backloading OpenJFX 8.

Simply installing OpenJFX from repository loads OpenJFX 11, which is a little dated but will work with the OpenJDK 11.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41
  • Does `LaunchThis` have a `public static void main(String[] args)` ? – Derrops Apr 26 '20 at 09:07
  • Yes. And the exact same jar runs on Windows. – Phil Freihofner Apr 26 '20 at 09:39
  • 1
    (1) `java jt jarfile` is an error; did you mean `jar tf jarfile`? (2) _Oracle_ j8 includes JFX, but _OpenJDK_ not necessarily. See https://stackoverflow.com/questions/56166267/ https://askubuntu.com/questions/1091157/ https://askubuntu.com/questions/1137891/ (3) But even so it should give a clearer error. Try adding `-verbose` and see if that narrows it down any. – dave_thompson_085 Apr 26 '20 at 09:39
  • Fixed the jt/tj mixup. Thanks. I've spent the last couple hours pursuing the JavaFX angle. My discovered my OpenJDK 8 doesn't have jfxrt.jar. So that could well be the problem. Your links look promising. They were not one's I found when searching on JFX missing from OpenJFX 8. OpenJFX default seems to be 11, and doesn't work with OpenJDK8, but one of your links has an earlier version. I did download Oracle 1.8 and was looking at popping it's copy of jfxrt.jar into the OpenJDK8 /lib. Will let you know what ends up working. – Phil Freihofner Apr 26 '20 at 09:51
  • Run it in docker lol – Derrops Apr 26 '20 at 10:02
  • Unfortunately, the suggestion doesn't help in this case. (1) OpenJDK 11 doesn't have JavaFX, turns out to be the main problem. (2) Many users I wish to give a test jar to don't do Docker. (Still learning about Docker myself.) – Phil Freihofner Apr 26 '20 at 18:46
  • @dave_thompson_085 Also wanted to thank you for the -verbose reminder. It didn't help a lot but it's good to have that in one's debugging repertoire, and it did verify all the non-jfx classes loaded correctly. – Phil Freihofner Apr 26 '20 at 18:56

1 Answers1

1

The issue here is that the repository OpenJDK 8 on Ubuntu 18.04 does not include JavaFX. I'm guessing that the error message results from the fact that a JavaFX main() is located on a class that extends the JavaFX class Application.

How to fix this?

There are a number of things I tested.

First, one could use Oracle's JDK 1.8 instead. I ruled this out due to licensing issues.

Some sites suggested copying the jfxrt.jar from either the Oracle JDK 1.8 or from a working Java program that uses JavaFX and uses a self-contained JRE. I found that if I linked to the Oracle jfxrt.jar (located in the /jre/lib/ext folder) as an external jar, I could run a simple, "Hello world" javafx program in Eclipse. But I could not run the program after it was exported to a jar.

One answer on a related stackoverflow thread suggested copying over several additional files along with jfxrt.jar, which I tried. This did not work, so I'm not going to pass that on.

The solution that has been most successful came from a link provided in the comment by @dave_thomson_085, How do I get Java FX running with OpenJDK 8 on Ubuntu 18.04.2 LTS?.

This answer involves purging and reinstalling openjfx with an older version, and marking it to NOT be subjected to updates.

The code provided by Wolfgang Fahl (which he credits to Druidefix) follows:

apt purge openjfx
apt install openjfx=8u161-b12-1ubuntu2 libopenjfx-jni=8u161-b12-1ubuntu2 libopenjfx-java=8u161-b12-1ubuntu2
apt-mark hold openjfx libopenjfx-jni libopenjfx-java

Now, I can run and test jars containing Java8 using JavaFX that were built on my Windows Eclipse, on my Ubuntu desktop.

I do get a warning message which I haven't dealt with yet:

Gtk-Message: 13:25:40.829: Failed to load module "canberra-gtk-module"

But this is not preventing my programs from running.

Phil Freihofner
  • 7,645
  • 1
  • 20
  • 41
  • I wish we had this link to the related SO question where the exact JavaFX files that should be copied / should exist inside the JDK folders in order to be able to run a JavaFX application on Java 8. after trial and error what worked for me was to copy jfxrt.jar (from %JAVA_HOME%\jre\lib\ext or %JAVA_HOME%\lib\ext) and jfxmedia.dll + jfxwebkit.dll from %JAVA_HOME%\bin – hello_earth Jul 08 '22 at 10:08