Executing a Jar file from an Java application - java

I have 2 methods I wrote to try and execute a Jar file from my Java application and they both are not doing anything. The Java Runtime Environment is installed on the C: drive and by default its Path points to a directory on the C: drive. The Jar file I am trying to execute is located on the E: drive.
Jar location: E:\Demo Folder\MyDemo.jar
I tried to execute MyDemo.jar using the following 2 methods:
Method 1:
try {
Runtime.getRuntime().exec("cmd /c start %SystemDrive%\\java -jar " + "E:/Demo Folder/MyDemo.jar");
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
Method 2:
try {
File dirFile = new File("E:/Demo Folder/");
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "E:/Demo Folder/MyDemo.jar");
pb.directory(dirFile);
Process p = pb.start();
} catch (Exception ex) {
System.err.println(ex.getMessage());
}

Didn't you try to put your invocation logic inside a, say, E:/Demo Folder/rundemo.bat` (or .cmd) file, and call that .bat from your java instead? That's usually more sane and easy to troubleshoot.

I'm guessing the problem is the space in the path of the jar file. Try this:
new ProcessBuilder("java", "-jar", "\"E:/Demo Folder/MyDemo.jar\"");

To launch a external java executable application you must first locate the java.exe file (Which loads the JVM) and pass the argument of -jar to indicate loading of a executable JAR file. In both methods you provided you had minor errors within your code.
In method one:
cmd /c start %SystemDrive%\\java -jar
%SystemDrive% is being treated as a string literal as java is unaware of Windows specific environment variables.
In method two:
"java", "-jar", "E:/Demo Folder/MyDemo.jar"
You are assuming that java.exe has been added to PATH environmental variables which may not be the case. Also, from your usage of the "%" operators, I am assuming you are on a windows machine, which uses \ for directories therefore... "E:/Demo Folder/MyDemo.jar" may not return a valid location.
Try the following segment of code:
try {
File dirFile = new File("E:\\Demo Folder\\");
ProcessBuilder pb = new ProcessBuilder(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java", "-jar", new File(dirFile, "MyDemo.jar").getAbsolutePath());
pb.directory(dirFile);
Process p = pb.start();
} catch (Exception ex) {
System.err.println(ex.getMessage());
}

Related

Running .bat file in java to create a .csv file

I am trying to execute a bat file using java. This bat file contains code that should create a .csv file in the same directory. The .csv file is successfully created when I execute the .bat file by running it on my Windows machine, however when I try to execute it in java using Runtime.getRuntime().exec(), the file does not get created.
String[] command = {"cmd.exe", "/C", "C:/Users/MidiCsv/ex.bat"};
Process p = null;
try {
p = Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
try {
p.waitFor();
System.out.println("ready");
} catch (InterruptedException e) {
e.printStackTrace();
}
content = Files.readString(Paths.get("C:/Users/MidiCsv/" + midiName + ".csv"), StandardCharsets.US_ASCII);
The value returned by the p.waitFor() method is 2, I assume this means there was an error here since the normal return value is 0. What error could this indicate?
If the working directory is required to be same as your batch file, use this variant of exec method instead:
public Process exec(String[] cmdarray,
String[] envp,
File dir)
throws IOException
Reference: https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec(java.lang.String[],%20java.lang.String[],%20java.io.File)
Make dir the directory containing your batch file.
I figured out the error from taking the helpful advice here. I used the exec() variant Febtober mentioned, also previously I was putting the absolute path of the .batch file as the dir paramter, whereas I should have put the directory of the .batch file instead.

How to run a batch file which is present in the working directory of the java file? [duplicate]

In my Java application, I want to run a batch file that calls "scons -Q implicit-deps-changed build\file_load_type export\file_load_type"
It seems that I can't even get my batch file to execute. I'm out of ideas.
This is what I have in Java:
Runtime.
getRuntime().
exec("build.bat", null, new File("."));
Previously, I had a Python Sconscript file that I wanted to run but since that didn't work I decided I would call the script via a batch file but that method has not been successful as of yet.
Batch files are not an executable. They need an application to run them (i.e. cmd).
On UNIX, the script file has shebang (#!) at the start of a file to specify the program that executes it. Double-clicking in Windows is performed by Windows Explorer. CreateProcess does not know anything about that.
Runtime.
getRuntime().
exec("cmd /c start \"\" build.bat");
Note: With the start \"\" command, a separate command window will be opened with a blank title and any output from the batch file will be displayed there. It should also work with just `cmd /c build.bat", in which case the output can be read from the sub-process in Java if desired.
Sometimes the thread execution process time is higher than JVM thread waiting process time, it use to happen when the process you're invoking takes some time to be processed, use the waitFor() command as follows:
try{
Process p = Runtime.getRuntime().exec("file location here, don't forget using / instead of \\ to make it interoperable");
p.waitFor();
}catch( IOException ex ){
//Validate the case the file can't be accesed (not enought permissions)
}catch( InterruptedException ex ){
//Validate the case the process is being stopped by some external situation
}
This way the JVM will stop until the process you're invoking is done before it continue with the thread execution stack.
Runtime runtime = Runtime.getRuntime();
try {
Process p1 = runtime.exec("cmd /c start D:\\temp\\a.bat");
InputStream is = p1.getInputStream();
int i = 0;
while( (i = is.read() ) != -1) {
System.out.print((char)i);
}
} catch(IOException ioException) {
System.out.println(ioException.getMessage() );
}
ProcessBuilder is the Java 5/6 way to run external processes.
To run batch files using java if that's you're talking about...
String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);`
This should do it.
The executable used to run batch scripts is cmd.exe which uses the /c flag to specify the name of the batch file to run:
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "build.bat"});
Theoretically you should also be able to run Scons in this manner, though I haven't tested this:
Runtime.getRuntime().exec(new String[]{"scons", "-Q", "implicit-deps-changed", "build\file_load_type", "export\file_load_type"});
EDIT: Amara, you say that this isn't working. The error you listed is the error you'd get when running Java from a Cygwin terminal on a Windows box; is this what you're doing? The problem with that is that Windows and Cygwin have different paths, so the Windows version of Java won't find the scons executable on your Cygwin path. I can explain further if this turns out to be your problem.
Process p = Runtime.getRuntime().exec(
new String[]{"cmd", "/C", "orgreg.bat"},
null,
new File("D://TEST//home//libs//"));
tested with jdk1.5 and jdk1.6
This was working fine for me, hope it helps others too.
to get this i have struggled more days. :(
I had the same issue. However sometimes CMD failed to run my files.
That's why i create a temp.bat on my desktop, next this temp.bat is going to run my file, and next the temp file is going to be deleted.
I know this is a bigger code, however worked for me in 100% when even Runtime.getRuntime().exec() failed.
// creating a string for the Userprofile (either C:\Admin or whatever)
String userprofile = System.getenv("USERPROFILE");
BufferedWriter writer = null;
try {
//create a temporary file
File logFile = new File(userprofile+"\\Desktop\\temp.bat");
writer = new BufferedWriter(new FileWriter(logFile));
// Here comes the lines for the batch file!
// First line is #echo off
// Next line is the directory of our file
// Then we open our file in that directory and exit the cmd
// To seperate each line, please use \r\n
writer.write("cd %ProgramFiles(x86)%\\SOME_FOLDER \r\nstart xyz.bat \r\nexit");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// Close the writer regardless of what happens...
writer.close();
} catch (Exception e) {
}
}
// running our temp.bat file
Runtime rt = Runtime.getRuntime();
try {
Process pr = rt.exec("cmd /c start \"\" \""+userprofile+"\\Desktop\\temp.bat" );
pr.getOutputStream().close();
} catch (IOException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
// deleting our temp file
File databl = new File(userprofile+"\\Desktop\\temp.bat");
databl.delete();
The following is working fine:
String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);
This code will execute two commands.bat that exist in the path C:/folders/folder.
Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat");
import java.io.IOException;
public class TestBatch {
public static void main(String[] args) {
{
try {
String[] command = {"cmd.exe", "/C", "Start", "C:\\temp\\runtest.bat"};
Process p = Runtime.getRuntime().exec(command);
} catch (IOException ex) {
}
}
}
}
To expand on #Isha's anwser you could just do the following to get the returned output (post-facto not in rea-ltime) of the script that was run:
try {
Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
System.out.println(process.getText());
} catch(IOException e) {
e.printStackTrace();
}

How to run a Java program using ProcessBuilder inside the other Java program. (with -cp and -Xbootclasspath commands)

Here is my code.
public class Test {
public static void main(String[] args) {
String directory = System.getProperty("user.home") + File.separator + "cache";
System.out.println(directory); // "/Users/byron1st/cache"
try{
ProcessBuilder builder = new ProcessBuilder("java",
"-cp", directory,
"-Xbootclasspath/p:", directory,
"framework.PFSystemMain");
builder.redirectErrorStream(true);
builder.redirectOutput(new File(System.getProperty("user.home") + "/output.txt"));
builder.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}
This program builds a process to run a java program with -cp and -Xbootclasspath commands. Classes of the target program are in /Users/byron1st/cache folder.
What I want to do is to run java -cp /Users/byron1st/cache -Xbootclasspath/p: /Users/byron1st/cache framework.PFSystemMain
(The reason that I use Xbootclasspath/p: is that I have some instrumented classes to log.)
This code cannot run the process and just produce an error message meaning "It cannot find or load a default class called '.Users.byron1st.cache'". (I'm sorry for showing the error message directly because it is written in Korean.)
What is wrong with my code to use ProcessBuilder?
I fixed this problem. It is because of 'Xbootclasspath/p:'.
I changed my code like below:
ProcessBuilder builder = new ProcessBuilder("java",
"-cp", directory,
"-Xbootclasspath/p:" + directory,
"framework.PFSystemMain");
In fact, I thought -Xbootclasspath/p: and its directory path are separate arguments for processbuilder, but it is not.

Calling shell script from Java by giving a relative path of script location

I am working on a project wherein I have to call my shell script stored at the location where my java files reside.I am currently calling the shell script by giving a hard-coded (absolute) path.I want to make my script run by giving a relative path.Currently I am running my script via this code in Java:
try {
ProcessBuilder pb2 = new ProcessBuilder("/bin/bash", "/Users/umang/Documents/script.sh", arg);
Process scriptexec = pb2.start();
scriptexec.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
Here the arg is the location of the file on which the script runs.The current Implementation works well but the Issue is I have to store my script at some location on the server.Its a webapp which is deployed on apache-tomcat server by making a war file. It would be good to have a relative path and store the script inside the war file when it is being generated.
Attempt #1:
final File executorDirectory = new File("A/B/C/D/E/F/G/H/");
try {
ProcessBuilder pb2 = new ProcessBuilder("/bin/bash","combiner.sh",arg);
pb2.directory(executorDirectory);
Process scriptexec = pb2.start();
scriptexec.waitFor();
System.out.println("Script executed successfully");
} catch (Exception e) {
e.printStackTrace();
}
A/B/C/D/E/F/G/H/ location where my script resides from the top of the application
Error: File not found error -2 JavaIOException()
Attempt #2
URL loc=ClassLoader.getSystemResource("script.sh");
try {
ProcessBuilder pb2 = new ProcessBuilder("/bin/bash", "/Users/umang/Documents/script.sh", arg);
Process scriptexec = pb2.start();
scriptexec.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
Error: loc does not get me the path for the script location.In the debugger tool I figured out it gets null.
Since the ClassLoader.getSystemResource returns a URL and ProcessBuilder only accepts String I cannot directly append them.
If this is deployed in tomcat try to put your script in the WEB-INF of your war. Now assuming you start the process from a servlet you could use
ServletContext ctx = getContext();
String pathForProcessBuilder = ctx.getRealPath("/WEB-INF/script.sh");
If you don't want to use the ServletContext, try using
getClass().getClassLoader().getResource("/WEB-INF/script.sh")
instead of using ClassLoader (in order to make sure you use the "correct" classloader, i.e. the one which loaded your class)

How to open the notepad file in java?

I want to open Notepad in my Java program. Suppose that I have one button if I click this button the notepad will appear.
I already have a file name and a directory.
How can I implement this case?
Try
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().edit(file);
} else {
// I don't know, up to you to handle this
}
Make sure the file exists. Thanks to Andreas_D who pointed this out.
(assuming you want notepad to open "myfile.txt" :)
ProcessBuilder pb = new ProcessBuilder("Notepad.exe", "myfile.txt");
pb.start();
Assuming you wish to launch the windows program notepad.exe, you are looking for the exec function. You probably want to call something like:
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("C:\\path\\to\\notepad.exe C:\\path\\to\\file.txt");
For example, on my machine notepad is located at C:\Windows\notepad.exe:
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("C:\\Windows\\notepad.exe C:\\test.txt");
This will open notepad with the file test.txt open for editing.
Note you can also specify a third parameter to exec which is the working directory to execute from - therefore, you could launch a text file that is stored relative to the working directory of your program.
Using SWT, you can launch any
If you want to emulate double-clicking on a text in windows, it's not possible only with a plain JRE. You can use a native library like SWT and use the following code to open a file:
org.eclipse.swt.program.Program.launch("c:\path\to\file.txt")
If you don't want to use a third-party lib, you should know and you know where notepad.exe is (or it's visible in PATH):
runtime.exec("notepad.exe c:\path\to\file.txt");
Apache common-exec is a good library for handling external process execution.
UPDATE: A more complete answer to your question can be found here
In IDE (Eclipse) it compains about "C:\path\to\notepad.exe C:\path\to\file.txt" .
So i have used the following which works for me keeping me and my IDE happy :o)
Hopefully this will help others out there.
String fpath;
fPath =System.getProperty("java.io.tmpdir")+"filename1" +getDateTime()+".txt";
//SA - Below launches the generated file, via explorer then delete the file "fPath"
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("explorer " + fPath);
Thread.sleep(500); //lets give the OS some time to open the file before deleting
boolean success = (new File(fPath)).delete();
if (!success) {
System.out.println("failed to delete file :"+fPath);
// Deletion failed
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String fileName = "C:\\Users\\Riyasam\\Documents\\NetBeansProjects\\Student Project\\src\\studentproject\\resources\\RealWorld.chm";
String[] commands = {"cmd", "/c", fileName};
try {
Runtime.getRuntime().exec(commands);
//Runtime.getRuntime().exec("C:\\Users\\Riyasam\\Documents\\NetBeansProjects\\SwingTest\\src\\Test\\RealWorld.chm");
} catch (Exception ex) {
ex.printStackTrace();
}
You could do this the best if you start notepad in command line with command: start notepad
String[] startNotePadWithoutAdminPermissions = new String[] {"CMD.EXE", "/C", "start" "notepad" };
Save array of string commands and give it like parametr in exec
Process runtimeProcess = Runtime.getRuntime().exec(startNotepadAdmin2);
runtimeProcess.waitFor();

Categories

Resources