Can't launch .exe from Java - java

I am trying to launch a .exe file through a Java program. I used the following code:
System.out.println("Opening " + path);
Process exec;
exec = Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL " + path);//path is the path of the exe file which is passed as an argument from another java class
the output is as follows:
Opening C:\Program Files (x86)\C-Free 5\CppIDE.exe
But it is not opening.
Instead when I try
String pat="C:\\Program Files (x86)\\C-Free 5\\CppIDE.exe";
Process exec;
exec = Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL " + pat);
the program is opened.
I don't know what the problem is.

It's very likely that the space in your path is the problem.
I suggest you pass the arguments as an array instead of passing a single string containing the whole command (alternatively you could quote the spaces correctly, but that's not quite as easy).
Either
use the String[] version of Runtime.exec() or
switch to using ProcessBuilder which has an altogether simpler and more intuitive API.
With ProcessBuilder this could look like this:
ProcessBuilder pb = new ProcessBuilder("rundll32", "SHELL32.DLL,ShellExec_RunDLL", path);
Process p = pb.start();
Also, I see no reason to invoke rundll32 at all in this scenario. This should work just as well:
ProcessBuilder pb = new ProcessBuilder(path);
Process p = pb.start();

You need to construct the path using File.separator. The path separator you are using will, in this case, will be system dependant.

Related

ProcessBuilder: Start .jar in java package

I try to execute an external jar in my java application. The .jar is in my java-package ("gui").
I tried:
String filepath = this.getClass().getResource("ServerRSS.jar").getPath();
ProcessBuilder pb = new ProcessBuilder("java", filepath);
System.out.println(filepath); results in:
/C:/Users/hox/workspace/PraktikumProg/bin/gui/ServerRSS.jar
My programm doesn't start. Could the problem be the slash before the C: ?
EDIT:
The solution was:
URL filepath = this.getClass().getResource("ServerRSS.jar");
ProcessBuilder pb;
pb = new ProcessBuilder("java", "-jar", new File(filepath.toURI()).toString());
Process p = pb.start();
First get your command working ... simply on the command line.
And only then try to run it from within Java using a ProcessBuilder.
Simple answer is probably: to use -jar when invoking java.
java someJar.jar
does not work!
And yes, that slash matters big time. You simply want a fully correct file path there.
Finally: are you really sure you want to start a new JVM in order to run a main method in some class? You see, you could do that within your current JVM - without the additional performance and complexity cost of using a second JVM!

Executing a jar file, with code [duplicate]

How could I run a local jar file from a java program?
The jar file is not in the class-path of the Java caller program.
I suggest you use a ProcessBuilder and start a new JVM.
Here is something to get you started:
ProcessBuilder pb = new ProcessBuilder("/path/to/java", "-jar", "your.jar");
pb.directory(new File("preferred/working/directory"));
Process p = pb.start();
Process proc = Runtime.getRuntime().exec("java -jar Validate.jar");
proc.waitFor();
// Then retreive the process output
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();
byte b[]=new byte[in.available()];
in.read(b,0,b.length);
System.out.println(new String(b));
byte c[]=new byte[err.available()];
err.read(c,0,c.length);
System.out.println(new String(c));
First, the description of your problem is a bit unclear. I don't understand if you want to load the classes from the jar file to use in your application or the jar contains a main file you want to run. I will assume it is the second.
If so, you have a lot of options here.
The simplest one would be the following:
String filePath; //where your jar is located.
Runtime.exec(" java -jar " + filepath);
Voila...
If you don't need to run the jar file but rather load the classes out of it, let me know.
Could something like the following be useful?
http://download.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html
Another way to do on windows is:
Runtime.getRuntime().exec("cmd /c start jarFile");
this way you can set priority of your process as well (normal/low/etc)
You can run a jar file from where ever you want by using only this one line code.
Desktop.getDesktop().open(new File("D:/FormsDesktop.jar"));
where
new File("your path to jar")
Hope it helps.
Thanks.
Add jar library to your project
Import main class (see manifest in jar file)
Invoke static method main with arguments
String args[] = {"-emaple","value"};
PortMapperStarter.main(args);
To run an executable jar from inside your java application, you can copy the JarClassLoader from https://docs.oracle.com/javase/tutorial/deployment/jar/examples/JarClassLoader.java
Use it like this. In this snippet, jarUrl is the URL to download the jar from, for example file:/tmp/my-jar.jar and args is the array of strings you want to pass as command line arguments to the jar.
JarClassLoader loader = new JarClassLoader(jarUrl);
String main = loader.getMainClassName();
loader.invokeClass(main, args);
Keep in mind that you're now inserting someone else's binary into your code. If it gets stuck in an infinite loop, your Thread hangs, if it calls System.exit(), your JVM exits.
This is my appriach, which I consider is more complete:
public static Process exec(String path, String filename) throws IOException {
String javaHome = System.getProperty("java.home");
String javaBin = javaHome +
File.separator + "bin" +
File.separator + "java";
ProcessBuilder pb = new ProcessBuilder(javaBin, "-jar", path+filename);
return pb.start();
}
1) Set the class path from environment variables
2) Go to the folder where your jar file exists
3) Run the following commands through command prompt
java -jar jarfilename

unable to access jarfile using java Runtime from another jar on linux platform

I am trying to run an executable jar from another jar using Runtime.exec function from java class.
Code is
Runtime r = Runtime.getRuntime();
Process p = r.exec("java -jar \""+_JarPath +"\" " + "\""+ args[0]+"\""+ " " +"\""+ args[1]+"\""+ " " +"\""+ args[2]+"\"" + " " +"\""+ args[3]+"\"");
Here, argument argsare not null and are well defined.
This code runs fine on Windows platform but on Linux, I am getting error
Unable to access jarfile "/opt/mydir/lib/MyFol/mytest.jar"
I have read other similar questions and made sure that
The directory /opt/mydir/lib/MyFol/ and file mytest.jar are having all the permission
The executable jar from which this process command is launched is also having all the permissions.
User on linux is also admin
I am using OpenJDK on Linux.
The actual problem with the above code on linux machine was the double quotes, as stated by Robin Green in post, and he is right.
But then I was unable to run jar when the path contained empty spaces or other arguments were having spaces in between.
For that I had to try some other way to load jars, which could work seamless in both the platforms and had the problem of spaces removed too.
Process Builder came to rescue, in this situation.
ProcessBuilder pb = new ProcessBuilder("java", "-jar", _JarPath, args[0], args[1], args[2], args[3]);
Process p = pb.start();
This worked fine on both the platforms without any probes, in all the situations.
EDIT
OOPS an easy solution was there but I did not got it, Thanks to Ingo for the comment posted that we can pass the arguments by using another overloaded function of exec
Runtime r = Runtime.getRuntime();
Process p =null;
String[] cmdarray = new String[7];
cmdarray[0] = "java";
cmdarray[1] = "-jar";
cmdarray[2] = _JarPath;
cmdarray[3] = args[0];
cmdarray[4] = args[1];
cmdarray[5] = args[2];
cmdarray[6] = args[3];
p = r.exec(cmdarray);
Try it without the double quotes. I suspect it may be an issue that the shell is not being invoked, but rather Java is being invoked directly.

Java command Runtime.getRuntime().exec() in Mac OS

I´m using Mac OS Lion, with java version 1.6.0_26
I'm making a small app for Mac in Java with a main menu for the user, so he can choose several options.
One of them is install an app using a .pkg
Everything was working fine with these commands:
File instFolder = new File(System.getProperty("user.dir") + "/foldername/appInstaller.pkg");
String s = "open "+ instFolder.toString();
Process p = Runtime.getRuntime().exec(s);
Then I realized that there is a problem when foldername has spaces or if I copy this java file with the needed subfolders to a USB pen drive with "NO NAME" as name (or some name with spaces).
Because s will become something like:
open /Volumes/NO NAME/foldername/appInstaller.pkg
or
open /Users/user1/Desktop/folder name/appInstaller.pkg
So when you run the p process, the command will finish where the first space appears on the path
open /Volumes/NO
or
open /Users/user1/Desktop/folder
To try to fix this I changed the s definition for something like this:
String s = "open "+ "\"" + instFolder.toString() + "\"";
It stopped working fine. The strange thing is that if i copy the s value (after creating the s variable) and paste it in the terminal it works:
open "/Users/user1/Desktop/folder name/appInstaller.pkg"
but running it from Java it does't work.
Could you help me, please?
Thanks.
In order to properly escape arguments, you can use the following:
Runtime.getRuntime().exec(new String[] { "open", instFolder.toString() });
Though I would probably to use the more modern ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("open", instFolder.toString());
Process p = pb.start();
int exitCode = p.waitFor();
Though this may be worth a read depending on what you want to do with the processes output.
Note: edited to reflect question in comment
it seems your path does not have quotes when turned into the shell.
You should probably add "'" on both sides of your path, so the final shell command will look like:
open 'your path'
instead of
open your path
Here's a little trick that came out from the answers mentioned above:
ProcessBuilder pb = new ProcessBuilder(commandString.split(" "));
Say commandString = "killall Mail" then the split will separate the words making it a String[] parameter to the ProcessBuilder.

Find the associated program to open a file using Java

I wish to open a file (lets say, a word document) from a Java application using the associated program installed on the computer (in this example, using MS Word or Open Office Writer).
The catch is that I want to wait until this subprocess finishes, which can be done using the waitFor() method in the Process class.
String executable = findAssociatedApplicationPath(); //for example, returns "C:\\Program Files\\Microsoft Office\\Office12\\msword.exe"
Process p = Runtime.getRuntime().exec(executable + " " + filepath);
p.waitFor();
Can someone tell me how to write the findAssociatedApplicationPath() method so it returns the correct executable? Or is there another way to do this?
The proper platform-independant way to open a file using the associated program is Desktop.open(). Unfortunately, it does not offer any way to interact with the resulting process.
If you're willing to lose platform independance, you can use the start command in cmd.exe:
String fileName = "c:\\tmp\\test.doc";
String[] commands = {"cmd", "/c", "start", "\"Title\"",fileName};
Process p = Runtime.getRuntime().exec(commands);
p.waitFor()
There's no pure Java way to do this, because it's necessarily OS-specific. On a Windows platform, the start command is probably what you're looking for (for example, start myfile.txt).
There is no "universal" way to do this across all platforms. On Windows, you can execute "start", which will find the correct associated executable. On the mac, you can execute "open". On Linux, I'm afraid you'll have to map the preferred applications manually as far as I know.
String execName = ("cmd /c \"start " + filename + "\"");
You can try to mess around with the Windows registry and other platform-specific settings, but I think the best solution is to simply have the application have its own preferences setting.
You may want to use the classes in package java.util.prefs for this.
I have figured it out.
Using the cmd.exe + start.exe combo, the method waitFor() will not wait for the subprocess to end.
If doing it without the start option it works like a charm (windows only though):
Process p = Runtime.getRuntime().exec("cmd /c \"" + filename + "\""); //extra quotes for filenames with spaces
p.waitFor()

Categories