I use Java Runtime.getRuntime().exec(command) to create a subprocess and print its pid as follows:
public static void main(String[] args) {
Process p2;
try {
p2 = Runtime.getRuntime().exec(cmd);
Field f2 = p2.getClass().getDeclaredField("pid");
f2.setAccessible(true);
System.out.println( f2.get( p2 ) );
} catch (Exception ie)
{
System.out.println("Yikes, you are not supposed to be here");
}
}
I tried both C++ executable and Java executable (.jar file). Both executables will continuously print out "Hello World" to stdout.
When cmd is the C++ executable, the pid is printed out to console but the subprocess gets killed as soon as main() returns. However, when I call the .jar executable in cmd, the subprocess does not get killed, which is the desired behavior.
I don't understand why same Java code, with different executables can behave so differently. How should I modify my code so that I could have persistent subprocesses in Java?
PS: I am using Ubuntu 9.10 and OpenJDK-1.6. (Not sure if they matters~)
Newbie in this field. Any suggestion is welcomed.
Lily
The C++ EXE is almost certainly marked as a console app. I'm thinking a jar would be considered a GUI app by default, and would do the standard detach-from-the-main-process thing.
If you were to take the C++ code and turn it into a GUI app, i think you'd see it behave similarly to the jar.
Related
I am developing a programm in java, using Eclipse IDE, and I'm trying to run a python script using a java method.
This python script will simply write "Test2" in a txt file, so it really won't interfere with anything within my java programm.
The image bellow shows how my packages are organized:
The python script I wish to run is Communication.py, and I used the following method, (called by Systemm.java on the method main) to do so:
private void runServer() {
try {
System.out.println("Im running your py");
Process p = Runtime.getRuntime().exec("cmd /c python pythonClient\\Communication.py");
} catch (IOException e) {e.printStackTrace();}
}
However this method does literally nothing (apart from printing "Im running your py").
I have never really worked with java Runtime's class, and I just copied this command from the internet, so I'd really aprecciate any help, in solving this issue.
P.S: my other classes both py and java are all working smoothly. This is literally the only issue so far
I've used Amazon corretto and Java's jre(javaw.exe) to try running my jar file. The task manager says that 'Java Platform SE Binary' is running but no dialogue box(or display) of the jar program is shown on my laptop.
I even tried opening it through command prompt or through a bat file, all in vain.
Any and all help would be deeply appreciated! Thanks! Task Manager snap
A java app does.. what the java app does.
Which may well involve no GUI whatsoever. You won't notice anything whatsoever in your windows environment if the java app you're trying to start doesn't actively involve any GUI elements from e.g. the javax.swing package.
Try using java.exe - javaw.exe does not show any console input or output, whereas java.exe does. If it's a console app (that reads and prints text from the command line), it would simply appear to be doing nothing if you try to launch it with javaw.exe.
For example, this app:
// Save this as 'Example.java'
public class Example {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
then open a 'dos box' (run cmd.exe), navigate to the proper directory, and run:
javac Example.java
javaw Example
does nothing. You witness precisely what you are witnessing (or possibly you can't witness it as the app closes too fast. But you certainly won't see any windows or any text). Then run:
java Example
and you'll see: Hello, World! and then the app exits.
If 'the command line' is gobbledygook to you, well, if you want to program, you're going to have to know how it works, but, fortunately, there are plenty of tutorials around :)
I need to use ffmpeg-normalize (https://github.com/slhck/ffmpeg-normalize) to properly normalize audio files in my java program but ffmpeg-normalize requires manual installation and command usage.
I thought I could automate it in java using ProcessBuilder but it's been proving somewhat impossible.
ffmpeg-normalize is written in python, so I tried every stackoverflow question that relates to running python commands in java. None of them worked, it seems windows just refuses to allow java to run commands in general.
I added python to my environment variables as well. No dice. Windows keeps telling me it doesn't recognize python nor py nor pip as valid internal or external commands.
This is my final code, I tried all other solutions before this including Runtime.exe, using "cmd /c start", and all other derivatives of that.
My last attempt was running a .bat file from the java cmd processor and have the .bat do the rest, but not only is that windows only, but also fails.
Running pip in a cmd from cmd.exe directly (outside the java program I mean), it runs properly and shows me the help menu for pip. When the cmd opens from the java app, windows refuses to acknowledge the existence of python all together like in the image below.
Process process = Runtime.getRuntime().exec("cmd /c start " + installerBat.getAbsolutePath(), null, ffNormExtractDir);
StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream());
StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream());
errorGobbler.start();
outputGobbler.start();
try {
process.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I expected the java-born cmd to run the commands instantly and perfectly, but it simply refuses to run them.
So what is my best approach to make installing ffmpeg-normalize a breeze to the user?
I'm on Linux and I have a Java application (JAR archive) which is using exec() to do it's stuff. I need to find out which commands is that application exec()uting... I tried strace and jstack but without any results. Suppose that the app is calling exec("ls"), can I find that ls command just by grepping output of above programs?
So the question is:
Is there a simple way to watch what is Java application executing with exec() ?
Edit for better situation overview:
Suppose that in Java app i have a button with onclick listener which calls static function from another class.In that function is exec("ls"); called.
When I click that button I see this in strace:
futex(0x7f14a6f799d0, FUTEX_WAIT, 4968, NULLDownload button clicked !
Trying SCP FROM...
<unfinished ...>
Trying SCP FROM.. is just my sout in that button handler right before calling exec().
Another edit:
Thank you guys, but I'm talking from OS point of view... Suppose that I'm sysadmin and I downloaded JAR. I want to know (from outside) what is that JAR doing - I'm only interested in programs started from exec()
So I tried strace but it shows nothing about calling that command from exec... Maybe it is logging too much low level calls for this...
Then i tried jstack -m but I can't find anything looking like that command from exec. I tried grepping string but with no luck.
Ok, what I'm going to propose is a veeeeeeeeeery rudimentary way of doing things, but it might be what you are looking for.
As you probably know, a .jar file is just a ZIP archive comprised of Java .class files. If you just need to get a peek at which commands are going to be executed, and if you know the class that is supposed to execute them, you can just extract the class files from the jar file with gzip and then use strings on them to look for commands.
For example, here's the most simple class I could think of that uses exec():
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
Runtime.getRuntime().exec("/bin/ls");
} catch (IOException ignored) {}
}
}
If you do strings Main.class you should get something like this:
[...]$ strings Main.class
<init>
Code
LineNumberTable
LocalVariableTable
this
LMain;
main
([Ljava/lang/String;)V
args
[Ljava/lang/String;
StackMapTable
SourceFile
Main.java
/bin/ls
java/io/IOException
Main
java/lang/Object
java/lang/Runtime
getRuntime
()Ljava/lang/Runtime;
exec
'(Ljava/lang/String;)Ljava/lang/Process;
As you can see, /bin/ls can be identified as a string. This should work in most cases, unless your Java program is constructing commands in a weird way, like using a char array to create command strings during runtime just to obscure the commands being executed (in which case I'd be highly suspicious of such a program).
However, if you want to see the commands executing in real time, I'm afraid you'll need to resort to some monitoring utility, since most commands would be too short-lived to even appear on top and the like.
EDIT: Regarding strace: I had a look at Java's native C code for UNIX systems and it seems that it actually uses the execvpe() system call to run all commands launched with Runtime.exec():
execvpe(argv[0], argv, envv);
So, in theory, you should be able to run strace -e execvpe <java command...> to list every command executed (as well as every other call to execvpe() -- you'll need to filter a bit more, that's true).
We all mostly use System.out.println in the Console of our IDE. I am using Eclipse.
I can also clearly see the println() message on my Mac's Console app. Which is nice for my personal things.
And here is the code:
public class Main {
public static void main(String[] args) {
System.out.println("Is this logged anywhere?");
}
}
And here's what I see on my Mac:
Does Windows have something similar to the Mac's version of Console?
Sadly, as previously said, we don't really have that on Windows. Your best options is to run your program from CMD and then pipe the standard out to a file. Something like java -jar HelloWorld.jar > hello.txt.
What I usually do is create a Handler to a log file (usually just [program name] log [date].txt and have all messages outputted there depending on the log level, which is good practice if you're used to only using System out prints.
Straightforward answer remains that no such functionality comes standard with Windows. You'll have to pipe to a file in some manner.
It does not. However you can simply run the process from a command prompt if you want to examine its stdout. (As you said, eclipse works too, of course.)