I am trying to run a database import command from a Java program like this:
public class Test {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String[] str = {"imp ASKUL/askul#ASKDB file=askdbinstall.dmp log=askul.log fromuser=askul touser=ASKUL full=N ignore=Y grants=Y indexes=Y;"};
Process pro;
try {
pro = Runtime.getRuntime().exec(str);
} catch (Exception e) {
System.out.println(e);
}
}
}
The error Output is:
java.io.IOException: Cannot run program "imp ASKUL/askul#ASKDB file=askdbinstall.dmp log=askul.log fromuser=askul touser=ASKUL full=N ignore=Y grants=Y indexes=Y;": CreateProcess error=2, The system cannot find the file specified
The file askdbinstall.dmp is present because if I Paster the Same Command in CMD, it is importing the database Dump Quite fine. What is My Mistake?
Added:
From Reimius Suggestion I have also tried this:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
public class Tes {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
String [] cmd = {"imp", "ASKUL/askul#ASKDB file=askdbinstall.dmp",
"log=askul.log", "fromuser=askul", "touser=ASKUL",
"full=N ignore=Y grants=Y indexes=Y;"};
Process process = Runtime.getRuntime().exec(cmd);
InputStream in = process.getInputStream();
InputStreamReader ins=new InputStreamReader(in);
BufferedReader br = new BufferedReader(ins);
String data = null;
while ((data = br.readLine()) != null) {
System.out.println(data);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
Output
run:
BUILD SUCCESSFUL (total time: 3 seconds)
No Import is taking place.
Your import command String is being treated as one single command. Try breaking up the tokens. Also check what is being output from Process#getErrorStream:
String[] str = {"imp", "ASKUL/askul#ASKDB file=askdbinstall.dmp",
"log=askul.log", "fromuser=askul", "touser=ASKUL",
"full=N ignore=Y grants=Y indexes=Y;"};
process = Runtime.getRuntime().exec(str);
BufferedReader in =
new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.err.println(line);
}
Aside: ProcessBuilder make the use of parameter passing easier.
Related
An equivalent command for something like this I don't know which is the correct form to call a batch command
def proc =["/bin/sh", "-c","curl https://stackoverflow.com"]
proc.waitFor()
StringBuffer outputStream = new StringBuffer()
proc.waitForProcessOutput(outputStream, System.err)
String output = outputStream.toString()
Why don't you consider using java.net.URL instead?
Sample code is here
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Hello{
public static void main(String []args){
try
{
URL url = new URL("http://stackoverflow.com");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"))) {
for (String line; (line = reader.readLine()) != null;) {
System.out.println(line);
}
}
}
catch (Exception e)
{
System.out.println("error occured");
}
}
}
instead if you want to invoke the curl command from java use the below
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class ShellFromJava {
public static ArrayList<String> command(final String cmdline,
final String directory) {
try {
Process process =
new ProcessBuilder(new String[] {"bash", "-c", cmdline})
.redirectErrorStream(true)
.directory(new File(directory))
.start();
ArrayList<String> output = new ArrayList<String>();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ( (line = br.readLine()) != null )
output.add(line);
if (0 != process.waitFor())
return null;
return output;
} catch (Exception e) {
//Warning: doing this is no good in high-quality applications.
//Instead, present appropriate error messages to the user.
//But it's perfectly fine for prototyping.
return null;
}
}
public static void main(String[] args) {
testHandler("curl http://stackoverflow.com");
}
static void testHandler(String cmdline) {
ArrayList<String> output = command(cmdline, ".");
if (null == output)
System.out.println("\n\n\t\tCOMMAND FAILED: " + cmdline);
else
for (String line : output)
System.out.println(line);
}
}
You can spawn a process from Java:
public class useProcess {
public static void main(String[] args) throws Exception {
String params[] = {"/bin/sh", "-c", "curl", "https://stackoverflow.com"};
Process myProcess = Runtime.getRuntime().exec(params);
myProcess.waitFor();
}
}
I have one requirement where I need to start and stop postgreSQL service through java code. I have written below code but I am getting below error:
System error 5 has occurred.
Access is denied.
System error 5 has occurred.
Access is denied.
Below is my code:
package frontend.guifx.pginstallation;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import common.core.Logger;
import frontend.guifx.util.ConstPG;
public class StartAndStopPostgres {
public static String version = "9.5";
public static void main(String[] args){
try {
System.out.println("Execution starts");
copyPostgreSqlConfFileAndRestartPg();
System.out.println("Execution finished");
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void copyPostgreSqlConfFileAndRestartPg() throws IOException, InterruptedException {
// TODO Auto-generated method stub
Path path = Paths.get("data/PGLogs");
//if directory exists?
if (!Files.exists(path)) {
try {
Files.createDirectories(path);
} catch (IOException e) {
//fail to create directory
e.printStackTrace();
}
}
Logger.print(StartAndStopPostgres.class, new String[] { "Copying postgresql.conf file ........" });
Path source = Paths.get("data/postgresql.windows.conf");
String copyConfFileTo = getInstallationPath(version);
copyConfFileTo = copyConfFileTo.substring(0, copyConfFileTo.lastIndexOf("\\"));
Path outputDirectoryPath = Paths.get(copyConfFileTo+File.separator+"data");
Files.copy(source, outputDirectoryPath.resolve(outputDirectoryPath.getFileSystem().getPath("postgresql.conf")), StandardCopyOption.REPLACE_EXISTING);
Logger.print(StartAndStopPostgres.class, new String[] { "Tunning datbase starts........" });
Runtime rt = Runtime.getRuntime();
final File file = new File(System.getProperty("java.io.tmpdir") + File.separator + ConstPG.CREATE_RESTART_PG_BAT_FILE);
PrintWriter writer = new PrintWriter(file, "UTF-8");
writer.println("net stop postgresql-x64-"+version);
writer.println("net start postgresql-x64-"+version);
writer.close();
String executeSqlCommand = file.getAbsolutePath();
Process process = rt.exec(executeSqlCommand);
/*final List<String> commands = new ArrayList<String>();
commands.add("cmd.exe");
commands.add("/C");
commands.add("net stop postgresql-x64-9.5");
commands.add("net start postgresql-x64-9.5");
ProcessBuilder b = new ProcessBuilder(commands);
Process process = b.start();*/
//public static final String PG_RESTART_PG_LOG_FILE = PG_LOGS+"/pgRestartProcess.log";
File createPgRestartProcessFile = new File(ConstPG.PG_RESTART_PG_LOG_FILE);
redirectProcessExecutionOutput(process, createPgRestartProcessFile);
int exitVal = process.waitFor();
Logger.print(StartAndStopPostgres.class, new String[] { "EXIT VALUE after tunning the PostgreSql database :::::::::::::::::::::" + exitVal + " Logs written to file at: " + createPgRestartProcessFile.getAbsolutePath() });
}
public static String getInstallationPath( String version) {
//public static final String PROGRAMME_FILES = "C:\\Program Files\\";
// public static final String PROGRAMME_FILES_X86 = "C:\\Program Files (x86)\\";
// public static final String POSTGRESQL = "PostgreSQL";
// public static final String PSQL_PATH = "\\bin\\psql.exe";
//Const values used below are as above
String psql = findFile(ConstPG.PROGRAMME_FILES, ConstPG.POSTGRESQL + "\\" + version + ConstPG.PSQL_PATH);
if (psql == null) {
psql = findFile(ConstPG.PROGRAMME_FILES_X86, ConstPG.POSTGRESQL + "\\" + version + ConstPG.PSQL_PATH);
}
if(psql != null){
psql = psql.substring(0, psql.lastIndexOf("\\"));
}
return psql;
}
public static String findFile(String directoryName, String fileName) {
File directory = new File(directoryName);
// get all the files from a directory
File[] fList = directory.listFiles();
String absolutePath;
if (fList != null) {
for (File file : fList) {
if (file.isFile()) {
absolutePath = file.getAbsolutePath();
if (absolutePath.contains(fileName))
return (absolutePath);
} else if (file.isDirectory()) {
absolutePath = findFile(file.getAbsolutePath(), fileName);
if (absolutePath != null)
return (absolutePath);
}
}
}
return (null);
}
private static void redirectProcessExecutionOutput(Process process, File processFile) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = null;
FileWriter fw = new FileWriter(processFile.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
while ((line = reader.readLine()) != null) {
Logger.print(StartAndStopPostgres.class, new String[] { line });
bw.write(line);
bw.newLine();
}
bw.close();
}
}
If I start my eclipse as an Administrator then this works fine. Also if I run start and stop commands on command prompt (which is opened as an Administrator i.e. right click on command prompt icon and click 'run as Administrator') then they execute successfully. But if I run the commands on normal command prompt (which is not opened as a administrator) then I get the same error there as well.
Please advise if there is any solution or any approach to solve this problem.
In java there is a option to run windows cmd as administrator
replace your code "commands.add("cmd.exe");" with below code and try
commands.add("runas /profile /user:ADMINUSERNAME \"cmd.exe");
So the idea is that this line in the code below
Runtime.getRuntime().exec("cd /Users/fnord/Documents/workspace/LearningJava/src/PackA/; javac classA.java; cd ..; java PackA.classA");
should do the same thing as this line
cd /Users/fnord/Documents/workspace/LearningJava/src/PackA/; javac classA.java; cd ..; java PackA.classA
when that second line is run from a terminal. That is to compile and run the java code. Am I misunderstanding how exec() works? If so, what would be the best way to go about accomplishing what it is I want to accomplish?
package PackA;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class classA {
public static void main(String[] args) throws Exception{
ClassLoader loader = classA.class.getClassLoader();
//Sets the file path to the path of the current .java file
File file = new File(loader.getResource(classA.class.getPackage().getName()+"/"+classA.class.getSimpleName()+".class").toString().replaceAll("file:", "").replaceAll("bin", "src").replaceAll("sA.class", "sA.java"));
BufferedReader in = new BufferedReader(new FileReader(file)); //establishes the reader that will be used to read this .java file
StringBuffer string = new StringBuffer(); //the stringBuffer that will be used to hold the contents of this .java file
String stringRead = in.readLine(); //sets a string to the first line of this .java file
while((stringRead) != null){ //as long as we haven't reached the end of the file
string.append(stringRead); //append the line
string.append(System.getProperty("line.separator")); //go to the next line
stringRead = in.readLine(); //read the next line
}
Integer intToFind = new Integer(0); //the integer being looked for
if (intToFind<=10) { //as long as the intToFind is less than or equal to 10
//increment the intToFind in the stringBuffer
StringBuffer newProgram = new StringBuffer(string.toString().replaceFirst("[(]"+intToFind.toString(), "("+String.valueOf(++intToFind)));
//establishes the writer that will be used to write to the file
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(newProgram.toString()); //write the newProgram to this .java file with the incremented intToFind
in.close(); //close both the reader and writer
out.close();
//Go to the directory of the java file, compile the code, move down one directory, execute the .class file
Runtime.getRuntime().exec("cd /Users/fnord/Documents/workspace/LearningJava/src/PackA/; javac classA.java; cd ..; java PackA.classA");
}
}
}
cd is not a program, it's a shell command.
You could use ProcessBuilder instead, which would allow you to define the working directory context from which the command should be executed
Something like this for example
Abbriviated code from previous example, updated to provide the ability to specifiy the working directory
public int compile(String file, File workingDirectory) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("javac", file);
pb.redirectError();
pb.directory(new File(workingDirectory));
Process p = pb.start();
InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
consumer.start();
int result = p.waitFor();
consumer.join();
System.out.println(consumer.getOutput());
return result;
}
public class InputStreamConsumer extends Thread {
private InputStream is;
private IOException exp;
private StringBuilder output;
public InputStreamConsumer(InputStream is) {
this.is = is;
}
#Override
public void run() {
int in = -1;
output = new StringBuilder(64);
try {
while ((in = is.read()) != -1) {
output.append((char) in);
}
} catch (IOException ex) {
ex.printStackTrace();
exp = ex;
}
}
public StringBuilder getOutput() {
return output;
}
public IOException getException() {
return exp;
}
}
Which you could call using something like...
compile("PackA/classA.java", new File("/Users/fnord/Documents/workspace/LearningJava/src"));
Now, if you're really courageous, you could take a look at How do you dynamically compile and load external java classes?, which uses javax.tools.JavaCompiler` class to compile a Java file...
In windows OS. using tasklist ( getting list of current open process ) i have collected list of running process. But how to get actual path of executable file of that process [FILE LOCATION]?
Is there any way to find recently used process from java?
do you mean something like this
import java.io.*;
public class taskmanager {
public static void main(String[] args) throws IOException {
String line;
Process p = Runtime.getRuntime().exec("tasklist.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line); //<-- Parse data here.
// new lines from here
String searchPath = "where notepad.exe";
searchProcessPath(searchPath);
}
input.close();
}
public static void searchProcessPath(String processName) throws IOException
{
Runtime.getRuntime().exec(processName);
}
}
I have been able to compile a python program from a java program. I am capturing the errors found in the python program and getting it printed out in the console.
I am not getting all the errors in the .py file at one go. I have to correct the previous error and run it again to get the next error. And below is sample of what I get in my console:
I need to capture only the line numbers and the syntax error e.g: pint.
Here's a sample of my program where log is string which holds the details about the error found:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Python_Compiler {
public static void main(String args[]){
String ret = compile();
System.out.println(ret);
}
public static String compile()
{
String log="";
String myDirectory = "C:\\";
try {
String s= null;
//change this string to your compilers location
Process p = Runtime.getRuntime().exec("cmd /C python Hello.py", null, new java.io.File(myDirectory));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
boolean error=false;
log+="";
while ((s = stdError.readLine()) != null) {
log+=s;
error=true;
log+="\n";
}if(error==false) log+="Compilation Successful !!!";
} catch (IOException e) {
e.printStackTrace();
}
return log;
}
public int runProgram()
{
int ret = -1;
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("cmd.exe /c start a.exe");
proc.waitFor();
ret = proc.exitValue();
} catch (Throwable t)
{
t.printStackTrace();
return ret;
}
return ret;
}}
Can anyone help in extracting only the line number and syntax error and have it stored in an array?
So you want to capture the line number which is 3 and the error which is prit.