I have the following code:
private static String[] createCommandLinux(String cvPath, String jsonPath, String libPath) {
List<String> command = new ArrayList<>();
command.add("java");
command.add("-cp");
command.add("'" + libPath + "/ResumeTransducer/bin/*:" +
libPath + "/GATEFiles/lib/*:" +
libPath + "/GATEFiles/bin/gate.jar:" +
libPath + "/ResumeTransducer/lib/*'");
command.add("code4goal.antony.resumeparser.ResumeParserProgram");
command.add("'" + cvPath + "'");
command.add("'" + jsonPath + "'");
String[] commandArr = new String[command.size()];
commandArr = command.toArray(commandArr);
return commandArr;
}
...
Runtime.getRuntime().exec(createCommandLinux(cvPath,jsonPath,libPath));
...
I copy the command to run on MACOS terminal and it works fine. But when run this command within java application, it can not work as terminal does. It notifies that it can not find the main class. Do you know what the issue with it on MAXOS ?
Thanks
Related
I have a jar file for which I created a custom c++ launcher script. I can't figure how to permit only one instance of the program to run. Is there a way to detect already running jvm?
Here's the launcher code-
#include <string>
#include <direct.h>
using namespace std;
int main(int arg_count, char* arg_list[]) {
string exeName(arg_list[0]);
string rootDir = exeName.substr(0, exeName.find_last_of("\\"));
string jarFile = ".\\dist\\PlayIt.jar";
string cmd;
string javaCmdFile = ".\\jre\\bin\\javaw.exe";
_chdir(rootDir.c_str());
if (arg_count == 1) {
cmd = "start " + javaCmdFile + " -jar " + jarFile + " visible";
}
else if (arg_count > 1) {
cmd = "start " + javaCmdFile + " -jar " + jarFile + " invisible";
for (int i = 1; i < arg_count; i++) {
cmd += " \"" + string(arg_list[i]) + "\"";
}
}
system(cmd.c_str());
}
jps command in /jdk/bin lists all running java processes. if you want to make sure no other processes are running you can use pkill -9 java command.
note that it kills all running java processes.
Why can't I run this:
process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "\"C:\\Program Files\\Gdal\\bin\\gdal\\apps\\ogr2ogr.exe\" -f \"" + "ESRI Shapefile" + "\" \"" + "C:\\Temp\\world.shp" +"\" PG:\"host=" + MainDialog.host + " user=" + MainDialog.dbUser + " password=" + MainDialog.dbPassword + " dbname=" + MainDialog.dataBase + "\" \"" + layerName + "\" -dim " + coordformat});
Which results in command:
"C:\Program Files\Gdal\bin\gdal\apps\ogr2ogr.exe" -f "ESRI Shapefile" "C:\Temp\world.shp" PG:"host=127.0.0.1 user=puser password=pwd dbname=db1" "world" -dim XY
This command can be executed in a Windows cmd-terminal without any problems...
but when running the java process nothing happens, no error codes.
It is much easier to use the String[] for exec(cmd) calls as this avoids problems with the punctuation / escape for parameter values. Try as something like this:
String [] cmd = new String[]{
"C:\\Program Files\\Gdal\\bin\\gdal\\apps\\ogr2ogr.exe"
,"-f"
,"ESRI Shapefile",
,"C:\\Temp\\world.shp"
,"PG:\"host=" + MainDialog.host + " user=" + MainDialog.dbUser + " password=" + MainDialog.dbPassword + " dbname=" + MainDialog.dataBase + "\""
, layerName
, "-dim"
, coordformat
};
Process p = Runtime.getRuntime().exec(cmd);
int rc = p.waitFor();
Runtime.exec is obsolete. Use ProcessBuilder instead. This will not only give your process more flexibility, it will also remove the need for all those extra quotation marks.
Many processes hang if they fill up their output or error buffer and no other process consumes it.
If you don’t care about the output of the process, just use inheritIO() to make sure none of it is blocked:
ProcessBuilder builder = new ProcessBuilder(
"C:\\Program Files\\Gdal\\bin\\gdal\\apps\\ogr2ogr.exe",
"-f", "ESRI Shapefile",
"C:\\Temp\\world.shp",
"PG:host=" + MainDialog.host,
"user=" + MainDialog.dbUser,
"password=" + MainDialog.dbPassword,
"dbname=" + MainDialog.dataBase,
layerName, "-dim", coordformat);
builder.inheritIO();
process = builder.start();
Notice that none of the arguments need to be quoted, and in fact must not be quoted.
If you do care about the output of the process, you can manually do some of the steps which inheritIO() does:
ProcessBuilder builder = new ProcessBuilder(
"C:\\Program Files\\Gdal\\bin\\gdal\\apps\\ogr2ogr.exe",
"-f", "ESRI Shapefile",
"C:\\Temp\\world.shp",
"PG:host=" + MainDialog.host,
"user=" + MainDialog.dbUser,
"password=" + MainDialog.dbPassword,
"dbname=" + MainDialog.dataBase,
layerName, "-dim", coordformat);
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
builder.redirectInput(ProcessBuilder.Redirect.INHERIT);
process = builder.start();
try (InputStream processOutput = process.getInputStream()) {
// ...
}
Thanks for all the help everyone!
When using
"ogr2ogr.exe"
instead of
"C:\Program Files\Gdal\bin\gdal\apps\ogr2ogr.exe"
in the progressBuilder, it works...
It uses system path which is set to C:\Program Files\Gdal\bin\gdal\apps
The strange thing is that it worked with the old version of ogr2ogr.exe, placed in C:\Program Files\OSGeo4W64\bin.
I don't understand....
I'm beginner at java and have some issues trying to startup oracle with java code. I've read several topics about this theme but none of them worked for me. Here is my code:
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
String host = "jdbc:oracle:thin:#localhost:1521:orcl";
String uName = "username";
String uPass = "password";
con = DriverManager.getConnection(host, uName, uPass);
}catch (Exception err){
}
if (con == null){
String[] startupOracle = new String[]{"cmd ", " /c start cmd /K " + "\"" + " chcp 1251 "
+ " &C:\\app\\Raph\\product\\12.1.0\\dbhome_1\\bin\\sqlplus.exe " + "username/password"
+ "&startup" };
Process pr = Runtime.getRuntime().exec(startupOracle);
}
I have two issues:
The Runtime.getRuntime().exec(startupOracle); execute till the point of login me in and stops execution immediately after I'm logged in thereby leaving line 15 ("&startup") not executed.
I'm unable to connect to oracle using "CONNECT / AS SYSDBA" as my username. I guess this is due to the empty space and "/" character in the username because when I use "system" as my username I get connected. I don't know how to solve the issue of empty space and "/" in the former username.
Javadoc of exec(String[] cmdarray) says:
Parameters:
cmdarray - array containing the command to call and its arguments.
Its "arguments" (plural), which means if you want to execute command foo.exe bar abc, then you need to pass { "foo.exe", "bar", "abc" }, not { "foo.exe", "bar abc" }.
For your code that means:
String[] startupOracle = new String[] {
"cmd",
"/c",
"start",
"cmd",
"/K",
"\"chcp 1251" +
" & " +
"C:\\app\\Raph\\product\\12.1.0\\dbhome_1\\bin\\sqlplus.exe username/password &startup\""
};
Or something like that, though I think you have some problems with the &'s.
I have a logging function in CSharp and Java that I use in walking the stack. How do I make each log print to a new line only. Below are my Java and CSharp Functions.
public static void LogFunctionCall(String parameters){
Object trace = Thread.currentThread().getStackTrace()[3];
android.util.Log.i("##################" + trace.toString()+ "", parameters );
}
the java version is this
public static void LogFunctionCall(string parameters,
[System.Runtime.CompilerServices.CallerMemberName] string methodName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
var stackFrame = new StackFrame(1);
var callerMethod = stackFrame.GetMethod();
var className = callerMethod.DeclaringType;
System.Diagnostics.Trace.WriteLine("CCCCCCCCCCCCCCCC" + " " + className + " " + methodName + " " + sourceLineNumber + " " + parameters + "\n");
}
I code on a windows machine.
Please where exactly do I need to place the new line character. I tried this
public static void LogFunctionCall(String parameters){
Object trace = Thread.currentThread().getStackTrace()[3];
android.util.Log.i("##################" + trace.toString()+ "", parameters + "\n" );
}
but I still saw some of the logs being clumped up on a single line.
Instead of \n, try \r\n (carriage return and newline). Some text editors will display differently, so the newline may be in there, but whatever app you're using to read the logs might not be displaying it correctly.
You could also try
System.lineSeparator();
I've seen instances where the /n won't work but the lineSep does.
Also, because it hasn't been mentioned, Environment.NewLine will give you the new line character that is configured for the current environment.
I am having trouble executing a shell command using Java. I am calling 4 commands which are supposed to run the sourceanalyzer executable from within the runFortifyScan method, and populate the fpr and pdf folders that I have created.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Set;
public class fortifyrunUtil {
HashMap<String, Details> projectDetails = new HashMap();
public fortifyrunUtil() {
this.projectDetails.put( "bi-dashboard-test", new Details( "bi-dashboard-test", "testuser#123.com" ) );
}
public void runFortifyScan() {
Set<String> projects = this.projectDetails.keySet();
for ( String project : projects ) {
try {
Details details = this.projectDetails.get( project );
String command = "/Applications/HP_Fortify/HP_Fortify_SCA_and_Apps_4.30/bin/sourceanalyzer -64 -b \"" + details.projectname + "\"" + " -clean";
System.out.println( command );
String output = this.executeCommand( command );
command = "/Applications/HP_Fortify/HP_Fortify_SCA_and_Apps_4.30/bin/sourceanalyzer -64 -b \"" + details.projectname + "\"" + " -source " + "\"1.6\" " + System.getProperty( "user.dir" ) + "/" + details.projectname;
System.out.println( command );
output = this.executeCommand( command );
command = "/Applications/HP_Fortify/HP_Fortify_SCA_and_Apps_4.30/bin/sourceanalyzer -64 -b \"" + details.projectname + "\"" + " -format " + "\"fpr\" -f " + System.getProperty( "user.dir" ) + "/fpr/" + details.projectname + ".fpr -scan";
System.out.println( command );
output = this.executeCommand( command );
command = "/Applications/HP_Fortify/HP_Fortify_SCA_and_Apps_4.30/bin/ReportGenerator -template \"DeveloperWorkbook.xml\" -format \"pdf\" -f " + System.getProperty( "user.dir" ) + "/pdf/" + details.projectname + ".pdf" + " -source " + System.getProperty( "user.dir" ) + "/fpr/" + details.projectname + ".fpr";
System.out.println( command );
output = this.executeCommand( command );
} catch ( Exception details ) {
// empty catch block
System.out.println( "Error while executing fortify command for " + project );
}
}
}
private String executeCommand( String command ) {
StringBuffer output = new StringBuffer();
try {
Process p = Runtime.getRuntime().exec( command );
p.waitFor();
BufferedReader reader = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
String line = "";
while ( (line = reader.readLine()) != null ) {
output.append( String.valueOf( line ) + "\n" );
}
} catch ( Exception e ) {
e.printStackTrace();
}
return output.toString();
}
}
class Details {
String projectname;
String owner;
public Details( String projectname, String owner ) {
this.projectname = projectname;
this.owner = owner;
}
}
It works for some of the other commands I tried, so, my executeCommand method is working.
Also, I did check the permission of the executable I am executing, and have bumped it up to chmod 777, so as to negate that being the cause of the error(EDIT : ignore the word error, I meant to say, to negate that being the cause of the files not getting generated).
-rwxrwxrwx 1 username admin 51428 Mar 17 2015 sourceanalyzer
Also, I have tried running simple scripts from within the folder
where the sourceanalyzer executable is, and that's working as
well.
I have tried running these commands from the command-line, outside
of Java, and it works as expected.
I see that you are trying to use shell argument quoting in your command strings. That does not work in Java, and I suspect it is the root cause of the behavior that you are seeing.
Instead, you should manually split the arguments and pass them as a String[]. For example:
String BIN = "/Applications/HP_Fortify/HP_Fortify_SCA_and_Apps_4.30/bin/";
String command[] = new String[] {
"BIN + "sourceanalyzer",
"-64",
"-b",
details.projectname, // This can contain spaces!!
"-clean"};
output = this.executeCommand(command);
...
private String executeCommand(String[] command) {
...
Process p = Runtime.getRuntime().exec( command );
...
}
(Even if this is not the cause of your problem, you should fix it. Your current approach will lead to arguments with literal quotes being passed to the child process. If some of the arguments that you are attempting to quote contain spaces, things will be even worse.)
If the above is not the problem, another possibility is that you running on a Linux with SELinux in "enforcing" mode, and that is blocking execution of commands ...