I am trying to make my own Java IDE, however i am having problems getting the input from user after displaying the program itself
I have so far tried 2 ways of getting the console to appear.
Using Create Java console inside a GUI panel
or using my own code of
void runCommand(String command)
{
try {
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", command);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
} catch (IOException ex) {
Logger.getLogger(FileToClass2.class.getName()).log(Level.SEVERE, null, ex);
}
}
void createClass(String dir, String filename)
{
//TODO: stop using exact java path / compile all .java in a dir
runCommand("cd "+dir+" && \"C:\\Program Files\\Java\\jdk1.8.0_91\\bin\\javac\" " + filename);
}
void runClass(String dir, String filename)
{
//TODO: allow use of packages etc
runCommand("cd " + dir + " && java " + filename);
}
This above code simply gets the output of the cmd terminal, the problem both these approaches have is the lack of input say if the user wanted to do a Scanner nextLine()
Is there any solution to this?
Related
I'm currently working on a Plugin which also can execute commands in the Linux shell. I've setup some commands that I will need later. Killing screens is already working but now I want to start some screen's through my Plugin. But this isn't working.
I've tried to change from Runtime.getRuntime.exec(cmd); to a ProcessBuilder worked for killing screens.
My method to execute commands
public static void shellExecuteBuilder(String[] command, Player p, boolean bool, String Wrapper) {
ProcessBuilder prb;
try {
prb = new ProcessBuilder(command);
prb.redirectErrorStream(true);
Process pro = prb.start();
BufferedReader r = new BufferedReader(new InputStreamReader(pro.getInputStream()));
String line;
while (prb.redirectErrorStream() == true) {
line = r.readLine();
if (line != null) {
System.out.println(line);
}
}
if (bool == true) {
p.sendMessage("§aDer Wrapper §e" + Wrapper + " §awurde angehalten!");
} else {
p.sendMessage("§aDer Wrapper §e" + Wrapper + " §awurde gestartet!");
}
} catch (IOException e) {
if (bool == true) {
p.sendMessage("§cDer Wrapper §e" + Wrapper + " §ckonnte nicht angehalten werden!");
} else {
p.sendMessage("§cDer Wrapper §e" + Wrapper + " §ckonnte nicht gestartet werden!");
}
e.printStackTrace();
}
}
How I setup this in another method
String[] command = new String[] {"/bin/sh", "-c", "cd /path/to/my/script/", "./start.sh"};
shellExecuteBuilder(command, p, false, Wrapper);
I expected that my method will startup a new screen but it actually does not do anything.
/bin/sh can accept a sequence of commands, but formatted differently than you have it. Try this instead:
String[] command = new String[] {"/bin/sh", "-c", "cd /path/to/my/script/; ./start.sh"};
Also, the way you process the output from the process will never end. The while loop should be testing the returned output from the process, not the redirection setting (which will never change). Here's a modified version that properly reads the output and wait for the subshell to exit. Note that I removed some of your app's variables (bool, Wrapper, Player) to simplify the example:
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
public class TestPB {
public static void shellExecuteBuilder(String[] command) {
ProcessBuilder prb;
try {
prb = new ProcessBuilder(command);
prb.redirectErrorStream(true);
Process pro = prb.start();
BufferedReader r = new BufferedReader(new InputStreamReader(pro.getInputStream()));
String line;
while( (line = r.readLine()) != null) {
System.out.println(line);
}
pro.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
public static final void main(String[] args) {
TestPB tpb = new TestPB();
String[] command = new String[] {"/bin/sh", "-c", "cd /path/to/my/script/; ./start.sh"};
TestPB.shellExecuteBuilder(command);
}
}
Alternatively, instead of telling the shell to change directory ProcessBuilder can do it, although not with the way you currently have your program 'factored':
ProcessBuilder prb = new ProcessBuilder ("/bin/sh", "-c", "./startsh");
prb.directory("/path/to/my/script");
prb.redirectErrorStream(true);
Process pro = prb.start();
or using 'fluent' style all in one statement:
Process pro = new ProcessBuilder ("/bin/sh", "-c", "./startsh")
.directory("/path/to/my/script").redirectErrorStream(true).start();
Am trying to run the source code from this link
Compile and run source code from Java application
I installed the Mingw32 compiler changed the compiler location path and getting this error when running a sample .cpp file in Eclipse.
public class C_Compile {
public static void main(String args[]){
String ret = compile();
System.out.println(ret);
}
public static String compile()
{
String log="";
try {
String s= null;
//change this string to your compilers location
Process p = Runtime.getRuntime().exec("cmd /C \"C:\\MinGW\\bin\\mingw32-gcc-4.6.2.exe\" C:\\MinGW\\bin\\Hello.cpp ");
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
boolean error=false;
log+="\n....\n";
while ((s = stdError.readLine()) != null) {
log+=s;
error=true;
log+="\n";
}
if(error==false) log+="Compilation successful !!!";
} catch (IOException e) {
e.printStackTrace();
}
return log;
}
public int runProgram()
{
int ret = -1;
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("cmd.exe /c start a.exe");
proc.waitFor();
ret = proc.exitValue();
} catch (Throwable t)
{
t.printStackTrace();
return ret;
}
return ret;
}}
Errors:
mingw32-gcc-4.6.2.exe: error: CreateProcess: No such file or directory
Can anyone tell me where to place my Source .cpp File. Thanks
The error message indicates, that the gcc compiler itself was not found.
Why don't you use gcc.exe instead of mingw32-gcc-4.6.2.exe anyway? If you do an update of MinGW, the latter will get invalid!
Also you do not need to use \" in the string, when the path does not contain whitespace characters.
You can place your cpp file then anywhere you want, providing the path to that gcc. Exec should also have a parameter dir, that you can set to the directory of your cpp.
public static void CompileCprog(String filename){
File dir = new File("C://Users//JohnDoe//workspace//Project");
try {
String exeName = filename.substring(0, filename.length() - 2);
Process p = Runtime.getRuntime().exec("cmd /C gcc " + filename + " -o " + exeName, null, dir);
// Process p = Runtime.getRuntime().exec("cmd /C dir", null, dir);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
This works perfectly for me.
The "dir" variable can be set to any location you want.
The first "p" process compiles a program and produces a .exe file with the same name (minus the .c) in the same location of the program you are compiling.
The buffered reader can be used if there is output from your command.
If you changed the command string to .exec("cmd /C dir"); the result of this will be printed in the output. (im using eclipse)
My program requires that I run a .bat file which will compile java source. This is running fine, however I am looking for a solution which will get the output (and possible errors) of compile.bat and add it to a text pane on a GUI. I have the following code, however when executed the process happens without printing anything to the pane and without any errors.
GenerationDebugWindow.main(null);
Process process = rut.exec(new String[] {file.getAbsolutePath() + "\\compile.bat"});
Scanner input = new Scanner(process.getInputStream());
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
String line;
int exit = -1;
while ((line = reader.readLine()) != null) {
// Outputs your process execution
try {
exit = process.exitValue();
GenerationDebugWindow.writeToPane(line);
System.out.println(line);
if (exit == 0) {
GenerationDebugWindow.writeToPane("Compilation Finished!");
if(new File(file + "/mod_" + WindowMain.modName.getText()).exists()){
GenerationDebugWindow.writeToPane("Compilation May Have Experienced Errors.");
}
}
} catch (IllegalThreadStateException t) {
}
}
GenerationDebugWindow
private static JTextPane outputPane;
public static void writeToPane(String i){
outputPane.setText(outputPane.getText() + i + "\r\n");
}
Use:
Runtime.getRuntime().exec( "cmd.exe /C " + file.getAbsolutePath() + "\\compile.bat" );
Reference this question: Java Process with Input/Output Stream
It's likely that the output of the process is going to the error stream. However, ProcessBuilder is a more useful class than directly using System.getRuntime().exec()
In the example below, we're telling the ProcessBuilder to redirect the error stream to the same stream as the output goes to, which simplifies the code.
ProcessBuilder builder = new ProcessBuilder("cmd.exe /C " + file.getAbsolutePath() + "\\compile.bat");
builder.redirectErrorStream(true);
builder.directory(executionDirectory); // if you want to run from a specific directory
Process process = builder.start();
Reader reader = ...;
String line = null;
while ((line = reader.readLine ()) != null) {
System.out.println ("Stdout: " + line);
}
int exitValue = process.exitValue();
My program requires that I run a .bat file which will compile java source.
Your users on *nix and OS X require that source be compiled using the JavaCompiler.
The STBC is an example of using the JavaCompiler. It is open source. It uses a JTextArea as opposed to a JTextPane to hold the source and errors, but should be trivial to adapt.
public static void main(String[] args) throws Exception {
System.setOut(new PrintStream(
new FileOutputStream("/home/main/smt/output/out.txt")));
try {
String line;
Process p = Runtime.getRuntime().exec(
"/home/main/smt/tools/moses-2010-08-13/moses/moses-cmd/src/moses " +
"-f /home/main/smt/work/model/moses.ini " +
"< /home/main/smt/work/corpus/dataset.en" );
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()) );
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (Exception e) {
// ...
}
}
the command
home/main/smt/tools/moses-2010-08-13/moses/moses-cmd/src/moses
-f /home/main/smt/work/model/moses.ini
< /home/main/smt/work/corpus/dataset.en
>/home/main/smt/output/out.txt
gets executed in terminal of Linux and out.txt is created. But in java no out.txt is created.
dataset.en is the input file. Using exe moses which is in src and moses.ini in model the content in dataset.en gets translated and saved in out.txt.
But here while running this code no out.txt is created. I removed saving output in a file from the command eventhough nothing gets displayed in the console. If i change Process p = Runtime.getRuntime().exec(ls) its working fine.
Shell can interpret the redirection and arguments. You should instead try
String[] cmd = {"/bin/ksh", "-c", "yourcommand < infile"};
Process process = Runtime.getRuntime().exec(cmd);
I'm trying to get my program to launch Enchanter to SSH into my server, but can't seem to figure out how to get in and output to go to stdin and stdout, or anywhere for that matter. I just get a blank output window in Netbeans. How to I get the Jar to run, and get input/output?
public class openShell {
public void openShell() throws IOException {
String line;
Scanner scan = new Scanner(System.in);
ProcessBuilder builder = new ProcessBuilder ("C:\\Program Files\\Java\\lib\\enchanter-beanshell-0.6.jar", "myscript.bsh");
builder.redirectErrorStream(true);
Process process = builder.start();
OutputStream stdin = process.getOutputStream ();
InputStream stderr = process.getErrorStream ();
InputStream stdout = process.getInputStream ();
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));
while (scan.hasNext()) {
String input = scan.nextLine();
if (input.trim().equals("exit")) {
// Putting 'exit' amongst the echo --EOF--s below doesn't work.
writer.write("exit\n");
} else {
writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n");
}
writer.flush();
line = reader.readLine();
while (line != null && ! line.trim().equals("--EOF--")) {
System.out.println ("Stdout: " + line);
line = reader.readLine();
}
if (line == null) {
break;
}
}
}
}
private void LaunchButtonActionPerformed(ActionEvent evt) {
//openShell open = new openShell(); //RUNS BUT NO IN OR OUTPUT
//BELOW CODE IS FOR TESTING, JUST TRYING TO GET PROCESSBUILDER TO CONNECT
// TO MY JAR
try {
ProcessBuilder builder = new ProcessBuilder(
"Java -jar C:\\Program Files\\Java\\lib\\enchanter-beanshell-0.6.jar");
builder.redirectErrorStream(true);
Process process = builder.start();
} catch (IOException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
The method ProcessBuilder.inheritIO will redirect your command streams in your stdin, stdout and stderr. This applies to Java 7.
String[] args = {
"java",
"-jar",
"C:\\Program Files\\Java\\lib\\enchanter-beanshell-0.6.jar"
};
ProcessBuilder builder = new ProcessBuilder(args);
Start with breaking up the arguments as above. Then implement all the recommendations of When Runtime.exec() won't.
The methods Process.getInputStream and Process.getOutputStream will get you streams that you can then read from and write to.