Executing a jar file, with code [duplicate] - java

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

Related

Run batch file code from java code

I want to execute a batch file code from java button click. Also I don't want any command prompt window to be shown all from java code.
I have a code :-
C:\xyz-3.1.1\bin>dita --input=C:/Users/india/Desktop/mobile-phone/m
obilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Use
rs/india/Desktop/dofhdif.txt
So I want above code to be run from batch command with C:\xyz-3.1.1\bin> as the parent directory.
Also I want to update --input file path whenever I will choose new file from JFileChooser.
I did this from the java code on button click transform:-
ProcessBuilder pb=new ProcessBuilder("dita --input=C:/Users/india/Desktop/mobile-phone/mobilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Users/india/Desktop/dofhdif.txt");
pb.redirectErrorStream(true);
Process process=pb.start();
and getting IOException error.
I get stuck over here for long time , where am I going wrong.
EDIT :- error
java.io.IOException: Cannot run program "dita --input=C:/Users/india/Desktop/mobile-phone/m
obilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Use
rs/india/Desktop/dofhdif.txt": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
As the Error mentioned, it cannot locate the command because the whole string will be treated as the command by ProcessBuilder.
Try to use Runtime.getRuntime().exec directly, but you have to ensure the command dita can be found.
Process process = Runtime.getRuntime().exec("C:\xyz-3.1.1\bin>dita --input=C:/Users/india/Desktop/mobile-phone/mobilePhone.xyz --format=pdf --output=C:/Users/india/Desktop --logfile=C:/Users/india/Desktop/dofhdif.txt");
process.waitFor();
int exitCode = process.exitValue();
System.out.println(IoHelper.output(process.getInputStream())); // handle the output;
Before JDK 5.0, the only way to start a process and execute it, was to use the exec() method of the java.lang.Runtime class after which ProcessBuilder can be used to help create operating system processes.
The major improvement being that, it also acts as a holder for all those attributes that influence the process. And this is how it should be used:
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
P.S. Actually Runtime.getRuntime().exec can also be used with String... as:
Runtime.getRuntime().exec(new String[]{"curl", "-v", "--cookie", tokenString, urlString});
My personal preference:
If you have to configure the environment for the command: to control the working directory or environment variables and also you want to execute the commands several times, you'd better use it since the ProcessBuilder will hold the settings and what you need to do is just processBuilder.start() to create another process with the same settings;
If you want to execute a whole long string command as you mentioned, you'd better just use Runtime.getRuntime().exec since you can just execute it right there without any bothering of the parameter format.
Try this:
String inputFile = ...;
String outputFile = ...;
String logFile = ...;
ProcessBuilder pb = new ProcessBuilder(
"dita",
"--input=" + inputFile,
"--format=pdf",
"--output=" + outputFile,
"--logfile=" + logFile)
.directory(new File("C:\\xyz-3.1.1\\bin"))
//.inheritIO();
.redirectErrorStream(true);
Process process = pb.start();
This shows the following points:
The command is separated from the arguments
The argument values can be determined at runtime
The command's default directory (C:\xyz-3.1.1\bin) is set before starting the process
Consider using inheritIO() instead of redirectErrorStream() if you want the process's output to appear as part of your Java application's output.

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!

Concatenate two DOS commands in a java program

I want to concatenate two dos commands in a java program. First I want to change directory then list the files and folders in that. So I wrote that like
try
{
Process process = UI.this.rt.exec("cmd.exe /c cd C:\\Users & start dir");
process.waitFor();
InputStream in = process.getInputStream();
while (in.read() != -1) {}
}
catch (Exception e)
{
System.out.println(e);
}
But this is not working. When I execute this in desktop it is not change the directory and display the files and folders which is in the desktop. Could you please help me to fix this problem? I'm using windows 7 machine.
Thanks
Isuru Liyanage
Write the commands to a batch file on the disk and execute the batch.
If you don't want to have such a batch on the disk, create it on demand and delete it after usage.
Or just use the java build-in features to list files.
EDIT
But your code works. I tried it.
It opens a dos-box an lists the directory after changing the directory.
You can use ProcessBuilder to set the working directory of the Process you exec later.
Or, do as suggested else-thread and use the Java API for listing files in a directory, which is saner.
While creating a process you can pass a string array of commands as below:
String[] command = new String[3];
command[0] = "cmd";
command[1] = "/c";
command[2] = " cd c:\\Users && dir";
Process p = Runtime.getRuntime().exec(command);
Drop the start, it runs files in a new window. Plus as there in no cmd in the NEW command DIR won't be recognised as a command. If you must use start for some reason add cmd /c to the dir part as well.
also dir c:\users is all you actually need to do. No need or reason to change directory.

Can't launch .exe from 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.

location of shell script called from java application

I have a java application from which i am calling a shell script. Can any one tell where to keep the script file in my application and what is the path to access the file in whole application.
i m keeping my script in the java package but when i m trying to access using path like com.abc.script.sh by running my java application through unix i ma getting error
java.io.IOException: error=2, No such file or directory
i am calling the script file with some argument with the following code
private static final String command = "com.abc.script.sh -db abc -scm TEST_xyz -bcp com.abc.out.txt -log /var/tmp -tab abc_$TABLENAME";
Process process = Runtime.getRuntime().exec(command);
and i am running the application from unix.
i need to pass the parameter to shell script file as well . the parameters are like hostname , table name...
where to keep the script file in my application
Your wrote, I can interprete this like:
Storing the content of the file into the memory
Storing the file into your .jar file
I think you mean the second.
You can place it in your jar file in every folder you want. I prefer a subfolder (not the root)
First put the file in your jar. Then you have to extract it to a temporary file (See the link if you want to know how to make a tempfile).
Then create an inputstream from the file in your jar and copy the data to the temp-file.
InputStream is = getClass().getResourceAsStream("/path/script.sh");
OutputStream os = new FileOutputStream(tempFile);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1)
{
os.write(buffer, 0, bytesRead);
}
buffer = null; // Clear the buffer
Then you have to execute your shellscript
Runtime.getRuntime().exec("terminalname " + tempFile.getAbsolutePath());
Maybe you can use this line to execute your script (I don't think this will work with your parameters):
java.awt.Desktop.getDestkop().open(tempFile);
I hope this is an answer for your question.
You could store your shell script as a resource (e.g. inside your jar file), then exec a shell and pipe the content of your script as standard input to the running shell.
Something like this (haven't tried it):
ProcessBuilder processBuilder = new ProcessBuilder( "/usr/bin/bash" );
Process process = processBuilder.start();
OutputStream outputStream = process.getOutputStream();
InputStream resourceStream = getClass().getResourceAsStream(
"/path/to/my/script.sh" );
IOUtils.copy( resourceStream, outputStream );
If you happen to be using the Spring framework for this project, a good and simple option is to store the shell script in a folder on your class path and use a ClassPathResource object to locate it.

Categories