I used system("java .....")to run a java app in cmd with VC++ code.
The java app will run a server in the cmd,it will output info in the console.And I can also enter commands to it just like run "dir" commands in cmd.
Now I want get all the output in my program and use C++ code to write commands sent to the java app.
But I found that the system() won't return until I stop the java app.It's reasonable.And how to avoid it?Use Thread ?
And the biggest problem is I don't know how to get the output and write commands,can anyone give me a method?
Thanks a lot!
P.S. The java app's code can't be changed.
--------------------------------------I have made progress--------------------
int main()
{
char psBuffer[256];
FILE* output = _popen("java xxxx.jar", "rt" );
if(output == NULL)
return 0;
while(fgets(psBuffer, 256, output))
{
printf(psBuffer);
}
if (feof( output))
{
printf( "\nProcess returned %d\n", _pclose( output ) );
}
else
{
printf( "Error: Failed to read the pipe to the end.\n");
}
system("pause");
return 0;
}
When I use "dir".It works perfect!But when I use java,psBuffer is always nothing,and the output of java app is normally.Is it pipe cannot redirect java's output?
I change my code and make some java command run perfect:
FILE* output = _popen("java -version 2>&1", "rt" );
But when it run that .jar,It failed.I read the .jar's code and find the output is create by java.util.logging.Logger.info().I'm not familiar with java. How dose the info() work in cmd?
Thanks many!
Finally, I found last code above is work correctly.But origin output of java app haven't been redirect .It will display normally,but buffer is correctly received the output I want.Anyway I solved my problems.Thanks everyone!!!
The MSDN article Creating a Child Process with Redirected Input and Output explains how you can do it. It is quite a lot of code to go through, but will allow you to do what you want, and give you full control over it.
On the other hand, using _popen is much easier, but you don't have as much control. Depends on your exact needs as to how much code you'll be writing :).
Related
I am working on a simple meteo station - I want to use raspberry pi 3b+ as a host, dht22 sensor and write a web application in Java (with spring boot, then deploy it to tomcat 8) and Python for retrieving sensor's data.
What I've done so far:
Python application for retrieving and displaying data. Works as expected, it just prints something like "22.5;37.4":
import Adafruit_DHT
DHT_SENSOR = Adafruit_DHT.DHT22
DHT_PIN = 4
humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
if humidity is not None and temperature is not None:
print("{0:0.1f};{1:0.1f}".format(temperature, humidity))
else:
print("FAIL")
Then I've wrote a java application, put it into .jar and checked if I am able to get sensor's data. Not a rocket science, also works as expected when I use java -jar InputTest.jar on my raspberry pi:
public static void main(String[] args) {
try {
ProcessBuilder pb = new ProcessBuilder("python", "/home/pi/Desktop/input/dht_once.py");
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println("measured: " + line);
}
process.waitFor();
} catch (IOException ) {
System.out.println(" exception " + e.getLocalizedMessage());
}
}
Then I've created a spring boot application, put my java code inside (logic same as above), packed as a war, deployed to tomcat 8 and run it. It turned out nothing is being printed (of course I've changed code to log output to logfile, it works fine, I can see other logs inside). No issues in logs, it looks like reader never returns a line.
I believe application does not wait for a process to produce output, but I have no idea why. Important thing: it takes up to few seconds to produce sensor's output. I've also changed python script just for test purposes to return value immediately:
print("22.4;33.0")
and it results in successful read by java web application. But when it has to wait few seconds for the output it kills process (process.isAlive() is false right after while loop).
I've also tried to play with sleep() on current thread to force it to wait for python process but no success.
Do you guys have any idea what can be the reason for this behavior? Is there anything more I should check?
TLDR;
Java application which creates python process works fine until I run it as a web application - then it looks like it does not wait for a process' output
I haven't found a solution yet, however I've implemented workaround/cleaner solution.
I've decided to separate totally java and python code and created microservice for data retrieving. I use flask for rest webservice (followed this tutorial https://docs.dataplicity.com/docs/control-gpios-using-rest-api) and call it directly from java.
Since this does not resolve my initial question I do not mark it as an answer, however it might help someone.
I am trying to write a program that calls external jars from the command line. In my code it will do java -jar test,jar args. What I want to know though is if a error occurs in this external jar, how to catch it in my java program so I can do the necessary procedure? This is a new zone of coding for me from college level so I am a little clueless.
Command-line programs returns exit status when finished executing it's work (e.g. zero when everything is ok).
You should be able to retrieve something interesting by storing the return value of your system call and test it according to what you want to do.
// Code from https://stackoverflow.com/questions/8496494/
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("java -jar test.jar args");
// Check retVal to test
int retVal = pr.waitFor();
More about this in this SO question.
I am trying to call a perl script from java runtime. It worked fine on my windows7 laptop with the following code,
try {
String cmdString= "c:\\perl64\\bin\\perl.exe c:\\perl64\\eg\\userinput.pl \""+arg1+"\" \""+arg2+"\"";
Process p = Runtime.getRuntime().exec(cmdString);
} catch(IOException e) {
System.out.println(e);
}
The perl script runs and produces what I expect (update database).
When I move the whole thing over to a remote CentOS server, it doesn't work anymore. The script is the same and the java code is,
try {
String cmdString= "/opt/lampp/bin/perl /home/support/scripts/userinput.pl \""+arg1+"\" \""+arg2+"\" > /tmp/userinput.log";
log(cmdString);
Process p = Runtime.getRuntime().exec(cmdString);
} catch(IOException e) {
System.out.println(e);
}
I added redirect to /tmp/userinput.log after I see the script is not working. But there is no log file created at all. I also added log to make sure this part of the java code did get executed, and indeed it did. I also tried to add "/bin/bash " in front of the comString and it didn't make a difference. However, when I run the cmdString directly on the remote server from command line, it works without problem.
Now, when I changed the cmdString to "touch /tmp/userinput.log", it does create the empty log file.
So I know the Runtime.getRuntime().exec(cmdString) command ran, and the cmdString works when entered on command line, and a simple "touch" command would work with this setup. But I am totally lost why the actual cmdString that calls the perl script doesn't work, and there is no message whatsoever to tell me what is wrong.
Can someone please help?
Frist, separate each parameter for the command and use the version of exec which takes a String[] (you won't have to worry about quoting issues). also, shell redirection won't work since java isn't executing a shell.
I'm testing tidesdk.
I have a java program that reads from standard input.
I run the program through the console console
java -cp MyProgram.jar package.MyMainClass
And then execute commands and get results.
there any way to do with tidesdk?
Edit:
The problem was that calls the java program with a list of one element (which contained the command separated by spaces)
It solved with passing every word to a item of list (and removing the spaces).
Right now I have porblemas to write standard input. This is what I'm trying.
var input = Ti.Process.createPipe();
var process = Ti.Process.createProcess({
args:['java', '-cp', 'C:/.../MyProgram.jar', 'package.MyMainClass'],
stdin: input
});
//process.setOnReadLine(function(line) { alert(line) });
process.launch();
input.write("comand parameter1 parameter2\n"); //This line does not work
The java program starts. But never gets a command.
Checkout Documentation of Ti.Process.createProcess. That is exactly what you are looking for:
http://tidesdk.multipart.net/docs/user-dev/generated/#!/api/Ti.Process
How to exit the console of a simple Java program after displaying an error message?
currently my code has:
...
...
if (some condition){
//print error
System.exit();
...
...
But this System.exit(); leaves the console open. I have tried exit(0);, System.exit(0); as well.
If you're wanting to close the Command Prompt window that your application is running in, then I don't believe there is a way to do it (At least not nicely).
Why do you want to start your application from the command prompt and then close the pre-existing Command Prompt window? This will surely get rid of the error message that you're outputting (unless it's also being logged - in which case why print it to a window you want to close?).
This is Windows specific, but would creating a shortcut in Windows Explorer to java -jar MyJarFile.jar or java MyCompiledClass do what you want? Instructions for this sort of approach can be found here.
System.exit(1);
should work fine. Note that if you're exiting with an error, you would normally set a non-zero exit code. From the doc:
The argument serves as a status code; by convention, a nonzero status
code indicates abnormal termination.
This means you can script using common conventions, any process spawning your program can react correspondingly etc.
If I understand you correctly, you want to run your program in a command prompt and if the program fails you want it to display the error message, close the program AND the commad prompt window?
If this is the case then the only thing I could think of would to be to run your program in a batch file that checks the exit status of your program. So in your code write your error message, then I suggest sleep for a few seconds so the user can actually see it, then exit with status code 1.e.g.
if(SomeCondition){
System.err.println("ERROR MESSAGE...");
Thread.sleep(3000);//Sleep for 3 seconds...
System.exit(1);
}
Then run your program from a batch file which checks the "ERRORLEVEL" environment variable e.g.
java <INSERT_PROGRAM_NAME>
IF %ERRORLEVEL% == 1 exit
Hope this helps :)
java.lang.System doesn't have an exit method with no parameters, so System.exit(); would be a compile-error. (System.exit(1);, however, would be fine.) The reason that your code isn't working is probably that you're not recompiling it, so you're still running some old version from before you added that line.
Suppose you are trying to install firefox .bat file from java
public static void main(String[] args) throws InterruptedException {
try {
String[] command = { "cmd.exe", "/C", "Start", "C:\\firefox.bat" };
Runtime.getRuntime().exec(command).waitFor();
}
catch (Exception e)
{
System.out.println("Execution error");
}
}
This would trigger the command prompt and the window will be opened until you manually go and close it after the firefox is installed.
The fix is that in your .bat file just after your command just put an "exit" For eg:
Your firefox.bat would contain
#Start /wait "Firefox" "C:\Firefox Setup 41.0.exe" -ms
exit
This will close your command prompt window. Hope this helps...
have a look at the below link
http://www.cs.bris.ac.uk/jot/decisions/exercise11/exit.html
There is a general convention that a program must return an exit code. The exit code should be zero to indicate success, and non-zero to indicate failure. Platforms differ about what different non-zero codes mean, so programmers often just return 1 as a general indication of failure.
System.exit(); terminates the JVM. The int is the status code (0 means "normal" exit). If it's not exiting it's because that part of your code is not reachable and not being executed at all.
Java API - System.exit()