Java command through CMD not working in C#.NET - java

I'm trying to run a java command in cmd using C# to get some inputs for my program, the path for Java is set correctly, and I am able to run Java commands in the cmd without any trouble but when I tried it in C#, it's showing " 'java' is not recognized as an internal or external command, operable program or batch file. " as if the path is not set.
But I am able to run the same command outside, don't know what seems to be the issue, kindly help, thanks in advance!
string cmd = #"/c java -jar """ + $"{treeEditDistanceDataFolder}libs" + $#"\RTED_v1.1.jar"" -f ""{f1}"" ""{f2}"" -c 1 1 1 -s heavy --switch -m";
Console.WriteLine(cmd);
var proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = cmd;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.Start();
Console.WriteLine("Process started");
string output = proc.StandardOutput.ReadToEnd();
Console.WriteLine("Output was read");
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();

This line is your problem:
proc.StartInfo.UseShellExecute = false;
When UseShellExecute is true, the system and user PATH variables will be used if the application to launch is just the executable name. Because you're setting it to false, and java doesn't exist in your application's folder, it isn't possible for .NET to find it.
You have two options:
Set UseShellExecute to true so that it can use the PATH variable to find java.
Use a fully qualified path, e.g. "C:\Program Files\Java\jdk1.8.0_101\bin\java"
See this answer for more info.

Related

Is there a way to have Java call a bash script which calls javac and java?

I'm trying to train a neural network to play Halite 3. The provided interface is a bash script which:
1. compiles my bot
2. calls the binary file with a string to run the bot java myBot
I'm trying to run this script from Java to train the network.
I've tried using a ProcessBuilder to run the script as well as the binary in the script. Running the script produces no output, and using echo I've determined that the program terminates when javac is called in the script. Removing that call, it terminates when the program is run.
I've tried calling the program directly as well using ProcessBuilder, and this does indeed produce output. The issue is it doesn't run the bots properly saying it can't find the file. I've tried changing the path to be relative to different directory levels as well as the absolute path (the java command doesn't seem to like absolute paths?).
Calling the binary directly:
List<String> cmd = new ArrayList<>();
cmd.add(dir+ "/src/halite");
// Replay
cmd.add("--replay-directory");
cmd.add(dir+"/replays/");
// Options
cmd.add("--results-as-json");
cmd.add("--no-logs");
// Dimensions
cmd.add("--width");
cmd.add("16");
cmd.add("--height");
cmd.add("16");
// Players
cmd.add("\"java -cp . myBot\"");
cmd.add("\"java -cp . myBot\"");
Process proc = new ProcessBuilder(cmd).start();
InputStream is = proc.getInputStream();
Scanner s = new Scanner(is);
while (s.hasNext()){
System.out.println((String) s.next());
}
This code does produce a JSON, however, I get an error in my logs saying that the bots do not run.

hide command prompt while setting java home Python

Currently I am working on PartOfSpeech(POS) tagging in Python using Stanford POStagger. I have set the java home
java_path = "Path to java bin"
os.environ['JAVAHOME'] = java_path
Below is my code
def getPOSandSentiment(sentence):
path_to_model = 'Path/to/Tagger/wsj-0-18-left3words-distsim.tagger'
path_to_jar = "path/to/stanford-postagger.jar"
tagger=StanfordPOSTagger(path_to_model, path_to_jar)
tagger.java_options='-mx2048m'
posWords = tagger.tag(sentence.split())
for words,pos in posWords:
print('Word : ',words)
print('POS :', pos)
Everytime I pass a sentence, The java.exe command prompt gets popped up. Is there any way to hide that command prompt? I am using Anaconda3 and spyder IDE for python. Is there any way to set Java_Home in Spyder or Anaconda?
Thanks

Execute a shell script in runtime of Java code from Eclipse

I have a shell script that I want to execute in Eclipse from a Java code.
I am able to use external tools in order to run the script, but I want the script to run during the execution of the Java code i.e. the Java code should make a call to the script.
Earlier I was using the "Process Builder" to do so but it seems Eclipse does not support that method as it says "File not found" when I have given it all the permissions.
Any idea how to run the script from a Java code in Eclipse?
Here is the code:
String line1 = null;
String target = new String("/home/aditya_s/workspace/rs-test/src/iperf_parse.sh " + host + " " + "9000");
while(line1 == null)
{
Process p1 = Runtime.getRuntime().exec(target);
BufferedReader input1 = new BufferedReader(new InputStreamReader(p1.getInputStream()));
System.out.println("Ran");
line1 = input1.readLine();
p1.destroy();
}
BW = Double.parseDouble(line1);
TIP: Right click on the shell script and go to Properties. There give the 'Read/Write/Execute' permissions to 'Owner'. By default, the 'Execute' permission is not there. So you might get an error like 'Could not execute script.sh'.
Eclipse runs your java program just as it normally would, so ProcessBuilder will work as well. It is possible that you passed in the wrong path. If the path is relative, it will be relative to System.getProperty("user.dir").
You should be able to use the below, replace shellscript with the script you want to run.
String s = "shellscript";
Process proc = Runtime.getRuntime().exec(s);
You should look at ProcessBuilder

Java-Application: Execute Batch File with subprocess / UNC Path

I want to execute a batch file within my java application.
I want to execute it this way:
String[] args = new String[] {
"C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/connect.bat",
"start",
"-f",
"C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/etc/db.xml" };
Process p = Runtime.getRuntime().exec(args);
p.waitFor();
BufferedReader prout = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String buffer;
while ((buffer = prout.readLine()) != null) {
System.out.println(buffer);
buffer = prout.readLine();
}
For explaination:
Let us consider I would use a normal cmd execution. I would open cmd, then i would go to my directory:
cd C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin
Afterwars I would start the batch file with the following command:
connect start -f C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/etc/db.xml
On the command line this works fine, it starts the batch and inside this batch there is a subprocess wich gets started:
if exist %JAVA_HOME%\bin\java.exe (
java -XX:NewSize=%NEWSIZE% -XX:NewRatio=1 -Xms%MAXHEAP% -Xmx%MAXHEAP% -Dfile.encoding=%ENCODING% -Djava.ext.dirs=%EXT_DIR% com.fastsearch.esp.connectors.jdbc.JDBCConnector %1 %2 %3 %4 %5 %6 %7
) else (echo Is JAVA_HOME=%JAVA_HOME% set correctly?)
But with my execution inside my Java application I have the following problem:
It only prints the first echo of my batch file but the subprocess does not start. When I catch the errorstream (like shown in the code on top) it says:
UNC-Pfade werden nicht unterstützt. (UNC-Paths are not supported)
java.lang.NoClassDefFoundError: com/fastsearch/esp/connectors/jdbc/JDBCConnector
After some reseach I found out that the cmd has problems to start subprocesses because of the current working directory or something like that. I did not really understand that.
The actual thing is, that I want to execute the batch file with its neccesary parameters (start, -f and the path) within my Java application. When I execute the statements directly on the cmd everything works fine but inside my java application it sucks.
Here is the full batch file, maybe this is helpful:
#echo off
rem This bat file should setup the java env and run the connector manager
SETLOCAL
echo Copyright (c) Microsoft Corporation. All rights reserved.
rem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
rem Java 1.6 must be installed and set here
rem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if NOT defined JAVA_HOME (
echo Sorry..
echo You have NOT set JAVA_HOME - Should point to where JRE 1.6.x or later is installed
echo Exiting.......
goto end
)
set JAVA_HOME=%JAVA_HOME%
:: Remove quotes if exist, then add quotes in case spaces
SET JAVA_HOME=###%JAVA_HOME%###
SET JAVA_HOME=%JAVA_HOME:"###=%
SET JAVA_HOME=%JAVA_HOME:###"=%
SET JAVA_HOME=%JAVA_HOME:###=%
SET JAVA_HOME="%JAVA_HOME%"
SET PATH=%JAVA_HOME%\bin
SET EXT_DIR=..\lib;%JAVA_HOME%\lib;%JAVA_HOME%\lib\ext
SET CLASSPATH=..\etc
SET MAXHEAP=1408m
SET NEWSIZE=256m
SET ENCODING=UTF8
if exist %JAVA_HOME%\bin\java.exe (
java -XX:NewSize=%NEWSIZE% -XX:NewRatio=1 -Xms%MAXHEAP% -Xmx%MAXHEAP% -Dfile.encoding=%ENCODING% -Djava.ext.dirs=%EXT_DIR% com.fastsearch.esp.connectors.jdbc.JDBCConnector %1 %2 %3 %4 %5 %6 %7
) else (echo Is JAVA_HOME=%JAVA_HOME% set correctly?)
:end
As you touched on, it is highly likely that your problem is that you are not executing the batch file from the proper directory. When you open the command line console and cd into the directory containing the batch file, THAT action sets the proper current working directory (CWD).
You can resolve it by changing the CWD before, or after, you enter your batch file.
Let's start by working with the CWD in the batch file; we've got a number of options here also, but let's keep it simple and just change the CWD:
set MYDIR=%~dp0
cd %MYDIR%
The first line uses a bit of batch-file magic to obtain the directory in which the currently executing batch file lives. That would be "C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/"
Alternative
You could use an alternate form of the Runtime.getRuntime().exec() to change the CWD:
Runtime.getRuntime().exec(String[] cmdarray, String[] envp, File dir)
Invoke as:
File workingDir = new File("C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/");
Runtime.getRuntime().exec(args, null, workingDir);
I'd strongly suggest you declare a static final const value for your working dir, or find some way to eliminate the hard-coding of that value in your program.
I would like to write down the correct answer now as a summary. But I have to mention that this is the idea of Richard Sitze and not mine.
static final String workingdirectory = "C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin";
String[] args = new String[] {"C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/connect.bat",
"start",
"-f",
"C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/etc/db.xml" };
Process p = Runtime.getRuntime().exec(args2, null, workingDir);
BufferedReader prout = new BufferedReader(new InputStreamReader(p.getInputStream()));
String buffer;
while ((buffer = prout.readLine()) != null) {
System.out.println(buffer);
buffer = prout.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}

Java executing Linux commands

I want to write a java code that executes some Linux command:
String cmd = "cd /home/arps/FBI" ;
Process p=Runtime.getRuntime().exec(cmd);
String [] arr = new String [9] ;
arr[0] = "cd /home/arps/FBI" ;
for(int n = 1 ; n < 9 ; n++){
String command = "mv" + " " + "/home/arps/FBI/hr" + n + ".txt" + " " + "/home/arps/FBI/hrs" + n +".txt" ;
arr[n] = command ;
}
Process pp=Runtime.getRuntime().exec(arr);
In above code: I try to rename 8 files named hr1, hr2 .... to hrs1 , hrs2 ... etc. In cd command I try to enter the required directory. However, I have used absolute path also. But the code is giving error:
java.io.IOException: Cannot run program "cd": java.io.IOException: error=2, No such file or directory
java.io.IOException: Cannot run program "mv /home/arps/FBI/hr1.txt /home/arps/FBI/hrs1.txt": java.io.IOException: error=2, No such file or directory
Can anybody help me why is this happening though I manually execute those command means "mv /home/arps/FBI/hr1.txt /home/arps/FBI/hrs1.txt" and executes properly?
cd is a built-in command to the current shell - you can't execute it - it's a shell built-in, as the cwd is a process-level setting, so a new process has it's own value. There is no way to change the cwd from within the java process.
The array argument version of exec is for executing a single command, where you have split the arguments yourself, not for executing multiple commands.
So you either need to give full paths, or implement the copy yourself in Java.
Change the final line of your program from
Process pp=Runtime.getRuntime().exec(arr);
to:
for (String cmdLine: arr) {
Process pp=Runtime.getRuntime().exec(cmdLine);
and you will execute each line separately, according to RunTime documentation.
You might be better off writing a shell script that does what you need and invoking that from Java.
arr array must store the arguments of command. Not seperated commands. refer to my question.
run shell command from java
If ls -l /home/arps/FBI/hrs1.txt outputs nothing as you said in the comments, then the file you're trying to rename simply does not exist, so the exception is right about this.
PS: IMHO this is not to be done in Java. Use scripting languages for such things. Way easier and way smaller code. For each problem, try to use the right tool, not one tool for all problems.

Categories