I made this code to move a folder then hardlink it to it's original destination. The problem it works fully when I'm just trying it from eclipse but when I make it into it's own self executing jar it wont create the hardlink but it will move the folder. The code runs a command line and then enters the commands. I dont know ehy the move command works and not the other one. Please help.
(Mklink command)
import java.io.*;
import javax.swing.JOptionPane;
public class The_Cloud_Setup {
public static void main(String[] args) throws IOException
{
try {
String command = "c:\\cmd.exe";
Runtime.getRuntime().exec(command);
}
catch (IOException e){
JOptionPane.showMessageDialog(null , e.getMessage(), "End Result", 2);
System.err.println(e.getMessage());
}
String[] StringMove = { "cmd.exe", "/c", "move"+" "+"\"C:/Users/%username%/Documents/My Games/Terraria/Players\""+" "+"\"C:/Users/%username%/Google Drive/Players\""};
String[] StringMklink = {"cmd.exe", "/c", "mklink"+" "+"/d"+" "+"\"C:/Users/%username%/Documents/My Games/Terraria/Players\""+" "+"\"C:/Users/%username%/Google Drive/Players\""};
Process ProcessMove = Runtime.getRuntime().exec(StringMove);
Process ProcessMklink = Runtime.getRuntime().exec(StringMklink);
BufferedReader VarMove = new BufferedReader(new InputStreamReader(ProcessMove.getInputStream()));
BufferedReader VarMklink = new BufferedReader(new InputStreamReader(ProcessMklink.getInputStream()));
String temp = "";
while ((temp = VarMove.readLine()) != null) {
System.out.println(temp);
}
VarMove.close();
VarMklink.close();
}
}
Most likely, when you are running natively, the move command has not completed before your program attempts to execute the mklink command. You can't make a link where there is an existing folder.
Related
I have a problem with my Java program where I have a button that opens the command prompt and opens a batch file to run a series of commands. To do this, I need to change directory.
Here is my code:
private void CommandPromptButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
new java.lang.ProcessBuilder("cmd.exe").start();
java.lang.Runtime.getRuntime().exec(new String[]{
//I need to change the directory in command prompt and I do not want to use escape
"cmd.exe","/c","start","cd C:\Users\Faz"
});
} catch (IOException ex) {
Logger.getLogger(TMISGUIInstallerPage.class.getName()).log(Level.SEVERE, null, ex);
}
}
Any suggestions and advice are appreciated.
The following code should work
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"C:\\Users\\Faz\" && dir");
You could change the directory in the ProcessBuilder using the ProcessBuilder#directory() and then start the process. Here is a sample code:
ProcessBuilder start = new ProcessBuilder("cmd.exe", "/c", "start");
start.directory(new File("C:\\Users"));
start.start();
Upvoted Aukta's answer, it should solve your problem.
But as you asked:
To do this, I need to change directory.
Actually with ProcessBuilder and its directory(File directory), we can easily set the working directory. Here is a simple demo to list all files in a specified directory to show you how it can be used.
public static void main(String... args) {
ProcessBuilder processBuilder = new ProcessBuilder("ls"); // pass in your command and options;
processBuilder.directory(new File("/home")); // specify you directory here;
try {
Process process = processBuilder.start();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
The output:
gitlab-runner
hearen
ubuntu
Thanks for all of your help and suggestions. I have finally found an answer. I forgot to add that I tried using Java runtime but that does not run all commands. I have found that if I add another quotation mark, I can change the directory.
private void CommandPromptButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
new java.lang.ProcessBuilder("cmd.exe").start();
java.lang.Runtime.getRuntime().exec(new String[]{
//I need to change the directory in command prompt and I do not want to use escape
"cmd.exe","/c","start","cd C:\"Users\"Faz"
});
} catch (IOException ex) {
Logger.getLogger(TMISGUIInstallerPage.class.getName()).log(Level.SEVERE, null, ex);
}
}
Thank you for all of your help. Probs submit some more questions later. Cheers!
I want to run a python file that can run AWS CloudFormation template using JAVA.
I am passing python file in JAVA code.
When I run the JAVA code it pauses at the following state:
compile-single:
run-single:
If i run the Python file from terminal it works perfectly.
Java Code:
private void RunPythonActionPerformed(java.awt.event.ActionEvent evt) {
String pythonScriptPath = "path to python file";
String[] cmd = new String[2];
cmd[0] = "python"; // check version of installed python: python -V
cmd[1] = pythonScriptPath;
// create runtime to execute external command
Runtime rt = Runtime.getRuntime();
Process pr = null;
try {
pr = rt.exec(cmd);
// retrieve output from python script
} catch (IOException ex) {
Logger.getLogger(Page2.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
try {
while((line = bfr.readLine()) != null) {
// display each output line form python script
System.out.println(line);
}
// TODO add your handling code here:
} catch (IOException ex) {
Logger.getLogger(Page2.class.getName()).log(Level.SEVERE, null, ex);
}
}
Provide path to your source file at <complete path to your python source file>
Copying working code for you. For me output is Python 3.6.5
package com.samples;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ProcessBuilderSample {
public static void main(String [] args) throws IOException {
RunPythonActionPerformed();
}
private static void RunPythonActionPerformed() throws IOException {
String pythonScriptPath = "python -V";
Process p = Runtime.getRuntime().exec(pythonScriptPath);
BufferedReader bfr = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
try {
while((line = bfr.readLine()) != null) {
// display each output line form python script
System.out.println(line);
}
// TODO add your handling code here:
} catch (IOException ex) {
}
}
}
I have the following code to run three executions :
public static void main(String[] args) throws InterruptedException, IOException
{
String filepath1 = "cmd /c gradlew jmhJar";
String filepath2 = "cmd /c java -jar path/to/the/file/filename.jar -rf csv -rff path/to/save/file1.csv -wi 3 -i 5 -f 2";
String filepath4 = "cmd /c javac path/to/the/file/ParserHash.java";/*Code to compile is parserHash.java*/
String filepath3 = "cmd /c java path/to/the/compiled/class/ParserHash "C:/Users/msek/Desktop/trial/result/file1.csv C:/Users/msek/Desktop/trial/result/file2.csv C:/Users/msek/Desktop/trial/result/file3.csv";
try
{
runProcess(filepath1);
runProcess(filepath2);
System.out.println("Sucessfully written into file1.csv");
runProcess(filepath4);
System.out.println("Compilation Over");
runProcess(filepath3);
System.out.println("Program Sucessfully Executed");
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void runProcess(String processString)
{
try
{
final Process p = Runtime.getRuntime().exec(processString);
new Thread(new Runnable() {
public void run() {
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
try {
while ((line = input.readLine()) != null)
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
p.waitFor();
}
catch (Exception x)
{
x.printStackTrace();
}
}
If I compile the java file going to that particular directory and compile its compiling successfully and on running it, it executes successfully. But if I pass it like "cmd /c path/to/java/file/file.java" its getting compiled but when I execute it, I get an error stating that could not find or load mainclass eventhough class file is present.
I have looked various links on this which suggested buid process, but that didn't work.
I just want to know where I'm going wrong and how to compile, execute a java file by passing multiple arguments using Runtime.exec()..
java path/to/the/compiled/class/ParserHash
If you're having trouble with an exec() you should:
Try the command from a command line yourself. It will fail the same way in this case.
Look up the syntax of the command. In this case you will learn that the argument to the java command is not a path but a class name, fully qualified, i.e. including the package name. With dots.
I am trying to read the output of Psexec into Java using a BufferedReader on a Process InputStream for use on a network however it is only outputting the first line.
Runtime rt = Runtime.getRuntime();
try {
Process p = rt.exec("C:\\Users\\*****\\Desktop\\PS\\Psexec \\\\" + "******" + " -u ****** -p ****** cmd /c dir D:\\");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
log.add("Computer: " + address);
String s = null;
while ((s = stdInput.readLine()) != null) {
log.add(s);
}
} catch (IOException e) {
e.printStackTrace();
}
What would be the reason for this happening and how would this be fixed?
The process is probably producing some of its output on stderr. Either read both the output and the error streams, in separate threads, or use the ProcessBuilder to create the Process, and merge the output streams before you do so, with redirectErrorStream().
So, I spent some time playing around with this, using ProcessBuilder.
I tried redirecting the IO through the INHERITED and PIPE options, but could not get it to display the output of the remote command (the psexec content was fine)
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class Test1 {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder(
"C:\\Users\\shane\\Downloads\\PSTools\\PsExec.exe",
"\\\\builder",
"-u",
"xxx",
"-p",
"xxx",
"cmd",
"/c", "dir", "c:\\"
);
try {
Process p = pb.start();
StreamConsumer.consume(p.getErrorStream());
StreamConsumer.consume(p.getInputStream());
System.out.println("Exited with :" + p.waitFor());
} catch (IOException | InterruptedException exp) {
exp.printStackTrace();
}
}
public static class StreamConsumer implements Runnable {
private InputStream is;
public StreamConsumer(InputStream is) {
this.is = is;
}
public static void consume(InputStream is) {
StreamConsumer consumer = new StreamConsumer(is);
new Thread(consumer).start();
}
#Override
public void run() {
try {
int in = -1;
while ((in = is.read()) != -1) {
System.out.print((char)in);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
I even tried redirecting the InputStreams to File without any success. It would seem that whatever mechanism psexec is using to stream the results from the remote machine don't seem to be picked up by Java.
You might try PAExec which did work, but didn't seem to wait to exit after the remote command exited...
It could be the case that you started the process and didn't wait for it to finish before checking it's output. If this is the case, your main thread will exit your while loop because it reads null even though the subprocess is still executing. I would suggest using Process.waitFor() so that all of the output ends up in the stream before you begin polling it.
How can I run the compiled code (.class) java from the java code itself?
I'm doing a kind of providing service like compiling and running java code on server side and giving output to the end user.
Can anyone suggest an approach that will accomplish this?
import java.io.*;
public class demo {
public static void main(String args[]) throws IOException, InterruptedException {
int result;
try {
System.out.println("command output:");
Process proc = Runtime.getRuntime().exec("java -cp . demoh");
InputStream in = proc.getInputStream();
result = proc.waitFor();
BufferedInputStream buffer = new BufferedInputStream(proc.getInputStream());
BufferedReader commandOutput = new BufferedReader(new InputStreamReader(buffer));
System.out.print(commandOutput);
String line = null;
try {
while ((line = commandOutput.readLine()) != null) {
System.out.print(line);
System.out.println("command output: " + line);
}//end while
commandOutput.close();
} catch (IOException e) {
//log and/or handle it
}
} catch (IOException e) {
System.err.println("IOException raised: " + e.getMessage());
}
}
}
If you have the .class files somewhere on disk, simply spawn a new process and run the java command like you would from a command line:
Process p = Runtime.getRuntime().exec("java <java class file>");
After some testing around, the following code worked for me:
public static void main(String args[]) throws IOException, InterruptedException {
int result;
try {
System.out.println("command output:");
Process proc = Runtime.getRuntime().exec("java -cp . Test");
InputStream errin = proc.getErrorStream();
InputStream in = proc.getInputStream();
BufferedReader errorOutput = new BufferedReader(new InputStreamReader(errin));
BufferedReader output = new BufferedReader(new InputStreamReader(in));
String line1 = null;
String line2 = null;
try {
while ((line1 = errorOutput.readLine()) != null ||
(line2 = output.readLine()) != null) {
if(line1 != null) System.out.print(line1);
if(line2 != null) System.out.print(line2);
}//end while
errorOutput.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}//end catc
result = proc.waitFor();
} catch (IOException e) {
System.err.println("IOException raised: " + e.getMessage());
}
}
Note two things here:
The runtime errors given by the java process are sent to the error stream, not input stream, so you have to read both of them!
You have to read the stream as the process is running. Waiting for the process to finish before reading the streams causes a deadlock because the process output buffer is filled and is waiting for your parent process to read the data, while the parent is waiting for the child to finish!
Create .jar file and add that file to the build path
There are still a lot of building/compiling tools, i.e. Ant or Maven, you can check before you write your own.
Try
Process process = Runtime.getRuntime().exec("java " + filePath); // without .class
Scanner output = new Scanner(process.getInputStream());
while (output.hasNext) {
String token = output.next();
...
}
One of the options is to create an instance of the class using the class loader. The class loader can take your class as a byte array and then you can create an instance of it and run it. See this method in the JDK docs.
Here's a sample app that will compile the Java source file, load the class, instantiate an instance, and print out the toString() of the class HelloWorld. I believe you'll need tools.jar on the classpath. The sample code expects the source file in the src folder. The src folder is required on the classpath since the .class file will get generated there by default.
For more control of the Java Compiler, read up on the javax.tools package.
package sourcerunner;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class SourceRunner {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(System.in, System.out, System.err, "src/sourcerunner/HelloWorld.java");
TimeUnit.SECONDS.sleep(1L);
Class<?> cls = Class.forName("sourcerunner.HelloWorld");
Object instance = cls.newInstance();
System.out.println(instance);
}
}
And here's the HelloWorld class:
package sourcerunner;
public class HelloWorld {
#Override
public String toString() {
return "Hello Java Compiler World.";
}
}
The above code is insanely insecure. Once you understand the code, modify it to use a new ClassLoader to load and instantiate the class. Make sure the ClassLoader has minimal permissions.