B4J Question Starting, Terminating a Process and Process Name

iCAB

Well-Known Member
Licensed User
Hi Erel

I am using the sample code in "ServerExampleNoMySQL" to create a push server

I have few questions about the process:
1. Can you please let me know what is the name of the process that runs
2. Can we control the name process name
3. and what is the proper way to launch a process like this at startup..
4. also how do we terminate and restart the process

The reason for my questions above:
I downloaded "Process Explorer", and I tried to find out the name of the process by locating the process locking the .jar file after I launched from the command line. I terminated the process, but I still get address in use when I try to run the server from the B4J.

Please clarify



Thank you
 

Roycefer

Well-Known Member
Licensed User
1. Depending on how you started the process, the name of the process will be "java.exe" or "javaw.exe". From within your program, you can request the process ID (PID) with the following Java code:
B4X:
import java.lang.management.RuntimeMXBean;
import java.lang.management.ManagementFactory;
public static String processID()
    {
        RuntimeMXBean rmxb = ManagementFactory.getRuntimeMXBean();
        return rmxb.getName();
    }
You can use this Java code by including it as "inline Java code" in your B4J code. You will need the PID to terminate the process, as you'll see in answer 4.

2. As far as I know, no, you cannot. The name of the process is the same as the name of the executable that spawned the process. In this case, the name of the executable is the java.exe or javaw.exe, depending on how you started the process.

3. If you want this process to be started as soon as you log into Windows, place a batch file in the following folder:
B4X:
 C:\Users\<YourUserName>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
In this batch file, place the following text:
B4X:
cd C:\Directory\Of\Your\Jar\File
javaw -jar <NameOfJarFile.jar>
4. To terminate any process from within a Java application, call:
B4X:
public static boolean killProcessByPID(String pid)
    {
        String cmd = "taskkill /F /PID " + pid;
        try {
            Runtime.getRuntime().exec(cmd);
            return true;
        } catch (IOException ex) {
            System.err.println("Failed to kill PID: " + pid);
            System.err.println(ex.getMessage());
            return false;
        }
    }
using the same "inline Java code" method as in answer 1. This code is the same as calling
B4X:
taskkill /F /PID <pid>
from the command line. You can also kill a process from within Windows Task Manager by right-clicking on it. If you want to kill a B4J app from within the same app, call
B4X:
ExitApplication
. If you want to start a Java process, you can double-click on the .jar file or call the same commands from the command line as are in the batch file from answer 3.

You can also get a Java process to restart itself as follows:
B4X:
public static boolean launchWithDelay(String jarName)
    {
        String cmd = "timeout 10 \njavaw -jar " + jarName;
        try {
            Runtime.getRuntime().exec(cmd);
            return true;
        } catch (IOException ex) {
            System.err.println("Failed to launch .jar: " + jarName);
            System.err.println(ex.getMessage());
            return false;
        }
    }
Include this function in your B4J code using "inline Java code" and then run
B4X:
Sub relaunchSelf(selfJarName)
     launchWithDelay(selfJarName)
     ExitApplication
End Sub
in your B4J code to restart a Java process from within the process. Note that the jarName you pass the function must include the ".jar" suffix. Also, this will only work to launch a .jar in the same directory as the calling .jar (namely, itself).

Note that you can also run these commands from within a B4J app using the jShell library.

EDIT: Make sure the inline Java methods are static, as they are now. They weren't when I first wrote this essay.
 
Last edited:

iCAB

Well-Known Member
Licensed User
Hi Roycefer

Thank you so much for taking the time to provide this amount of details.
 

Roycefer

Well-Known Member
Licensed User
My pleasure.

To amend my answer #2, I think you can control the process name by using a program like Launch4J that will package your .jar file into an .exe whose name you can choose. Then, when you run your program, its process will be named after the .exe you created, not java.exe.
 

Roycefer

Well-Known Member
Licensed User
To beat a dead horse, my B4J Sub in answer #4 won't work for numerous reasons. Here is a superior alternative that doesn't require any inline Java code:
B4X:
Sub relaunchJar(selfJarName as String)
    Dim batchFileContent As String = "timeout 5 " & CRLF & "start javaw -jar " & selfJarName & CRLF & "del ""relaunch.bat"" "
    File.WriteString(File.DirApp, "relaunch.bat", batchFileContent)
'    fx.ShowExternalDocument(File.GetUri(File.DirApp, "relaunch.bat"))
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array("relaunch.bat"))
    Dim d As JavaObject
    d.InitializeStatic("java.awt.Desktop")
    Dim dt As JavaObject = d.RunMethodJO("getDesktop", Array())
    dt.RunMethod("open", Array(f))
    ExitApplication
End Sub
The commented out line can be used in place of all the following JavaObject code if your program has an FX Object. However, if you're running an http server, it won't have an FX Object and you'll have to use all that JavaObject code.

This Sub creates a batch file and then runs the batch file and then closes down the application. The batch file pauses for 5 seconds to ensure two instances of the same application aren't running simultaneously. Then the batch file starts the jar file, then it deletes itself and closes the command window.

Additionally, you can send command line arguments to the new instance of your program by placing them after selfJarName and before CRLF in the batchFileContent String.
 
Top