I have python code. I run it using python -m base-package arguments
I want to run this project from a spring boot project and use the output given by the python. I could not find any simple tutorial, is there any simple way to get this done?
Try execute your command with this:
private String getResponseFromCommand(String command) throws IOException {
Process process = exec(command);
InputStream in = process.getInputStream();
String response = new BufferedReader(
new InputStreamReader(in))
.lines().collect(Collectors.joining("\n"));
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
I wrote this for running docker commands and getting feedback from them. It should work for any command though.
Related
I'm working on an application written in Java. The application is composed of many modules (maven). My task is to add a new module containing the application code written in ElectronJS and run it with Java code.
I did it this way.
private void turnOnElectronApp() {
ElectronAppRunner electronAppRunner = new ElectronAppRunner();
electronAppRunner.turnOnElectronApp();
}
public class ElectronAppRunner {
public void turnOnElectronApp() {
String user_dir = System.getProperty("user.dir");
user_dir += "/electron-app/src/main/electron-frontend-main";
System.out.println(user_dir);
String command = "npm start";
File workDir = new File(user_dir);
Runtime rt = Runtime.getRuntime();
try {
Process pr = rt.exec(command, null, workDir);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The application starts but the problem arises when building the project production version. Because user.dir is changing. How else can this be done?
I made spark+hadoop yarn enviroment and spark-submit command works well. So I made SparkLauncher java code to do this in my application jar, BUT somehow it doesn't work (actually computer fan is spinning at first but not as long as i did with spark-submit.)
It seems not work well (no application log in hadoop web ui, unlike spark-submit). I cannot see any error log when I do with 'SparkLauncher'. without log message, I can do nothing with it.
Here is how I made it so far.
public class Main {
public static void main(String[] args) {
Process spark = null;
try
{
spark = new SparkLauncher()
.setAppResource("/usr/local/spark/examples/jars/spark-examples*.jar")
.setMainClass("org.apache.spark.examples.SparkPi")
.setMaster("yarn")
.setDeployMode( "cluster")
.launch();
}
catch( IOException e)
{
e.printStackTrace();
}
}
}
executed it with ( java -jar example.jar)
I had the same problem at first. I think the main issue is that you forgot about the waitFor().
Also, it's really helpfull to extract your errorMessage and deal with it (e.g. log it or checking it while debuging ) within your java code. To allow this, you should create a streamReader thread as follows:
InputStreamReaderRunnable errorStreamReaderRunnable = new InputStreamReaderRunnable(spark.getErrorStream(), "error");
Thread errorThread = new Thread(errorStreamReaderRunnable, "LogStreamReader error");
errorThread.start();
int result= spark.waitFor();
if(result!=0) {
String errorMessage = extractExceptionMessage(errorStreamReaderRunnable.getMessage());
LOGGER.error(errorMessage);
}
This should be after your launch() command and inside your try block. Hope it helps
I'm writing a code that runs a commandline using default executor of apache.
I found the way to get the exit code but I couldn't found the way to get the process ID.
my code is:
protected void runCommandLine(OutputStream stdOutStream, OutputStream stdErrStream, CommandLine commandLine) throws InnerException{
DefaultExecutor executor = new DefaultExecutor();
PumpStreamHandler streamHandler = new PumpStreamHandler(stdOutStream,
stdErrStream);
executor.setStreamHandler(streamHandler);
Map<String, String> environment = createEnvironmentMap();
try {
returnValue = executor.execute(commandLine, environment);
} catch (ExecuteException e) {
// and so on...
}
returnValue = e.getExitValue();
throw new InnerException("Execution problem: "+e.getMessage(),e);
} catch (IOException ioe) {
throw new InnerException("IO exception while running command line:"
+ ioe.getMessage(),ioe);
}
}
What should i do in order to get the ProcessID?
There is no way to retrieve the PID of the process using the apache-commons API (nor using the underlying Java API).
The "simplest" thing would probably be to have your external program executed in such a way that the program itself returns its PID somehow in the output it generates. That way you can capture it in your java app.
It's a shame java doesn't export the PID. It has been a feature-request for over a decade.
There is a way to retrieve the PID for a Process object in Java 9 and later. However to get to a Process instance in Apache Commons Exec you will need to use some non-documented internals.
Here's a piece of code that works with Commons Exec 1.3:
DefaultExecutor executor = new DefaultExecutor() {
#Override
protected Process launch(final CommandLine command, final Map<String, String> env, final File dir) throws IOException {
Process process = super.launch(command, env, dir);
long pid = process.pid();
// Do stuff with the PID here...
return process;
}
};
// Build an instance of CommandLine here
executor.execute(commandLine);
I can't for the life of me figure out how to start a nd stop a server for the game Minecraft using two buttons in Java.
So far I have this mess..
try
{
ProcessBuilder processBuilder = new ProcessBuilder("/Users/UserName/Desktop/servers/test/launch.sh");
Process server;
if (event.getSource() == start_Btn)
{
server = processBuilder.start();
//OutputStream out = server.getOutputStream();
start_Btn.setText("Started");
}
else if (event.getSource() == stop_Btn)
{
OutputStream out = server.getOutputStream();
server.getOutputStream().write(new String("stop").getBytes("utf-8"));
stop_Btn.setText("Stoped");
start_Btn.setText("Start");
}
}
catch (IOException exception)
{
}
catch (InterruptedException exception)
{
}
I have been scouring the internet for the entire day today and I've decided to finally bring it to you guys.
I want to be able to start the server by pressing a "Start" button, then stop it with a "Stop" button I have a GUI set up and I know how to set up button events. I can get the server to start with the start button easily, it is just the stopping feature I can't seem to manage.
Note: To stop the server you must enter in "stop" in the command line where the server was initiated.
Thank you very much for your help, I greatly appreciate it.
Seeing as though there never was an answer that solved my question, and seeing as though I figured it out on my own I figured I'd post it for everyone else happening on the question.
I use a couple classes to accomplish this goal, two to be exact.. One to be the thread that houses the server and the other to send commands to the server.
First things first, the code to start and house the server stream.
The first class here is where the magic happens
public class Sender{
ConsoleWriter cWriter = new ConsoleWriter();
public void execute(){
this.ui = ui;
try{
ProcessBuilder pb = new ProcessBuilder(path_to_server+"launch.bat");
Process process = pb.start();
StreamGobbler sgError = new StreamGobbler(process.getErrorStream());
new Thread( sgError ).start();
writer = new PrintWriter( process.getOutputStream() );
} catch ( IOException e ){
e.printStackTrace();
}
}
private class StreamGobbler implements Runnable
{
private InputStream is;
public StreamGobbler( InputStream is ){
this.is = is;
}
#Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader( is );
BufferedReader br = new BufferedReader( isr );
String line = null;
while ( ( line = br.readLine() ) != null ){
cWriter.writer(line, ui);
}
} catch ( IOException e ){
e.printStackTrace();
}
}
}
}
How does this work you ask? Let's take it from the top.
ConsoleWriter
This is the class I wrote to write the stream from Minecraft's server console to my own GUI, the code for this isn't important so I'll leave it out. You can write that part.
execute()
This method builds the process for the server using Java's ProcessBuilder then starting the process. More importantly, we have the StreamGobbler.. This gives us access to and 'gobbles up' the input stream from the server. Basically it receives all the output the console from the server. For some reason, not sure why, the Minecraft server likes the ErrorStream so I've bound it to that. Then I create a new Thread for the gobbler and that's that. Last thing in this method is the...
PrinterWriter
This binds to the Server as an output which let's me send commands to the server like for stopping it or really any other server command available.
StreamGobbler class
Now, onto the Gobbler its self. Not too much here. Basically just taking the inputStream we sent from the execute method sending it to a reader, then buffering it and finally reading it to my console writer.
The second Class is quite simple!
public class WriteCommand
{
public void send(String command)
{
txtA.append("Command:>>"+ command + "\n");
writer.write(command);
writer.write("\n");
writer.flush();
}
}
All this is doing is writing the command and hitting 'enter' then flushing it to be ready to send the next! txtA.append is for adding the command that was sent to my own console output simply a visual item.
And there you go! Hopefully this will help someone else out.
If you'd like to see this code in action you can see it as part of the app I've used it in.
Here is a link: Minecraft Server Utility(BETA)1.3.6
I was working on this same task today. I am a novice at java but I think I found what you may be missing.
I more or less followed your lead but in the stop command use the slash "/stop"
also it seems that I needed to close the outputstream in order for the action to complete.
private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
oS.write(new String("/stop").getBytes("utf-8"));
oS.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I hope that this helps you.
Need to execute an external EXE from either a Java web app (running on Glassfish on Windows Server) or from an Flex/AIR desktop app.
Any suggestions, links?
Thanks,
You cannot execute an executable on the client from a web application on the server. It would be very bad if you could.
You also cannot execute something from AIR, since it is outside the security sandbox. You can, however, do so from an AIR2EXE application like Shu or airAveer, but this will change your deployment strategy.
If you do not need AIR-specific APIs, you can also use a SWF2EXE application like Screenweaver (open source) or Zinc.
Okay .. I found the answer ...
import java.io.*;
public class Main {
public static void main(String args[]) {
try {
Runtime rt = Runtime.getRuntime();
//Process pr = rt.exec("cmd /c dir");
Process pr = rt.exec("c:\\helloworld.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line=null;
while((line=input.readLine()) != null) {
System.out.println(line);
}
int exitVal = pr.waitFor();
System.out.println("Exited with error code "+exitVal);
} catch(Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
}
}