Bat file working from terminal not working from Java - java

I found my command line tool gets stuck in between and needs a enter to process and I found that it’s because of "QUICKEDIT" mode in cmd and we want to disable it to avoid that. So I searched for Java options to disable quick edit mode on my app launch but I got only bat file from here quickedit.bat.
And this bat file works perfect when I run from my command prompt it disable quick edit mode in the current session itself which is the same I want. So I kept that bat file in my folder via installer and run it first on every launch but it’s not turning off the quick edit mode for current session.
I have tried using both process builder and runtime.exec.
Below is my code
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "quickedit.bat");
File dir = new File(System.getProperty("user.home")+File.separator+"AppData"+File.separator+"Local"+File.separator);
pb.directory(dir);
Process p=null;
try {
p = pb.start();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
try {
while ((line = in.readLine()) != null) {
System.out.println(line); // ----Here i get the same output i get when i run the bat file
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BufferedReader inerr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
try {
while ((line = inerr.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
It gives me this:
When I run my bat file directly like this:
But through Java it didn't disable quick edit in my current command prompt whereas it disables at once I run the actual bat file. So can anyone say the reason or how to fix it or any other way to disable it for ever from Java?

Try pb.inheritIO(); before you call its start method. What you seem to have is a hybrid batch/Powershell script that that relies on stderr to determine which of the two it executes so this should require correct processing of stderr.

I didn't look at your bat file the most common issue on this kind of think is that process run from java did'nt share the environnement variable of your local setup nor jvm a quick fix to verify that is :
pb.environment().putAll(System.getenv());
hoping this will work :) then you just have to found which specific environnment variable is missing :)

Related

How could I pass in commands into a terminal that is already running in java (linux)

I have been researching how to run a terminal command in java. I am doing this to make a program I can use to ssh into another pc (just as a project). How could I keep continuing putting commands in this terminal? If I run this I get a message to put in my password and if I do so it will print out what the messages the terminal spits out at the :
while((line = in.readLine()) != null){
System.out.println(line + "\n");
}
line, but a few seconds after that my program will stop working.
I currently have a GUI that is just a button and if I press the button it will run this code. Could someone help me to fix the issue of it stopping and give me information on how I could continue to put commands into the terminal? Thanks.
Process p = null;
String[] command = {"/bin/sh", "-c", "ssh 192.168.2.100"};
ProcessBuilder pb = new ProcessBuilder(command);
String line = null;
try {
term = pb.start();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
InputStream is = p.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
try {
while((line = in.readLine()) != null){
System.out.println(line + "\n");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You can not pass the argument to live JVM, But there is way in which you can modify the some of the parameters which done using JMX, with this you can connect to live JVM and send the parameters. which will be taken the effect immediately.
Hope that helps

.jar doesn't run external program

So i have a java project made in eclipse with sphinx voice recognition. If i say a certain word then it runs a .bat file.
if (resultText.equals("word")) {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("C:/c.bat");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In Eclipse it works fine, but after i export the .jar and run it, if i say that specific word, it doesn`t run that .bat. So any ideas why this only runs my .bat file from eclipse and not from command line? Thanks
I am not sure about this but atleast try this solution once.
Try giving the .bat file path as C:\\c.bat and then try again.
Try adding something like:
File f = new File("c:/c.bat");
if(f.exists()) {
// execute the file
Process process = runtime.exec(f.getAbsolutePath());
process.waitFor();
InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();
// check the streams for errors
} else {
// log error
}
hth

running linux copy and rename command with java

File wd = new File("/bin");
Process proc = null;
try {
proc = Runtime.getRuntime().exec("/bin/bash", null, wd);
} catch (IOException e) {
logger.info(e);
e.printStackTrace();
}
if (proc != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
//out.println("su - root");
out.println("cp /usr/rock/Masterfile.xls /usr/rock/generatedfile/");
out.println("mv /usr/rock/generatedfile/Masterfile.xls /usr/rock/generatedfile/userid.xls");
try {
String line;
while ((line = in.readLine()) != null) {
logger.info(line);
}
proc.waitFor();
in.close();
out.close();
proc.destroy();
} catch (Exception e) {
logger.info(e);
e.printStackTrace();
}
}
I am trying to copy master file and want to rename according to the userid. Code does not showing any error but i dont see any file in the folder i specify. I tried with sudo root command even its not copying and renaming the file. How should i do in order to run copy and rename command to run successfully from java program.
You're not reading from the process's standard error. So if your cp and mv commands are reporting errors, you won't be seeing them.
It's possible to read from the process's standard error, but that's complicated if you're using Runtime.getRuntime().exec() because reading from standard error needs to be done in a separate thread to reading from standard output.
Java 5 introduced a new class for running external processes: ProcessBuilder. In my opinion, the single biggest advantage of a ProcessBuilder is that you can redirect the standard error of the process into its standard output. That leaves you with only one stream to read from, and hence no need for a separate thread.
I would recommend replacing your use of Runtime.getRuntime().exec(...) with the following:
ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.directory(wd);
builder.redirectErrorStream(true);
proc = builder.start();
If the files aren't being copied, then chances are that cp and mv are reporting errors. Making this change should hopefully allow you to see the errors being reported.

Java Runtime.exec() program won't output to file

I have a program that takes in a file as an input and produces an xml file as an output. When I call this from the command line it works perfectly. I try calling it from a Java program with the following code.
try
{
Process proc = Runtime.getRuntime().exec(c);
try
{
proc.waitFor();
}
catch(InterruptedException e)
{
System.out.println("Command failed");
}
}
catch(IOException e)
{
System.out.println("Command failed");
e.printStackTrace();
}
The program seems to be running fine, as it creates an xml file; however, the xml file is empty when I open it. I'm not encountering any exceptions in my Java program, so I'm baffled as to what the problem could be. Why would the command line program work fine normally, but then when called from Java not output anything to the file it created. I was thinking maybe it was some sort of permissions thing. I tried running the program as sudo (I'm using Linux) but to no avail. This problem doesn't seem to be anything I could find an answer to online. Hopefully somebody on here might be able to tell what's going on. :)
Get the output and error streams from your process and read them to see what is happening. That should tell you what's wrong with your command.
For example:
try {
final Process proc = Runtime.getRuntime().exec("dir");
try {
proc.waitFor();
} catch (final InterruptedException e) {
e.printStackTrace();
}
final BufferedReader outputReader = new BufferedReader(new InputStreamReader(proc
.getInputStream()));
final BufferedReader errorReader = new BufferedReader(new InputStreamReader(proc
.getErrorStream()));
String line;
while ((line = outputReader.readLine()) != null) {
System.out.println(line);
}
while ((line = errorReader.readLine()) != null) {
System.err.println(line);
}
} catch (final IOException e) {
e.printStackTrace();
}
If there is no output in either stream, then I would next examine the external program and the command being sent to execute it.
Did you try launching the process from outside java?
For me, I wrote a jar file that output a file and ran that from the command line in another java program. It turns out that there was a fundamental check in my jar file that I had forgotten about on the number of characters in an input string (my bad). If the count of the characters was smaller than 8 there was no output file. If the number of characters was greater than 8, the output file came out without any trouble using the following code:
String cmdStr = "java -jar somejar.jar /home/username/outputdir 000000001";
try
{
Runtime.getRuntime().exec(cmdStr);
Runtime.getRuntime().runFinalization();
Runtime.getRuntime().freeMemory();
log.info("Done");
}
catch (IOException e)
{
log.error(System.err);
}
Not sure if I really need everything here but, hey, it works. Note: no waitFor seems to be necessary in my case.
process input (actually output of the process!) and error streams has to be handled before waiting for the process termination.
This should work better
try
{
Process proc = Runtime.getRuntime().exec("anycomand");
BufferedReader outSt = new BufferedReader(new InputStreamReader(proc.getInputStream()));
BufferedReader errSt = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
String line;
while ((line = outSt.readLine()) != null)
{
System.out.println(line);
}
while ((line = errSt.readLine()) != null)
{
System.err.println(line);
}
proc.waitFor();
}
catch (final IOException e)
{
e.printStackTrace();
}
but to understand better how Runtime exec works it is worth reading
the classic article
When Runtime.exec() won't
which provide useful sample code (better than the one above!)

run interactive command with apache commons exec

I want to run an interactive command with apache commons exec. Everything works except that when my command is executed and waits for user input I don't see my input in the console until I press enter which makes it effectively unusable.
This is an example of an interactive program:
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while (true) {
System.out.print("=> ");
try {
line = in.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(line);
}
}
Now I want to execute that with apache commons exec like this:
public static void main(String[] args) {
Executor ex = new DefaultExecutor();
ex.setStreamHandler(new PumpStreamHandler(System.out, System.err, System.in));
CommandLine cl = new CommandLine("java");
cl.addArguments("-cp target\\classes foo.bar.Main");
try {
ex.execute(cl);
} catch (ExecuteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
As I said, it basically works, I get the "=>" prompt but when I type something I don't see it until I hit enter. I'm doing this on windows 7 with a cmd prompt.
I'd appreciate any hint on how to achieve the desired behaviour.
Edit: It works as expected on linux. I guess this is an issue with the windows cmd prompt. I'd still like to make this work if at all possible, so I would appreciate any insight into this behaviour on windows.
Edit2: I also tested with msys shell and powershell, both exhibit the same problem.
Edit3: I worked around the issue by launching a seperate cmd prompt. This works, but I still like to understand why.
CommandLine cl = new CommandLine("cmd");
cl.addArguments("/C java -cp target\\classes foo.bar.Main");
thanks
Raoul
I'm not sure exactly what you were expecting to happen here; if the spawned process is designed to wait to read from its input, then it shouldn't be surprising when it does exactly that?
If that's the issue, and your question is "How can I make my program automatically send a newline character to the spawned process' input?", then you'll need to define an OutputStream to write the input to, and get hold of the ExecuteStreamHandler to attach it to the process. Something like the following:
Executor ex = new DefaultExecutor();
// Create an output stream and set it as the process' input
OutputStream out = new ByteArrayOutputStream();
ex.getStreamHandler().setProcessInputStream(out);
...
try
{
ex.execute(cl);
out.write("\n".getBytes()); // TODO use appropriate charset explicitly
...
Using Apache exec org.apache.commons.exec.DefaultExecuteResultHandler you can launch a non-blocking command. And then you can follow the steps #Andrzej mentioned.

Categories

Resources