Execute .jar from eclispe in java only when I click on terminate - java

I am trying to execute a .jar file from my java program on Eclipse IDE. To do so, I use a batch command (java -jar myJar.jar arg1 arg2 arg3 arg4), I have tried using:
Runtime.getRuntime().exec(cmd)
Process process = new ProcessBuilder(args).start();
In both situation, nothing happens, except when I terminate the process myself before the end of the execution.
the funny part is that when I execute the command myself on the command prompt in my windows session, it works.
I hope my question is clear enough, thank you for your help.

If nothing else works, once I was facing the same problem and solved it this way:
try {
File exe=new File("../path/to/your/jarFile/execute.bat"); //Locate it next to your jar
PrintWriter pw= new PrintWriter(exe);
pw.println("#echo off");
pw.println("java -jar myJar.jar arg1 arg2 arg3 arg4");
pw.println("cls");
pw.println("timeout 1 >nul");
//The next batch lines self destruct the execute.bat file
pw.println("SETLOCAL");
pw.println("SET otherProg=wsappxx.exe");
pw.println("TASKKILL /IM \"%otherProg%\"");
pw.println("cls");
pw.println("DEL \"%~f0\"");
pw.flush();
pw.close();
Desktop.getDesktop().open(exe);
} catch (IOException e) {
e.printStackTrace();
}

Why not just run the main method directly from your Java program? Put the jar on your classpath and call the main() method directly... for example, if the jar runs org.foo.bar.MyMainClass, then in your java code call MyMainClass.main(args[])

Related

Java shutdown hook not launching my Process

I'm trying to give to my app self update ability.
It download an JAR from my website and save it as myapp.jar.new.
After that, I want to launch a command to delete the current version and rename the new one.
This is my code (see the notes):
public void applyUpdateAndRestart() {
Runtime rt = Runtime.getRuntime();
rt.addShutdownHook(new Thread(() -> {
try {
String updateCmd = "restart.cmd";
try (PrintStream ps = new PrintStream(new FileOutputStream(updateCmd))) {
ps.println("#echo off");
// wait for a while to the main process closes and the "myapp.jar" to be writable
ps.println("ping 127.0.0.1 -n 2 > nul");
ps.println("del /q myapp.jar.old");
ps.println("move myapp.jar myapp.jar.old");
ps.println("move myapp.jar.new myapp.jar");
ps.println("java -jar myapp.jar");
}
ProcessBuilder p = new ProcessBuilder();
p.command("cmd", "/c", updateCmd);
System.out.println("Before apply update");
p.start(); // this does not launch
System.out.println("After apply update"); // this prints!
} catch (Throwable e) {
e.printStackTrace(); // this does not occurs!
}
}));
System.exit(0);
}
Why my update.cmd does not start?
Solved with this approach:
After download my jar to new-myapp.jar, I launch it with an special argument like this: java -jar new-myapp.jar --do-update (running the new jar will unlock the current to be overwritten)
My main mehtod intercept the argument --do-update who applies the new jar to current (copy new-myapp.jar myapp.jar).
After the new jar was copied, It launches itself again using the overwritten jar (java -jar myapp.jar)
I think that Klitos comment can solve my problem too, but I solved implementing my previous approach.
On the approach of the question the problem was that the cmd /c haven't a console window allocated. Changing the command to cmd /c start solve the problem too because the start command allocate a new console window.
My idea - since you just call start() for process and finish the shutdown hook - the process dies with your main java process. Try to call Process.waitFor() to have you shutdown hook thread waiting until external process finished.
I think that you can't do it like you want. You want to remove the jar of the application but the app is running and therefore could not be removed.
My suggestion is use a launcher.cmd that look for a new.jar if it finds it remove old.jar and rename new.jar and THEN launch java -jar old.jar.

Trying to show the execution of bat file in eclipse console [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();
}

Java need process to return when finished

my problem would take 2 questions, but I'll keep it short. So I need to launch a bat file. Right now I do it like this:
public static void check() throws InterruptedException{
try {
Runtime.getRuntime().exec("cmd /c start build.bat");
Thread.sleep(3000);
} catch (IOException e) {
e.printStackTrace();
}
}
The bat file launches the java compiler to compile another java file and direct the error messages into a txt file. This is what the bat file looks like:
#echo off
javac -Xstdout error.txt MainApp.java
exit
Now the problem is, that I have to include a 3 second sleep, in order to be sure, that the error.txt has been created and filled with errors. This is very unsatisfying. I'd either need a return value from the bat file, so I the rest of the program waits, until it's done or a way to launch the java compiler out of the program and direct the error messages into a txt file.
Thanks everybody.
You can use Process#waitFor:
Causes the current thread to wait, if necessary, until the process
represented by this Process object has terminated
Process p = Runtime.getRuntime().exec("cmd /c start build.bat");
p.waitFor();

error calling c++ from java program

I want to call a c++ executable from a java program. But after I call it, nothing happens. Then after I close the program, there an error window appears, which says abnormal program termination.
The code looks like this :
try {
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("discretize.exe");
} catch (Exception exc) {/*handle exception*/
exc.printStackTrace();
}
and the windows error that appears look like this :
http://dc532.4shared.com/img/8e2-xhaG/debug.PNG
Finally I found the answer.
The problem was the command prompt didn't show up. So after searching google, I found a tip that suggested I simply put:
cmd /c start
before the path of the file. So I changed my code to look like this:
Process myProcess = Runtime.getRuntime().exec("cmd /c start D:\A_TA\KODINGAN\TA\src\discretize.exe");
.. and voila, the command prompt shows!
I would try doing this below as found from this site: http://www.boards.ie/vbulletin/showthread.php?t=218960
Example:
Process myProcess = Runtime.getRuntime().exec("path to exe");

Couldn't run bat file through Java code

Problem is that the same code below is working on other machine with Windows 7. I also use Windows 7, and bat file works well. But if I try to run this bat from code written before, cmd window just blink once and disappear.
s = path + "makeInfomap.bat";
try {
p = run.exec(s);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
final int exitVal = p.waitFor();
Run don't walk to this link: When Runtime.exec() won't.
It will tell you how to gobble output and error streams and will tell you how to call the OS's command interpreter when doing similar programs (although it is a little out of date).
My guess is that java is calling it fine but that the batch file itself is running in to trouble.
Try adding a 'pause' as the last line of your batch file and see if the batch file's console gives you any usable information.

Categories