I am making a GUI for a command line program using JavaFX.
If I just pack the program inside the .JAR, can I call it? Or do I need to extract the program into the local machine first before making a process? I ask because since a .JAR is a ZIP file, I suppose you can't just run a file inside the .JAR because it is compressed or something.
-
The command line program that you want to launch, is it a Java program? Or like a native binary?aioobe– aioobe2015年05月26日 05:48:37 +00:00Commented May 26, 2015 at 5:48
-
@aioobe native binarySaturn– Saturn2015年05月26日 05:48:49 +00:00Commented May 26, 2015 at 5:48
-
1Then it's the operating system that launches the program. Unless the operating system in question is able to launch programs from within zip-files (which I doubt) you would have to extract the binary and write it to disk before launching.aioobe– aioobe2015年05月26日 05:49:59 +00:00Commented May 26, 2015 at 5:49
-
1this is a good question and I can imagine future visitors struggling with a similar use case so I took the time to write an exhaustive answer.aioobe– aioobe2015年05月26日 06:22:19 +00:00Commented May 26, 2015 at 6:22
2 Answers 2
You'd have to do this in two steps:
Extract the binary and write it to disk (because the OS is probably only able to launch the program if it's a file on disk)
Launch the program, preferably using
ProcessBuilder.
Here's a complete demo:
test.c
#include <stdio.h>
int main() {
printf("Hello world\n");
return 0;
}
Test.java
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Collections;
public class Test {
public static void main(String[] args) throws Exception {
Path binary = Paths.get("mybinary");
Files.copy(Test.class.getResourceAsStream("mybinary"), binary);
System.out.println("Launching external program...");
// Needed for Linux at least
Files.setPosixFilePermissions(binary,
Collections.singleton(PosixFilePermission.OWNER_EXECUTE));
Process p = new ProcessBuilder("./mybinary").inheritIO().start();
p.waitFor();
System.out.println("External program finished.");
}
}
Demo
$ cc mybinary.c -o mybinary
$ ./mybinary
Hello world
$ javac Test.java
$ jar -cvf Test.jar Test.class mybinary
$ rm mybinary Test.class
$ ls
mybinary.c Test.jar Test.java
$ java -cp Test.jar Test
Launching external program...
Hello world
External program finished.
Further reading:
Comments
You have to extract your program first to let the os execute it. There's no way to 'stream' it to ram and execute from there.