B4J Question result.jar and result.exe do not run

Didier9

Well-Known Member
Licensed User
Longtime User
I recently had issues with jssc, which I was able to resolve (thank you Chris2): https://www.b4x.com/android/forum/threads/still-problems-with-com-ports.167940/#post-1029596

Now I still have another issue which is that result.jar does not run, nor does the packager produced exe file.
I have OpenJDK19 installed.
This is relatively new, I have used B4J on both machines for many years now and did not have that issue until recently.
I have the same issue on my work computer where we use Oracle Java (it's a corporate thing) and where I have substantial restrictions on what I can do.
I was previously able to run the jar file directly without having to do anything under both environments.

Clicking the jar file produces absolutely nothing, running the result.exe from the packager produces a brief flash of the form's outlie on the screen then it goes away. No error message.

If I try to run the run_debug.bat file from a powershell, I get this, which seems to indicate there is still an issue with jssc:

B4X:
PS C:\Users\xxxxxx\Documents\B4J Projects\RadioConfiguror\dev\Objects\temp\build> .\run_debug.bat

C:\Users\xxxxxx\Documents\B4J Projects\RadioConfiguror\dev\Objects\temp\build>cd bin

C:\Users\xxxxxx\Documents\B4J Projects\RadioConfiguror\dev\Objects\temp\build\bin>java.exe @release_java_modules.txt  -m b4j/b4j.example.main
main._appstart (java line: -1)
java.lang.UnsatisfiedLinkError: Could not load the jssc library: Couldn't load library library jssc
        at b4j/jssc.SerialNativeInterface.<clinit>(Unknown Source)
        at b4j/jssc.SerialPortList.<clinit>(Unknown Source)
        at b4j/anywheresoftware.b4j.serial.Serial.ListPorts(Unknown Source)
        at b4j/b4j.example.main._appstart(Unknown Source)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at b4j/anywheresoftware.b4a.BA.raiseEvent2(Unknown Source)
        at b4j/anywheresoftware.b4a.BA.raiseEvent(Unknown Source)
        at b4j/b4j.example.main.start(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(Unknown Source)
        at java.base/java.security.AccessController.doPrivileged(Unknown Source)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(Unknown Source)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)


C:\Users\xxxxxx\Documents\B4J Projects\RadioConfiguror\dev\Objects\temp\build\bin>pause
Press any key to continue . . .
PS C:\Users\xxxxxx\Documents\B4J Projects\RadioConfiguror\dev\Objects\temp\build>

I found that if I copy jssc.dll in the Objects\temp\build\bin folder as explained in this post: https://www.b4x.com/android/forum/threads/jserial-library.34762/page-6#post-735742, then the exe will run on my development machine, but then it's obvious the exe file will not run by itself. What do I need to do to distribute a single standalone exe file?
Is there a way that I can package everything needed into a single exe file?

For reference, I used to use Launch4J to create standalone exe files instead of B4JPackager because at work I can't use OpenJDK and B4JPackager only supports OpenJDK. Launch4J produces a single exe that I could distribute and run on any machine with a JRE, but that also recently stopped working. Launch4J is no longer able to create working exe files (even though Launch4J does not complain when I run it and it does produce a file). People in my company that run the older, previously built exe files are still able to run those, so if it was a Java update that broke it, it only broke the development machine or development process or the process of creating the exe.
Both work and home machines now run my projects (under the IDE) with jssc installed as described above.

I understand Erel does not endorse Launch4J and I do not expect help with it here, but since some of us at least in some cases cannot use B4JPackager, I thought it might be useful to someone in that predicament to have this info here.

Here is the error Launch4J generates when running it in debug mode

B4X:
Executing: C:\Users\djuge\Documents\!Sync\Sync\B4J Projects\RadioConfiguror\RadioConfiguror_v.exe
Exception in thread "JavaFX Application Thread" Exception in thread "main" java.lang.UnsupportedClassVersionError: b4j/example/main has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:473)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:359)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplicationWithArgs$2(LauncherImpl.java:352)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$7(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$5(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$6(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:185)
    at java.lang.Thread.run(Thread.java:750)
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:913)
Caused by: java.lang.NullPointerException
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:383)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    ... 5 more
 

bdunkleysmith

Active Member
Licensed User
Longtime User
@Didier9 I feel your frustration and I'd like to help as I have developed several apps which use the serial port and have successfully produced standalone installers for distribution after some early frustration of my own, but I'm not sure I fully understand all of your problems.

If we start with your development (home) machine running OpenJDK19, why do you not produce an installer for distribution using the inbuilt Build Standalone Package tool then Inno Script as described in this post https://www.b4x.com/android/forum/t...-way-to-distribute-standalone-ui-apps.117880/? @Erel's creation of that tool was a watershed moment for me because by following Tips and special cases #5 If using jSerial put the attached jssc.dll file in the project folder and add:

B4X:
#CustomBuildAction: After Packager, %WINDIR%\System32\robocopy.exe, ..\ temp\build\bin\ jssc.dll

previous problems of incorporating jssc.dll were overcome.

Then it doesn't matter what JRE is installed on the target machine, the installed package will run and for me, providing an installer makes the app appear far more professional than just copying a bundle of files.

While that will not solve the "other" problem in that you can't produce a single file executable or installer on your "work" machine because of the installed Java environment and other restrictions, I think you'd be pleasantly surprised when you master creation of a standalone installer by reading through all of the posts in the reference above.

Incidentally I thought being able to run the jar by clicking on it was lost once we moved on from Java 8 and so some of the behaviour you describe above is to be expected.

This may not be the assistance your looking for and in any case I can't assist with being able to create a single file executable in the Java environment in your work environment, but I needed to offer something. Hopefully someone with an understanding of Launch4J or an alternative method can help.
 
Upvote 0

Chris2

Active Member
Licensed User
Longtime User
(thank you Chris2)
It's nice for someone to post a question that I can answer!

result.jar does not run
As @bdunkleysmith said, I don't think we've been able to run (by double-clicking) UI app jars since OpenJDk 11.

Is there a way that I can package everything needed into a single exe file?
but then it's obvious the exe file will not run by itself
Not with the B4J Packager. As stated in the tutorial (https://www.b4x.com/android/forum/t...-way-to-distribute-standalone-ui-apps.117880/)
B4X:
You need to distribute the executable together with the 4 folders.
1753966847568.png

This package includes the java runtime for the java version in which you built your app, so the end user doesn't need to have any Java installed on their machine. You can just copy the exe and these four folders onto the machine (preserving the structure), or as @bdunkleysmith suggested, build and installation routine with Inno Setup.
This is why you have the instruction to copy the jssc.dll file into the '...\bin\' folder - because it will then get distributed as part of your app package.

Exception in thread "JavaFX Application Thread" Exception in thread "main" java.lang.UnsupportedClassVersionError: b4j/example/main has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
It's a long time since I used Launch4J, but that error rings a bell.
I think it means that the Java version that was used to build the app is higher/newer than the one used either within the Launch4J package or the one that is installed on the end user machine.
You need to match the Java version that the end user is using (either because it's installed on their machine, or because you're including it within the Launch4J package) with the one that you're using to build the app jar.

You avoid this kind of mis-match by using the B4J Packager because you package and distribute all the files needed to run your app in one bundle (albeit not a single file).
 
Upvote 0
Top