My requirement is to load a script using sql loader from within my java app. For this purpose, I've been using the following script
D:\oracle\product\10.2.0\db_1\BIN\SQLLDR.EXE userid=myDBUserID/myDBPswrd data=C:\Users\myUserName\Desktop\sql_ldr_files\1\table_export_DATA.ldr control=C:\Users\myUserName\Desktop\sql_ldr_files\1\table_export_DATA.ctl log=C:\Users\myUserName\Desktop\sql_ldr_files\1\logitit.log discard=C:\Users\myUserName\Desktop\sql_ldr_files\1\discard.txt bad=C:\Users\myUserName\Desktop\sql_ldr_files\1\bad.txt
But while trying to run it first on cmd prompt, i realized that the command won't run if I do not run it, on cmd prompt which is launched by "Run as Administrator".
Once the cmd was launched by "Run as Administrator", the command ran successfully, the script executed and the table got populated properly.
Now my task was to use the same code, but run it from within a java code. For this, I've used the following java code,
import java.io.FileWriter.*;
import java.io.BufferedWriter.*;
import java.io.BufferedReader.*;
import java.io.InputStreamReader.*;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class RunSqlLrdFromJava
{
public static void main(String s[])
{
try{
Runtime rt = Runtime.getRuntime();
String sqlLoaderPath = "D:\\oracle\\product\\10.2.0\\db_1\\BIN\\";
String runAsCmd="runas /user:myPCName\\administrator ";
String cmd = runAsCmd + "\""+sqlLoaderPath + "SQLLDR.EXE userid=myDBUserID/myDBPswrd "
+ " data=C:\\Users\\myUserName\\Desktop\\sql_ldr_files\\1\\table_export_DATA.ldr"
+ " control=C:\\Users\\myUserName\\Desktop\\sql_ldr_files\\1\\table_export_DATA.ctl"
+ " log=C:\\Users\\myUserName\\Desktop\\sql_ldr_files\\1\\logitit.log"
+ " discard=C:\\Users\\myUserName\\Desktop\\sql_ldr_files\\1\\discard.txt"
+ " bad=C:\\Users\\myUserName\\Desktop\\sql_ldr_files\\1\\bad.txt " + "\"";
try{
FileWriter file = new FileWriter("ExceptionInSqlldr.txt");
BufferedWriter bf = new BufferedWriter(file);
bf.write("SQLLDR COMMAND:\n" +cmd +"---------------------------------\n\n\n");
Process proc = rt.exec(cmd);
int exitVal = proc.waitFor();
BufferedReader br = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
String line;
System.out.println("\n------------------exitVal:"+exitVal+"------------------\n\n");
bf.write("SQLLDR COMMAND:\n" +cmd +"---------------------------------\n\n\n");
if(br!=null && exitVal!=0)
{ while((line = br.readLine()) != null)
{
bf.write("\n"+ line +"\n");
System.out.println("Read from error stream: \"" + line + "\"");
}
}
proc.destroy();
bf.close();
}
catch(Exception e)
{
e.printStackTrace();
//System.out.println(e.getMessage());
}
}
catch(Exception e)
{
e.printStackTrace();
//System.out.println(e.getMessage());
}
}
}
But this time, it won't run.
My problem is, when we use "run as" to run the process as administrator on command prompt, it prompts for a password. Thus when I'm using the same "run as" command from within a java code, I can't provide the response to that prompt [as it seems at the least].
Is there a wayout, where I can run the command as an administrator from within my java code by passing the password for administrator inside the command only, so that my java code becomes successfull in running it?
Please advice as I didn't ever do it before.
Warm regards.
Related
I dont know why, but I can only execute a very small pallet of commands on my Raspberry 3B from code (I cane even execute echo). For some reason, 99% of the commands that you would normally be able to do in the terminal itself, you cant do from code.
Example: I execute this java code:
Runtime.getRuntime().exec("echo hi");
And I get this:
`java.io.IOException: Cannot run program "echo hi": error=2, No such file or directory
Is there a PATH configuration that I dont have access to in java code? why cant I execute any commands to the raspberry pi from code?
I've written some example that uses the exec() call. There are other methods to start processes from within Java (ProcessBuilder is the keyword here), but this example is relatively easy to understand:
import java.util.*;
import java.io.*;
import java.text.*;
public class X {
public static void main(String argv[])
{
String args[] = { "/bin/bash", "-c", "uptime" };
try {
Process p = Runtime.getRuntime().exec(args);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = in.readLine();
while (line != null) {
System.out.println("Found: " + line);
line = in.readLine();
}
} catch (Exception e) {
System.err.println("Some error occured : " + e.toString());
}
}
}
Basically the program executes the command line /bin/bash -c uptime; just an uptime would have done the same, but I wanted to show how to work with command line arguments for the program to start.
I am trying to call Fortran 90 program from java program,
My Fortran program is as follows:
!sum.for
program Numbers_sum
implicit none
! -----------------------------------------------Declare
REAL :: a,b,sum
! -----------------------------------------------Input
print*,"Enter first number..."
read*, a
print*,"Enter second number ..."
read*, b
! -----------------------------------------------Compute
sum = a+b
! -----------------------------------------------Output
print*,"Sum =", sum
end
Which is working on Fortran compiler. And finally I got an exe file which will execute and give fortran result. I am trying to call it from my java program,
My java program as follows:
import java.io.File;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Sum {
public static void main(String []args) {
String filePath = "sum.exe";
if (new File(filePath).exists()) {
try {
ProcessBuilder pb = new ProcessBuilder(filePath);
pb.redirectError();
Process p = pb.start();
InputStream is = p.getInputStream();
int value = -1;
while ((value = is.read()) != -1) {
System.out.print((char) value);
}
int exitCode = p.waitFor();
System.out.println(filePath + " exited with " + exitCode);
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.err.println(filePath + " does not exist");
}
}
}
But it is not working.
I am calling the java from my command prompt as follows:
But cursor blinking only. It is not working.
I did cntrl+c to escape from the java command prompt . That case I gott like the following:
Why it is not working. Please help me. How I could read that exe from my java program correctly. Any help will be appreciated!!
Seems that you need to redirect streams here--so input stream of fortran execution process would be redirected to System.in and output stream to System.out. Just put the following lines:
pb.redirectInput(Redirect.INHERIT);
pb.redirectOutput(Redirect.INHERIT);
before pb.start().
I've been struggling for a while now with this problem and i can't seem to fix it. i have tried ProcessBuilder for executing the custom command on linux terminal but its not working
Actually i have two .sh file setProto.sh and setTls.sh file which is used to set the environment.So for executing the command i need to run these two file first for each instance of linux terminal.Only then we can be able to run the custom command anloss on the same instance of linux terminal in which .sh file supposed to run.For some reason i'm not able to make it work what is the mistake in my code ? Here's the code.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ProcessBuilder.Redirect;
public class EngineTest {
public static void main(String[] args) {
try {
ProcessBuilder builder = new ProcessBuilder(
"/. setProto.sh",
"/. setTls.sh",
"/anloss -i ${TOOL_INPUT}/census_10000_col5.csv -d ${TOOL_DEF}/attr_all_def.txt -q k=14,dage=2 -g ${TOOL_RES}/census_100_col8_gen.csv");
builder.directory(new File(System.getenv("HOME") + "/PVproto/Base"));
File log = new File("log");
builder.redirectErrorStream(true);
builder.redirectOutput(Redirect.appendTo(log));
Process process = builder.start();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = "";
String output = "";
while ((line = bufferedReader.readLine()) != null) {
output += line + "\n";
}
System.out.println(output);
int exitValue = process.waitFor();
System.out.println("\n\nExit Value is " + exitValue);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Process does not by default execute in the context of a shell; therefore your shell scripts cannot be executed the way you tried.
ProcessBuilder pb =
new ProcessBuilder( "/bin/bash",
"-c",
". setProto.sh && . setTls.sh && /anloss -i ${TOOL_INPUT}/census_10000_col5.csv -d ${TOOL_DEF}/attr_all_def.txt -q k=14,dage=2 -g ${TOOL_RES}/census_100_col8_gen.csv" );
I am not sure about /anloss - it's unusual for a command to be in root's home /. (Also, the /. you had there in front of the shell scripts - what should they achieve?)
Later
Make sure to replace /anloss with an absolute pathname or a relative pathname relative to $HOME/PVproto/Base, e.g., if it is in this directory, use ./anloss, if it is in $HOME/PVproto/Base/SomeSub, use SomeSub/anloss, etc.
Also, if setProto.sh and . setTls.sh are not in $HOME/PVproto/Base, use an appropriate absolute or relative pathname. If they are, use ./setProto.sh and ./setTls.sh to avoid dependency on the setting of environment variable PATH.
I think you need to use Runtime.exec() for executing the commands on linux. I suppose you are executing your java code on linux machine where linux scripts needs to be run.
Below code snippet will help you in resolving it.
Process process = Runtime.getRuntime().exec(scriptWithInputParameters);
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("Executed successfully");
}
else {
System.out.println("Failed ...");
}
Please note you need to handle error and output stream in different threads to avoid buffer overflow.
If the above works for you then this article will help you further
I am using a Java class to execute a Perl script on a Linux box. The .class is being created successfully.
But when I execute the class, it says exit code successful as sop, but I'm not able to see the Perl output or the execution of the script. If I execute the Perl directly, it works fine...
This is the Perl script:
#!/usr/local/bin/perl
print ("Enter the distance to be converted:\n");
$originaldist = <STDIN>;
chop ($originaldist);
$miles = $originaldist * 0.6214;
$kilometers = $originaldist * 1.609;
print ($originaldist, " kilometers = ", $miles, " miles\n");
And this is my Java class to call the script:
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
class test {
public static void main(String[] args) throws IOException {
String[] aCmdArgs = { "perl", "-e"
, "pl newprg.pl" };
Runtime oRuntime = Runtime.getRuntime();
Process oProcess = null;
try {
oProcess = oRuntime.exec(aCmdArgs);
oProcess.waitFor();
} catch (Exception e) {
System.out.println("error executing " + aCmdArgs[0]);
}
/* dump output stream */
BufferedReader is = new BufferedReader
( new InputStreamReader(oProcess.getInputStream()));
String sLine;
while ((sLine = is.readLine()) != null) {
System.out.println(sLine);
}
System.out.flush();
/* print final result of process */
System.err.println("Exit status=" + oProcess.exitValue());
return;
}
}
Two issues:
perl -e pl newprg.pl will not actually execute your program from the command line, as it will fail to parse the given (non) expression. You probably meant to use perl newprg.pl
Your program requires input, which you will need to pipe in using the output stream of the process
For example:
try {
oProcess = oRuntime.exec(aCmdArgs);
PrintWriter writer = new PrintWriter(new OutputStreamWriter(
oProcess.getOutputStream()));
writer.println(200);
writer.close();
oProcess.waitFor();
} catch (Exception e) {
System.out.println("error executing " + aCmdArgs[0]);
}
I've been struggling for a while now with this problem and i can't seem to fix it.
i already have tried different approaches (Runtime.exec(), ProcessBuiler) but none seem to work.
This is my issue.
I have a laptop which is always on. This laptop runs a java tool connected to an arduino via usb to turn on and off the lights in the house. i have created this program myself, therefore i'm also doing some regular maintenance work on it. Recently i have added a button to restart the program from my html interface (in case i have an update, or if for some other reason i might need to restart the program or i decide to implement auto updating in the near future).
This idea behind this is to start a second instance of the application from the first instance and then System.exit(0) the first instance.
For some reason i'm not able to start a second instance of the application.
Here's some code.
public void shutdown(boolean restart) {
if (this.serial != null) {
this.serial.disconnect();
}
if (restart) {
System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
String startupCommand = "java -jar \"" + this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath().replace("%20", " ") + "\"";
ProcessBuilder builder = new ProcessBuilder();
// String[] command = new String[1];
// command[0] = "-jar \"" + (System.getProperty("user.dir") + "/Home_Automation_Executor.jar") + "\"";
try {
// //System.out.println("Restarting Home Automation with command: " + command[0]);
// System.out.println("Restarting Home Automation with command: " + startupCommand);
// Runtime.getRuntime().exec("bash");
// Process proc = Runtime.getRuntime().exec(startupCommand);
Process proc = builder.command(startupCommand).start();
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<ERROR>");
while ((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("</ERROR>");
int exitVal = 0;
try {
exitVal = proc.waitFor();
} catch (InterruptedException ex) {
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Process exitValue: " + exitVal);
} catch (IOException ex) {
ex.printStackTrace();
}
}
System.out.println("Terminating Home Automation");
System.exit(0);
}
java.io.IOException: Cannot run program "java -jar "/Users/NightWalker/Dropbox/Development/Source Code/Java/NightWare Tools/Home Automation/Home Automation Executor/dist/Home_Automation_Executor.jar"": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:460)
at home.automation.executor.Engine.shutdown(Engine.java:186)
at home.automation.executor.webserver.HTTPGenerator._handleActionCommand(HTTPGenerator.java:190)
at home.automation.executor.webserver.HTTPGenerator._generateHTTPPage(HTTPGenerator.java:165)
at home.automation.executor.webserver.HTTPGenerator.getHTTPPage(HTTPGenerator.java:58)
at home.automation.executor.webserver.HTTPRequestHandler.run(HTTPRequestHandler.java:160)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.(UNIXProcess.java:53)
at java.lang.ProcessImpl.start(ProcessImpl.java:91)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:453)
... 5 more
The problem is this:
String startupCommand = "java -jar \"" + this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath().replace("%20", " ") + "\"";
/* more stuff */ builder.command(startupCommand);
This means Jav will look for a command named java -jar ...stuff with spaces.... But what you want is, that Java looks for a command named java and give that command several parameters.
You should use
/*...*/ builder.command("java", "-jar", jarLocation) /*...*/
Since it is another Java program you might want to consider running it in the same process because it's much easier to communicate between the two programs if they live in the same process. Have you tried running the command outside your program? Does it work? What does the meta-inf.mf file in the jar hold? It might be that the classpath in the meta-inf.mf file isn't relative so any dependent jars can't be found.