compile java in a different path from java - java

it's probably a stupid question but i need help.(i tried to solved it myself for 3 hours , so please do not block me)
i'm trying to compile java files in a different directory.
i'm getting a folder with some .java files and i need to compile them.
with:
public boolean complie() throws Exception{
Process pro = Runtime.getRuntime().exec("javac -cp "+location+"/*.java");
String line = null;
BufferedReader in = new BufferedReader(
new InputStreamReader(pro.getErrorStream()));
while ((line = in.readLine()) != null) {
System.out.println(name + " " + line);
}
}
but i'm getting errors.
the errors are point to the usage of other class in the folder. (error: cannot find symbol)
when i'm trying to compile in the CMD after navigating to the folder with "javac *.java", there is no errors.
please help me!
update:
i have trid:
File pathToExecutable = new File(location );
ProcessBuilder builder = new ProcessBuilder( pathToExecutable.getAbsolutePath(),"javac *.java");
builder.directory( new File( location ).getAbsoluteFile() ); // this is where you set the root folder for the executable to run with
builder.redirectErrorStream(true);
Process process = builder.start();
Scanner s = new Scanner(process.getInputStream());
StringBuilder text = new StringBuilder();
while (s.hasNextLine()) {
text.append(s.nextLine());
text.append("\n");
}
s.close();
but getting CreateProcess error=5, Access is denied error (i'm running my IDE as administrator)

One, see this: link ... (I believe that your executing a folder and not a commnad at the example given by you)
Two, ProcessBuilder should be called like this:
String classpath = "somePath" + File.pathSeparator + "otherpath";
ProcessBuilder builder = new ProcessBuilder("javac", "-cp " + classpath, "*.java");
builder.directory(new File(location));
This assuming that location contains the files .java that you want to compile...
UPDATE: This a little example that works for compiling and executing:
package test;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class Compile {
public static void main(String[] args) throws IOException {
ProcessBuilder builder = new ProcessBuilder("javac", "hello/*.java");
builder.directory(new File("C:\\Users\\carlitos\\Desktop"));
Process pro = builder.start();
String line = null;
BufferedReader in = new BufferedReader(new InputStreamReader(pro.getErrorStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
// executing...
ProcessBuilder builder1 = new ProcessBuilder("java", "hello.Main", "carlitosWay");
builder1.directory(new File("C:\\Users\\carlitos\\Desktop"));
Process pro1 = builder1.start();
in = new BufferedReader(new InputStreamReader(pro1.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
}
And the main class:
package hello;
public class Main {
public static void main(String[] args) {
System.out.println("Hello: " + args[0]);
}
}
My example assumes that at "C:/Users/carlitos/Desktop", there is a folder called: "hello", and it contains the class "Main"...

Related

Start and stop postgreSQL service through java code

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");

Compiling and executing using exec in Java fails using command that works from the command line

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...

ProcessBuilder cannot run bat file with spaces in path

I have the following code segment to run a bat file:
String workingDir = System.getProperty("user.dir");
ProcessBuilder pb = new ProcessBuilder("cmd", "/c",
"\"" + workingDir + File.separator + "midl.bat\"");
Process ddsBuildProc = pb.start();
ddsBuildProc.waitFor();
The workingDir includes spaces in the path. Eventhough I use quotes to enclose the workingDir+fileName string, the shell still splits the workingDir and doesn't run the bat file. If a try and copy-paste-execute the bat file path string in the Windows command window manually, it works as expected. What can be the problem here?
Also, please do not close this question as duplicate because I tried all the solutions in the other questions with no success.
Don't quote commands in a command list, unless the command been executed expects it, this will just stuff things up
user.dir is your programs current executing context...so it actually makes no sense to include it, you could just use midl.bat by itself (assuming the command exists within the current execution context)
I wrote a really simple batch file...
#echo off
dir
Which I put in my "C:\Program Files" directory, as I need a path with spaces and used....
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
public class RunBatch {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder(
"cmd", "/c", "listme.bat"
);
pb.directory(new File("C:/Program Files"));
pb.redirectError();
try {
Process process = pb.start();
InputStreamConsumer.consume(process.getInputStream());
System.out.println("Exited with " + process.waitFor());
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
}
}
public static class InputStreamConsumer implements Runnable {
private InputStream is;
public InputStreamConsumer(InputStream is) {
this.is = is;
}
public static void consume(InputStream inputStream) {
new Thread(new InputStreamConsumer(inputStream)).start();
}
#Override
public void run() {
int in = -1;
try {
while ((in = is.read()) != -1) {
System.out.print((char) in);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}
To run it without any issues...

Getting process Details in windows using Java

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);
}
}

Run Import database DOS command from Java

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.

Categories