Opened external JAR file with JAVA ProcessBuilder does not work properly - java

I want to open JAR file by pressing JButton in JPanel. To achieve this goal I used ActionListener with ProcessBuilder inside. Here is my code:
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ProcessBuilder pb = new ProcessBuilder("java", "-jar"
, "f:/Documents/TBot/topbotclient.jar"
, "-n", getTopBotName().getText()
, "-pw", getTopBotPass().getText()
, "-s", getScript_name().getText()
, "-w", getWorld().getText()
);
try {
Process p = pb.start();
} catch (IOException ee) {
ee.printStackTrace();
}
}
});
The problem is that opened JAR file do not function properly - it freezes after I press some of its buttons. However, if I close my initial JAVA window that is used to open external JAR, JAR file becomes functional again. What to do to get both initial window and opened JAR file window functional?
I did not find any solution by searching:
Run a jar File from java program,
Execute .jar file from a Java program etc.
UPDATE:
I tried not to use ProcessBuilder and used "runtime.exec" instead.
try {
Runtime runtime = Runtime.getRuntime();
runtime.exec(" java -jar f:/Documents/TBot/scripts/topbot.jar -n Fataho -pw diehard15 -s scriptjoiner -w 301 -nort -a b#hadas.lt -apw blood444");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Exception occured" + ex);
}
The problem remains the same.

Try to start a processbuilder in a separate thread so that your main thread won't block. From your code your doing everything in a Main thread. Make use of swingWorker kind of stuff to start the operation in a separate thread.

Related

How to open IE from a java program

Hey I tried to open IE from a java program.
the command start iexplorer works on command prompt and terminal but when used in a java program throws a IOException. When I execute the command cmd start iexplorer the program is just running without stopping for almost 15 minutes
String command = "cmd start iexplore";
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
This is the call stack of from VScode:
image
can someone help me with this please
All you are doing is running "cmd" in background. If iexplore is on your system Path then this may work:
String[] cmd = new String[] {"cmd", "/c", "start iexplore"};
The "/c" option tells CMD.EXE to start the process, and then CMD exits immediately [in your case it is hanging around for more input]. Also you need to read the STDERR stream of the process to see any error messages from CMD.

you may need to install the My::Module module

i work now in a project of web vulnerability scanner so i would run my perl script into my java the perl script is the uniscan open source tool from kali linux so when i click go to run the script this message appear
Can't locate Uniscan/Crawler.pm in #INC (you may need to install the
Uniscan::Crawler module) (#INC contains: ./Uniscan C:/Perl64/site/lib
C:/Perl64/lib .) at C:\uniscan\uniscan.pl line 25. BEGIN failed--compilation
aborted at test\uniscan.pl line 25.
However when i run hello world script it appear correctly with no probleme in my console. So this is my code of calling perl script in my java
try {
String[] commande = {"perl", "C:\\uniscan\uniscan.pl"};
Process p = Runtime.getRuntime().exec(commande);
AfficheurFlux fluxSortie = new AfficheurFlux(p.getInputStream());
AfficheurFlux fluxErreur = new AfficheurFlux(p.getErrorStream());
new Thread(fluxSortie).start();
new Thread(fluxErreur).start();
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
and the code of uniscan is here
Please i need help i'm blocked is for my final degree next week
The program relies on the script's directory being found in the module search path (#INC), but does not ensure this.
If you run the script from the script's directory, it works because . is in #INC by default. But you are running the script from a different directory.
Remove the following useless line:
use lib "./Uniscan";
Replace it with the following:
use FindBin qw( $RealBin );
use lib $RealBin;

Running exe from java code

I've been working on in a swing application. I've a JFrame having some buttons and fields.
On some button click event,I'm opening an exe from my current directory. Everything works fine.
try {
Runtime.getRuntime().exec(System.getProperty("user.dir") +
"\\Upgrade\\Upgrade.exe");
} catch (IOException ex) {
ex.printStacktrace();
}
this.dispose(); // disposing my current java file.
But what i need is to exit the java code after opening the exe file.
Anyone help to deal this.?
Can you try making it a process, then waiting for that process to finish before exiting, like so:
class SO {
public static void main(String args[]) {
try {
Process proc = Runtime.getRuntime().exec("your command");
proc.waitFor(); //Wait for it to finish
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Executing an application from java using Runtime.exec() is a source of well known problems. Like waiting for a Process to finish, but not consuming the data from the stream buffers is a sure way for you application to hang.
I would suggest you use a library like Apache Common Exec to handle this.
I worked on a project a while back where we used Runtime.exec() to launch a process that would eventually extract files over existing files. All worked well except on one machine used for staging - it would just hang. It turned out on that staging machine, someone had set the date/time back so it looked liked the new files being extracted where older than the existing one, causing the external process to generate a warning message for each, overflowing the error buffer - which our application was not consuming!

Run bat file from java code and wait for it to execute TestComplete script - no can do :(

I am writing this question which is related to my previous topic:
Run bat file from java code to get desired result in txt file - no can do :(
In a shortcut: i wrote a program in java that runs a bat file. This bat file runs TestComplete8 script that performs desktop application test. After test is finished, bat file generates file called result.txt and prints information about test to it.
I'm stuck with another issue right now: Now from my java code i would like to wait until the bat run is finished. I do that by looping until the file called result.txt exists. Not the nicesest solution i guess but I thought it could work, also tried different solutions. What happens is that it will loop fine and wait until file exists, but testcomplete doesn't perform the test. It is very strange, because testcomplete runs, i can see that test starts, my AUT starts as well, but than nothing happens. Testcomplete is waiting for any object and doesn't click anywhere just waits until predefined time for action runs out. When i run the test without any waiting done in code, everything is fine. I just don't understand why nothing happens during the test when waiting is enabled and why it works fine when i just remove any do - while or waitFor(), or even i tried running it in seperate threads. :(
I have a feeling that it may be somehow related to the OS and have something to do with processes as it runs something like a bat as process and than bat runs it's child process as testcomplete or sth like that.
Thanks for any answers
Source code as asked:
Right now i was trying a solution with modified bat file:
#ECHO OFF
"C:\Program Files (x86)\Automated QA\TestComplete 8\Bin\TestComplete.exe" "C:..." /r /p:projname PathToApp="C:\...p" Login=... Password=B1 /t:"KeywordTests|..." /exit
and the code to run and wait in latest version is:
new Thread(new Runnable() {
public void run() {
File file = new File("D:\\");
int exitValue = -1;
try {
Process process = Runtime.getRuntime().exec(batch, null, file);
while (true) {
try {
exitValue = process.exitValue();
System.out.println(exitValue);
break;
} catch (IllegalThreadStateException e) {
// e.printStackTrace();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("Waiting for process...");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
The most likely cause, without knowing more about the problem, is a common one faced when launching external processes from Java. When launching an external process three streams are created between the parent and child process, input, output, error.
You can liken these to System.in, System.out and System.err. If the parent process (Java) does not actively consume the data on the out and error streams the child process may block as the OS will reach a buffer limit on the stream and prevent any more being written until it is consumed. This is quite likely if your script writes to standard out or standard error.
I would recommend using apache commons-exec to handle Java process launching.
Here's a code sample that I know works.
CommandLine commandLine = new CommandLine( "TestComplete8.bat" );
commandLine.addArgument( ... );
commandLine.addArgument( ... );
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue( 0 );
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
executor.setStreamHandler( new PumpStreamHandler( outputStream, errorStream ) );
try
{
executor.execute( commandLine );
}
catch ( ExecuteException e )
{
// TODO: ...
}
catch ( IOException e )
{
// TODO: ...
}
Then you can examine the output/error streams if you wish when execute returns.

unable to run ksh script from java: java.io.IOException: .: not found

I tried to run a shell script from java code, but I am facing problem. The script is in batchstart.sh file -
#!/bin/ksh
export DISPLAY=:0.0
Now the script is run with a dot on the command line -- . batchstart.sh
How do I run it from java? My java code is below. It throws the following exception -
java.io.IOException: .: not found
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:102)
at java.lang.ProcessImpl.start(ProcessImpl.java:65)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:451)
at java.lang.Runtime.exec(Runtime.java:591)
at java.lang.Runtime.exec(Runtime.java:429)
at SetDisplay.main(SetDisplay.java:12)
import java.io.*;
public class SetDisplay {
public static void main(String[] args) {
File wd = new File("/myhomedir/");
System.out.println("Working Directory: " +wd);
Process proc = null;
try {
proc = Runtime.getRuntime().exec(". batchstart.sh", null, wd);
} catch (Exception e) {
e.printStackTrace();
}
}
}
How do I make the shell script run ?
I tried the following code as well, but that too doesn't work.
File wd = new File("/bin");
System.out.println(wd);
Process proc = null;
try {
proc = Runtime.getRuntime().exec("/bin/bash", null, wd);
}
catch (IOException e) {
e.printStackTrace();
}
if (proc != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
out.println("cd /home/");
out.println(". batchstart.sh");
out.println("exit");
try {
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
proc.waitFor();
in.close();
out.close();
proc.destroy();
}
catch (Exception e) {
e.printStackTrace();
}
}
When run from the command line, using a dot at the start of a script indicates that the script should be run in the current environment, instead of spawning a new subshell and using a new copy of the current environment. This allows you to export a new value of an environment variable to be used by commands run later from the same interactive shell.
Obviously, this technique only works if you are running your batchstart.sh script from an actual shell. Java does not know how this mechanism works and so the dot means nothing to it. A script cannot modify the environment of the Java process it was called from.
If your goal is to change the value of the DISPLAY environment variable for other commands run by your Java process, consider using the ProcessBuilder class to specify a new environment for the child process. Java does not contain a built-in way to modify variables in its own environment.
The source command (".") is a shell built-in. You have to explicitly run /bin/ksh, passing your script name as the argument (followed by any script arguments).
You have a larger problem if you need to source the script. That usually means that environment changes happen in the context of the current shell, not a subshell.
This won't work with Java since Java's not a shell. You'll need to figure out how to change the environment with Java.
Of course, if I'm wrong and there's more to that script that just setting DISPLAY, it may work as suggested.
The method you're going to have to use depends on what you're trying to achieve(as in "Are you running other programs using exec() that rely on DISPLAY being set?" or "Does your Java program need DISPLAY to be set?").
If, as you state in your comment, it's only your Java program that needs DISPLAY set, just set it outside before your program runs. Create a cmd (or bash) file which sets the DISPLAY variable then calls the JRE to run your program.
#/bin/ksh
export DISPLAY-:0.0
/usr/bin/jre/java your_program blah.blah.blah
I would also modify your main() to check that it's set to something and exit gracefully if not:
if (System.getenv ("DISPLAY") == null)
// doesn't exist, exit gracefully.
The period "." is a shell built-in, and executes the script "in-place", analogous to #include in C/C++. Using "." outside of a shell-script has no meaning.
If you want to run the script from Java, you have to execute the script interpreter (/bin/ksh):
Runtime.getRuntime().exec("/bin/ksh batchstart.sh", ...)
but note that this is not semantically equivalent, since you're executing batchstart.sh as a sub-process instead of sourcing it.

Categories

Resources