return string from shell to java file - java

I have written code in below way.
Java program 1(call shell program) => Shell program => Java program 2 (Will perform encryption).
Hence when I run the Java program 1, it should call shell and followed by java program 2. The java program 2 will return the encrypted value to me and same need to be passed to Java program 1.
When execute shell directly from command prompt, I am getting message like below.
[Serverapp01 AESEncryption]$ sh AESEncrypt.sh /keys/keyfile_05.txt texttoencrypt
AESEncrypt.sh: line 28: exit: 0UhSI9LTa/7efiT0quKUsg==: numeric argument required
My aim is to get the value 0UhSI9LTa/7efiT0quKUsg== to my java program 1. But i am not getting this value from shell to java program 1.
Any help is much appreciated.
Java Program 1
package com.abc.encrypt;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class AESEncrypt1 {
public static String callScript(String encryptionScriptPath,String KeyLocation,String textToEncrypt)
{
int value = 0;
String enc ="Error";
try
{
ProcessBuilder pb = new ProcessBuilder(encryptionScriptPath,KeyLocation,textToEncrypt);
Process p = pb.start();
value = p.waitFor();
BufferedReader br=new BufferedReader(
new InputStreamReader(
p.getInputStream()));
String line;
String temp ="";
while((line=br.readLine())!=null){
System.out.println(line);
temp = temp + line;
}
enc=temp;
}
catch (Exception e)
{
//value = 2;
enc = "ErrorOccured.."+e.toString();
}
return enc;
}
}
Shell look like below
unset CLASSPATH
KeyLocation=$1
TextToEncrypt=$2
isolatedjreLocation=/AESEncryption/isolatedjre17
JarLocation=/AESEncryption
CLASSPATH="/AESEncryption/isolatedjre17/jre17/bin"
export CLASSPATH
#echo $CLASSPATH
encryptedValue='ErrorInJava'
#echo 'Call Java Program'
encryptedValue=$($isolatedjreLocation/jre17/bin/java -cp $JarLocation/AESCryptoJava_v1.0.0.jar com.abc.AESEncryption $KeyLocation $TextToEncrypt)
#echo $encryptedValue
exit $encryptedValue

Related

getting error from java

How can I call a shell script through java code?
I have writtent the below code.
I am getting the process exit code as 127.
But it seems my shell script in unix machine is never called.
String scriptName = "/xyz/downloads/Report/Mail.sh";
String[] commands = {scriptName,emailid,subject,body};
Runtime rt = Runtime.getRuntime();
Process process = null;
try{
process = rt.exec(commands);
process.waitFor();
int x = process.exitValue();
System.out.println("exitCode "+x);
}catch(Exception e){
e.printStackTrace();
}
From this post here 127 Return code from $?
You get the error code if a command is not found within the PATH or the script has no +x mode.
You can have the code below to print out the exact output
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
String s= null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
BufferedReader stdOut = new BufferedReader(new InputStreamReader(process. getErrorStream()));
String s= null;
while ((s = stdOut.readLine()) != null) {
System.out.println(s);
}
If you are getting an exit code, then your script is executed. There is a command that you are running inside of "Mail.sh", which is not succeccfully executed and returning a status code of 127.
There could be some paths that are explicitly set in your shell, but is not available to the script, when executed outside of the shell.
Try this...
Check if you are able to run /xyz/downloads/Report/Mail.sh in a shell terminal. Fix the errors if you have any.
If there are no errors when you run this in a terminal, then try running the command using a shell in your java program.
String[] commands = {"/bin/sh", "-c", scriptName,emailid,subject,body};
(Check #John Muiruri's answer to get the complete output of your command. You can see where exactly your script is failing, if you add those lines of code)

Execute external Java code and get output

I want to execute a Java CLI-program from within another Java program and get the output of the CLI-program. I've tried two different implementations (using runtime.exec() and ProcessBuilder) and they don't quite work.
Here's the peculiar part; the implementations work (catch the output) for when executing commands such as pwd but for some reason they do not catch the output of a Hello World java program executed with java Hello.
Execution code:
public static void executeCommand(String command)
{
System.out.println("Command: \"" + command + "\"");
Runtime runtime = Runtime.getRuntime();
try
{
Process process = runtime.exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
// read the output from the command
System.out.println("Standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e)
{
e.printStackTrace();
}
}
Example output
Command: "cd /Users/axelkennedal/Desktop && java Hello"
Standard output of the command:
Standard error of the command (if any):
Command: "pwd"
Standard output of the command:
/Users/axelkennedal/Dropbox/Programmering/Java/JavaFX/Kode
Standard error of the command (if any):
I have verified that Hello does indeed print "Hello world" to the CLI when running Hello directly from the CLI instead of via executeCommand().
Hello world
public class Hello
{
public static void main(String[] args)
{
System.out.println("Hello world!");
}
}
This "cd /Users/axelkennedal/Desktop && java Hello" is not one command but two commands separated by the &&. In general it means do the first command and if the first command succeeds do the second command. You can't pass this as a single command but you can implement the logic yourself:
eg to execute "cmd1 && cmd2"
if (Runtime.getRuntime().exec("cmd1").waitFor() == 0) {
Runtime.getRuntime().exec("cmd2").waitFor();
}
However, because in this case cmd1 is to change directories there is a better way, which is to use the directory function of ProcessBuilder instead of the first command.
Process p = new ProcessBuilder("java","hello")
.directory(new File("/Users/axelkennedal/Desktop"))
.start();

How to access unix shell special variables using java

How to access the unix shell special variables using java.
Few examples of unix shell special variables:
echo $$ which prints the process ID (PID) of the current shell.
echo $0 which prints the name of the command currently being executed.
echo $? which prints the exit status of the last command executed as a decimal string.
When these shell variables are included in a script file and passed the script file in ProcessBuilder argument, I'm able to execute it successfully using java. But when these variables are passed as arguments, these are not treated as variables itself. Why? How to access these special shell variables?
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class ExecSpecVars {
public static void main(String a[]){
InputStream is = null;
ByteArrayOutputStream baos = null;
List<String> list = new ArrayList<String>();
// String command ="/home/csk/sptest.sh";
String command ="echo $$"; //This should print the PID instead of the string "$$".
String cmd[] = command.split(" ");
for (int i = 0; i < cmd.length; i++) {
list.add(cmd[i]);
}
ProcessBuilder pb = new ProcessBuilder(list);
try {
Process prs = pb.start();
is = prs.getInputStream();
byte[] b = new byte[1024];
int size = 0;
baos = new ByteArrayOutputStream();
while((size = is.read(b)) != -1){
baos.write(b, 0, size);
}
System.out.println(new String(baos.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(is != null) is.close();
if(baos != null) baos.close();
} catch (Exception ex){}
}
}
}
sptest.sh file contains the below commands:
echo $$
echo $?
echo $0
Run this java class to test the shell special variables in the script file:
uncomment the below line:
String command ="/home/csk/sptest.sh";
Comment the below line:
String command ="echo $$";
This is because the echo command is not resolving the $$ but bash is.
As Java does not run the command in the bash shell, this does not work.
If you run the command in bash then it will work, but it won't return what you might expect; it will return information about bash rather than the Java process:
/bin/bash -c 'echo $$' -> pid of bash process
/bin/bash -c 'echo $?' -> bash exit code
/bin/bash -c 'echo $0' -> /bin/bash
This is because you are now running another command ('/bin/bash') and the information given is about that command rather than your JVM.
In short, there is no easy way to do the things you want in Java.
Here's a quick test case to prove this (code significantly tidied and using Guava):
public static void main(final String[] args) throws Exception {
System.out.println(ManagementFactory.getRuntimeMXBean().getName());
runCommand("/bin/bash", "-c", "echo $$");
runCommand("/bin/bash", "-c", "echo $?");
runCommand("/bin/bash", "-c", "echo $0");
}
private static void runCommand(String... command) throws IOException {
ProcessBuilder pb = new ProcessBuilder(command);
Process prs = pb.start();
try (InputStream is = prs.getInputStream()) {
byte[] b = ByteStreams.toByteArray(is);
System.out.println(new String(b, StandardCharsets.UTF_8));
}
}
Output:
4466#krypto.local
4467
0
/bin/bash
So you can see that the pid is one higher than the JVM pid. And the program name is '/bin/bash'.

Cannot launch shell script with arguments using Java ProcessBuilder

I am trying to execute a shell script with command line arguments using ProcessBuilder, this shell script inturn calls two other shell scripts that uses this argument. The first shell script runs fine, but when the second one is started it returns exit code 1.
ProcessBuilder snippet from Java Program:
//scenario - A string that holds a numerical value like 1 or 2 etc
String[] command2 = {"/bin/bash", "<path to shell script>/runTemporaryTestSuite.sh", scenario};
ProcessBuilder pb2 = new ProcessBuilder(command2);
Process p2 = pb2.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p2.getInputStream()));
String line;
//print - is an object ref of response.getWriter() //
print.println("Output of running "+Arrays.toString(command2)+" is: ");
while ((line = br.readLine()) != null) {
print.println(line);
}
try {
int exitValue = p2.waitFor();
print.println("<br><br>Exit Value of p2 is " + exitValue);
} catch (InterruptedException e) {
e.printStackTrace();
}
runTemporaryTestSuite.sh
#!/bin/bash
sh <path to script>/clearRegressionResult.sh (This runs fine)
sh <path to script>/startRegression.sh $1 (This is where the issue occurs)
startRegression.sh looks like:
SUITE_PATH="./"
java -DconfigPath=${SUITE_PATH}/config.xml -Dscenario=$1 -Dauto=true -jar test.jar
My output:
Output of running [/bin/bash, /runTemporaryTestSuite.sh, 29] is:
Exit Value of p2 is 1
Any help in resolving this is really appreciated.
In think the problem is not that you cannot launch shell script with arguments, I was curious and I did a test
public class Main {
public static void main(String[] args) throws IOException {
String[] command = {"/bin/bash", "test.sh", "Argument1"};
ProcessBuilder p = new ProcessBuilder(command);
Process p2 = p.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p2.getInputStream()));
String line;
System.out.println("Output of running " + command + " is: ");
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
here is the test.sh script
echo Hello im the script, here your args $#
Here the output
Output of running [Ljava.lang.String;#604e9f7f is:
Hello im the script, here your args Argument1
What I think is just that your startRegression.sh exit with a non-0 status (aka it failed somewhere) and it have repercussion, runTemporaryTestSuite.sh will also exit with a non-zero status, and so on hence the message : Exit Value of p2 is 1
What I see right now,
SUITE_PATH="./"
java -DconfigPath=${SUITE_PATH}/config.xml [..] the configPath will be .//config.xml so maybe you have a plain file not found issue? I might be wrong, hope it helped

Unable to run Shell Script

Hi i am trying to run shell script from following code
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ScriptTest {
public static void main(String[] args){
BufferedReader stdErr=null;
BufferedReader stdIn=null;
try{
System.out.println("In Script");
String[] commands= {"ls"};
Process process = Runtime.getRuntime().exec("/mobilityapps/testScript/testScript.sh");
stdIn= new BufferedReader(new InputStreamReader(process.getInputStream()));
stdErr = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String inline= stdIn.readLine();
String errline =stdErr.readLine();
System.out.println("*Inline*"+inline);
System.out.println("*Errline*"+errline);
while(inline!=null){
System.out.println(inline);
inline=stdIn.readLine();
}
while(errline!=null){
System.out.println(errline);
errline=stdErr.readLine();
}
System.out.println("Process Exit Value: "+process.waitFor());
}catch(Exception excp){
excp.printStackTrace();
}
}
}
The script i am trying to call is
CURRDATE=`date '+%d%b%Y'`
TIMESTAMP=`date '+%H:%M'`
BASE_PATH=/mobilityapps/testScript
LOGFILE=${BASE_PATH}/logs_${CURRDATE}_${TIMESTAMP}.log
echo ${CURRDATE} ${TIMESTAMP}>>${LOGFILE}
All both the script and Java program are in the same directory.
When i run testScript.sh from PUTTY it runs fine
But when i run from Java program Process Exit Value is 255
Can anyone suggest the changes?
Try replacing the path
Runtime.getRuntime().exec("/mobilityapps/testScript/testScript.sh");
with
Runtime.getRuntime().exec("./mobilityapps/testScript/testScript.sh");
If you just use / at the begining, it means that it's a absolute path.
Using '.' indicates that is a relative path.

Categories