Java Spring Boot failing to find Python Script in resources folder - java

I am trying to call python Scripts(in resources) from my Java class.
This is my code spinnet
String res = "/Scripts/Brokers/__init__.py";
URL pathUrl = this.getClass().getResource(res);
String path = "";
if(pathUrl != null)
path = pathUrl.toString();
ProcessBuilder pb = new ProcessBuilder("/usr/bin/python3.6", path);
ProcessBuilder is giving error No such file or directory.
P.S.
value of path = "file:/home/path-to-project/project-name/out/production/resources/Scripts/Brokers/\__init__.py"
Also how to include python scripts in jar file to run the project on linux server.
I am stuck with this issue since last 3 days. Please suggest.

From java doc:
https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
Starting a new process which uses the default working directory and
environment is easy:
Process p = new ProcessBuilder("myCommand", "myArg").start();
So basically, you going to fork a sub process that will
start a python interpreter
with the python script that you have provided as argument.
The path to your script should be a normal path that your OS can understand, therefore you should not give a URI? like path (protocol:address/path).
if (path.contains(":"))
path = (path.split(":"))[1];
Also the backslash \ before __init__.py looks suspicious.
You should be able to run ls /home/path-to-project/project-name/out/production/resources/Scripts/Brokers/__init__.py and see the file, the same goes for ls /usr/bin/python3.6.

Related

Unable to get Eclipse to recognize binaries using ProcessBuilder located on $PATH on mac os x

I have just switched over to working on a mac and I am trying to determine why I am unable to get Eclipse to recognize the binary I am trying to run via a ProcessBuilder.
I have tried to run it both as a Java Application in Eclipse and as a TestNG test.
If I compile the class with java and run it directly from the command line it will work but not through Eclipse which leads me to believe the configuration for the $PATH is not setup correctly in my TestNG configuration.
Question
I am sure this is a configuration issue within Eclipse but after searching for a day and coming up short I wanted to post for some help. I have tried to set $PATH on the configuration but it does not seem to work.
Thank you
Update /Answer
It turned out that the PATH I had set on the shell shown below was not the same that Java had which I checked using the code below. After verifying that I then added the proper path to my environment on the ProcessBuilder and executed the script as shown in the answer.
Map<String, String> env = processBuilder.environment();
for (String key : env.keySet())
System.out.println(key + ": " + env.get(key));
Map<String, String> envs = processBuilder.environment();
System.out.println("Path " + envs.get("PATH"));
envs.put("PATH", "/usr/local/bin");
System.out.println("PATH " + envs.get("PATH"));
Code
File logsDir = new File(logDirectory);
if (!logsDir.exists()) {
logsDir.mkdirs();
}
// run process directly
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("appium");
processBuilder.redirectError(new File(logsDir, "appiumError.txt"));
processBuilder.redirectOutput(new File(logsDir, "appiumOutput.txt"));
process = processBuilder.start();
Output (it cannot find node to run appium hence the No such file or directory)
Caused by: java.io.IOException: Cannot run program "appium": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at AppiumService.startAppium(AppiumService.java:77)
Path (The bin for node and appium is in /usr/local/bin)
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:
/usr/local/opt/ant/bin:/usr/local/opt/maven/bin:
/usr/local/opt/gradle/bin
The PATH variable of the java-process might be explicitly set by Eclipse not containing the paths you need. You can call the command using the absolute path to the corresponding directory or you might try using a shell to start the process by creating the process with
processBuilder.command("/bin/sh", "-c", "appium");

Running a script from a folder on a Tomcat Server

I am trying to run a script on my tomcat webserver. To run the script before on my local machine, this is the code I used.
String absolutePath = new File(".").getAbsolutePath();
int last = absolutePath.length()-1;
absolutePath = absolutePath.substring(0, last);
String filePath = "";
if(osVersion.equalsIgnoreCase("Ubuntu"))
{
try (FileReader fr = new FileReader("template.txt");
FileWriter fw = new FileWriter("Ubuntu/ubuntu_file.json");) {
int c = fr.read();
while(c!=-1) {
fw.write(c);
c = fr.read();
}
} catch(IOException e) {
e.printStackTrace();
}
filePath = "Ubuntu";
String fi = absolutePath + filePath;
System.out.println(fi);//Get the full path.
// Create ProcessBuilder.
ProcessBuilder pb = new ProcessBuilder("bash", "-c",
"cd "+fi+" ; PACKER_LOG=1 /usr/local/bin/packer build ubuntu_file.json");
Process p = pb.start();
When I however try to run it on the tomcat webserver, I keep getting this error.
EclipseEE.app/Contents/MacOS/Ubuntu Failed to parse template: open
ubuntu_file.json: no such file or directory
I am fairly new to Tomcat, and I am just learning it's ins and outs. What tomcat directory should I place my Ubuntu folder (I am assuming it's the webapp directory) in order for tomcat to get the absolute path of the folder and then be able to run the script.
If you have a more or less conventional Tomcat installation then the $CATALINA_HOME environment variable will be set and point to your server installation which will contain at least the following directories:
$CATALINA_HOME/
bin/
conf/
lib/
webapps/
You can get the value of $CATALINA_HOME via:
String catalinaHomeDir = System.getenv("CATALINA_HOME");
I would be inclined to put your configuration in the conf subdirectory.
If you're running multiple Tomcat instances from the same base then be sure to read the RUNNING.txt file that comes with it because you may need to use $CATALINA_BASE instead.
You may need to set up CATALINA_HOME/BASE in your Eclipse Tomcat Runtime environment when running locally with an Eclipse controlled server.
BTW. This is not a portable solution. If you need to migrate to some other container (such as WildFly or Glassfish) then the absolute path config recommended by others is the way to go.

Running yarn job from java program using ProcessBuilder gives file does not exist error

I am trying to run a yarn job from a java wrapper program. The mapreduce jar takes two inputs:
A header file: I dont know the name of the file but the location and file extension and there's only one file at that location
A Input files directory
Apart from these I have an Output directory.
the processbuilder code looks like:
HEADER_PATH = INPUT_DIRECTORY+"/HEADER/*.tsv";
INPUT_FILES = INPUT_DIRECTORY+"/DATA/";
OUTPUT_DIRECTORY = OUTPUT_DIRECTORY+"/";
ProcessBuilder mapRProcessBuilder = new ProcessBuilder("yarn","jar",JAR_LOCATION,"-Dmapred.job.queue.name=name","-Dmapred.reduce.tasks=500",HEADER_PATH,INPUT_DIRECTORY,OUTPUT_DIRECTORY);
System.out.println(mapRProcessBuilder.command().toString());
Process mapRProcess = mapRProcessBuilder.start();
On run, I get the following error:
Exception in thread "main" java.io.FileNotFoundException: Requested
file /input/path/dir1/HEADER/*.tsv does not exist.
But when I run the same command as :
yarn jar jarfile.jar -Dmapred.job.queue.name=name -Dmapred.reduce.tasks=500 /input/path/dir1/HEADER/*.tsv /input/Dir /output/Dir/
It works all fine.
what can be the issue when running the command from java is causing this issue?
The * is being treated as part of the literal string in this case rather than a wildcard. Therefore globbing isn't expanding to your desired path name.
If there is only one file in the directory, why don't you find what its path is and pass that as the argument instead
eg.
File dir = new File(INPUT_DIRECTORY+"/HEADER);
if (dir.list().length > 0)
String HEADER_PATH = dir.list()[0].getAbsolutePath();

Open a file on Openshift using Java

I have a DIY cartridge. My project structure looks like
MY_PROJECT
-diy
-myProgram.jar
-resources
-file1, file2...
-.openshift
-action_hooks
-start
The myProgram.jar uses files from the folder 'resources'.
The code looks like
File imageFolder = new File("resources");
System.out.println("Image Folder read:"+imageFolder.canRead()); //canRead returns false
File[] listOfFiles = imageFolder.listFiles(); // here I get null
The program runs by action hook 'start':
nohup java -jar $OPENSHIFT_REPO_DIR/diy/*.jar --server.port=${OPENSHIFT_DIY_PORT} --server.address=${OPENSHIFT_DIY_IP} &
The problem is that I'm not able to work with files.
As described in code comments I get null on listFiles().
If I run the program on Openshift manually(ssh to server/$OPENSHIFT_REPO_DIR/diy/ and run java -jar ...) it works, but it doesn't work via action_hooks.
Thank you in advance!
I resolved the issue with Openshift env variable 'OPENSHIFT_REPO_DIR'.
Instead of using relative path
new File("resources");
I use absolute
String absolutePath = System.getenv("OPENSHIFT_REPO_DIR");
new File(absolutePath + "diy/resources")

java, execute exe from WAR in java code

In my war, I have file exe in WEB-INF\classes\
How can I execute this file in Java code (How can I specify path to this file) ?
command = " ? ";
Process x = p.exec(command);
Te following approach could work:
1) Prepare full path of your executable:
ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/classes/executable");
2) Execute like you would normally do it:
String[] cmd = { fullPath /*[...] arguments */};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
This is a simplified example; you may also want to read more about ProcessBuilder.
This is bad idea. Imagine simply fact that your .war packege should run on almost any server (".war is platform independend") and your .exe file is compiled just for one architecture.
Better should be execute your .exe as external program just for separate platform independent and platform dependent part. Then in java you can test operating system and on this basis run desired externel programm.
Read this link with similar question.
The best way to do find a file's real location inside a web app is to use the ServletContext.getRealPath (see http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getRealPath(java.lang.String))
You can access that object from the session...

Categories

Resources