B4J Question Running jars under OpenJDK 11

agraham

Expert
Licensed User
Longtime User
With Java 8 you could run a jar on a Windows PC by double clicking on it. This does not work with OpenJDK so as I want to be able to quickly run some utility B4J programs easily without packaging them this is what I did.

1) I installed OpenJDK in a convenient place, mine is in 'C:\jdk-11', and set up B4J to use it.

2) I made an environment variable named 'OpenJdkPath' with the value of the OpenJDK path, in my case 'C:\jdk-11'.

3) I wrote and compiled a trivial program in Basic4ppc called 'RunSelfNamedJarJdk11.sbp' that looks at what its .exe is named and invokes javaw.exe to run a co-located jar of the same name. Your Basic4ppc won't do this as one of the mods to my own version is to pass its own exe name as args(0). However you can probably do this in any other language that can create an exe that can identify itself.
B4X:
Sub Globals
   'Declare any global variables here
   Dim appargsfile
   appargsfile = args(0) & ".args"
   Dim ThisVersion : ThisVersion = "4.0"
End Sub

Sub App_Start
   Obj1.New1
   Obj1.CreateNew("System.Environment")
   envar = "OpenJdkPath"
   ojp = Obj1.RunMethod2("GetEnvironmentVariable", envar, "System.String")
   If ojp = cNull Then
       Msgbox("Environment variable '" & envar & "' not present!", "OpenJDK Path Error")
   Else
       appargs = ""
       javaops = ""
       debug = ""
       If FileExist(appargsfile) Then
           FileOpen(in, appargsfile, cRead)
           appargs = FileRead(in)
           javaops = FileRead(in)
           debug = FileRead(in)
           If javaops = EOF Then
               javaops = ""
           End If
           FileClose(in)
       End If
       If ArrayLen(args()) > 1 Then
           For j = 1 To  ArrayLen(args()) - 1
               If StrIndexOf(args(j), " ", 0) > 0 Then
                   appargs = appargs & " " & Chr(34) & args(j) & Chr(34)
               Else
                   appargs = appargs & " " & args(j)
               End If
           Next
       End If       
       ' java options
       shellargs =  " --module-path " & ojp & "\javafx\lib --add-modules ALL-MODULE-PATH " & javaops & " "
       ' jar file
       shellargs = shellargs & "-jar " & Chr(34) & AppPath & "\" & args(0) & ".jar" & Chr(34)
       ' app arguments
       shellargs = shellargs & " " & appargs
       Shell(ojp & "\bin\javaw", shellargs)
       If debug <> EOF Then
           Msgbox("Runner Version "  & ThisVersion & CRLF & CRLF &  shellargs, "Shell Arguments")
       End If
   End If
End Sub

4) I place a copy of 'RunSelfNamedJarJdk11.exe' in the B4J project Objects folder next to the B4J jar and rename it to match the jar. Voila! you can now double click the exe and the jar will run without the hassle of packaging it.

5) To pass arguments to the invoked jar place a file named <nameofjar>.args in the B4J project Objects folder. The first line of this file will be passed to the Args() array of App_Start. Remember that an argument item containing space characters will need to be delimited by quotes. There is no error raised if the file is not present. 'RunSelfNamedJarJdk11.exe' can also accept command line arguments that will be passed to the B4J program. These arguments wil lbe added to the end of any argument list present in the args file.

6) To pass options to javaw.exe add a second line containing the required options to the <nameofjar>.args file.

7) To examine the generated argument string passed to java.exe add a third line to the <nameofjar>.args file. This can be blank or contain anything, it doesn't matter. The presence of a third line triggers the display of a Msgbox.

If you trust me you can use the zipped exe attached

EDIT: Version 2 now posted that passes arguments to the jar when run.

EDIT: Version 3 now posted passes java options as well.

EDIT: Version 4 now posted accepts command line arguments.
 

Attachments

  • RunSelfNamedJarJdk11_v4.zip
    89 KB · Views: 545
Last edited:

Cableguy

Expert
Licensed User
Longtime User
Make it the other way around:
First line : options
Second line: parameters

Just to be in sync with the command line itself
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Doesn't seem to work, gives "error: Could not create the Java Virtual Machine"
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
I should have thought of this before :(. Version 4 now posted accepts command line arguments to pass to the the invoked jar. See the first post for details.
Can you please provide an example of a resulting Complete command generated by the Tool if all lines are used in the <myjar.args> file
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Attached is an example that I used for testing. The program in the jar just displays its arguments in a message box. Run the exe and/or the bat then remove the third line in args.
 

Attachments

  • RunSelfNamedJarJdk11_v4_Example.zip
    422 KB · Views: 319
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Is there a technical reason why with JDK11 that we cant just simply click and run a JAR like we could in the past? without all these hacks?

Just curious what changed.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
This is probably an incomplete answer and is Windows only but from my point of view -

Java 8 was installed by a 'proper' installer that set a Path environment variable and some registry entries to make java.exe the default for a .jar file. When invoked by double-clicking on a jar file Java 8 seemed to be able to find all its libraries by itself and load and run the jar.

JDK 11 is xcopy installed without an installer. I believe that it is intended by the powers that be that Java 11 jars are packaged for distribution with a copy of the Java run-time to ensure correct run-time versioning for that jar. You could set up your own Path and default program for jar files but java.exe and javaw.exe in JDK11 also need to be told where the libraries are so it is not that simple a solution. Hence my kludge to run a jar from my own exe to avoid the packaging hassle for utilities that might change from invocation to invocation.

If any one has a better/more complete answer I like to read the detailed reasoning behind this change.
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
Based on this command, I can create a batch file as below:
B4X:
@ECHO OFF
TITLE RUN A JAR FILE
CD C:\Java\jdk-11.0.1\bin
javaw --module-path C:\Java\jdk-11.0.1\javafx\lib --add-modules ALL-MODULE-PATH -jar "C:\Development\App\Objects\App.jar"
::PAUSE
Thank you for this, I have been trying to figure out how to do it with a batch file.

Add the word START,
B4X:
START javaw --module-path C:\Java\jdk-11.0.1\javafx\lib --add-modules ALL-MODULE-PATH -jar "C:\Development\App\Objects\App.jar"
And it will run in windows 10 without leaving a window open.
 
Upvote 0

micro

Well-Known Member
Licensed User
Longtime User
Hi agraham
in your example (code) in B4ppc, Obj1 what type of object is it?
What dll did you load in B4ppc?
Can you share the complete RunSelfNamedJarJdk11.sbp project?
Thanks
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Obj1 is a Reflector object. The entire project code is here but as I stated above
Your Basic4ppc won't do this as one of the mods to my own version is to pass its own exe name as args(0). However you can probably do this in any other language that can create an exe that can identify itself.
 

Attachments

  • RunSelfNamedJarOpenJdk_v4.zip
    92.3 KB · Views: 155
Upvote 0

micro

Well-Known Member
Licensed User
Longtime User
Sorry again aghram
but strangely the reflector dll is missing in the Libraries folder of Basic4ppc, yet I remember using it years ago
Can you pass it to me?
Thanks
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
If I remember correctly it was called the DoorEx library and is here
I renamed to Reflection and enhanced it when I started developing my own private version of Basic4ppc.
 
Upvote 0
Top