I've been looking to incorporate a Python Script a friend made for me into a Java application that I am trying to develop. After some trial and error I finally found out about 'Jython' and used the PythonInterpreter to try and run the script.
However, upon trying to run it, I am getting an error within the Python Script. This is odd because when I try run the script outside of Java (Eclipse IDE in this case), the script works fine and does exactly what I need it to (extract all the images from the .docx files stored in its same directory).
Can someone help me out here?
Java:
import org.python.core.PyException;
import org.python.util.PythonInterpreter;
public class SPImageExtractor
{
public static void main(String[] args) throws PyException
{
try
{
PythonInterpreter.initialize(System.getProperties(), System.getProperties(), new String[0]);
PythonInterpreter interp = new PythonInterpreter();
interp.execfile("C:/Documents and Settings/user/workspace/Intern Project/Proposals/Converted Proposals/Image-Extractor2.py");
}
catch(Exception e)
{
System.out.println(e.toString());
e.printStackTrace();
}
}
}
Java Error regarding Python Script:
Traceback (most recent call last):
File "C:/Documents and
Settings/user/workspace/Intern
Project/Proposals/Converted
Proposals/Image-Extractor2.py", line
19, in
thisDir,_ = path.split(path.abspath(argv[0]))
IndexError: index out of range: 0
Traceback (most recent call last):
File "C:/Documents and
Settings/user/workspace/Intern
Project/Proposals/Converted
Proposals/Image-Extractor2.py", line
19, in
thisDir,_ = path.split(path.abspath(argv[0]))
IndexError: index out of range: 0
Python:
from os import path, chdir, listdir, mkdir, gcwd
from sys import argv
from zipfile import ZipFile
from time import sleep
#A few notes -
#(1) when I do something like " _,variable = something ", that is because
#the function returns two variables, and I only need one. I don't know if it is a
#common convention to use the '_' symbol as the name for the unused variable, but
#I saw it in some guy's code in the past, and I started using it.
#(2) I use "path.join" because on unix operating systems and windows operating systems
#they use different conventions for paths like '\' vs '/'. path.join works on all operating
#systems for making paths.
#Defines what extensions to look for within the file (you can add more to this)
IMAGE_FILE_EXTENSIONS = ('.bmp', '.gif', '.jpg', '.jpeg', '.png', '.tif', '.tiff')
#Changes to the directory in which this script is contained
thisDir = getcwd()
chdir(thisDir)
#Lists all the files/folders in the directory
fileList = listdir('.')
for file in fileList:
#Checks if the item is a file (opposed to being a folder)
if path.isfile(file):
#Fetches the files extension and checks if it is .docx
_,fileExt = path.splitext(file)
if fileExt == '.docx':
#Creates directory for the images
newDirectory = path.join(thisDir, file + "-Images")
if not path.exists(newDirectory):
mkdir(newDirectory)
currentFile = open(file,"r")
for line in currentFile:
print line
sleep(5)
#Opens the file as if it is a zipfile
#Then lists the contents
try:
zipFileHandle = ZipFile(file)
nameList = zipFileHandle.namelist()
for archivedFile in nameList:
#Checks if the file extension is in the list defined above
#And if it is, it extracts the file
_,archiveExt = path.splitext(archivedFile)
if archiveExt in IMAGE_FILE_EXTENSIONS:
zipFileHandle.extract(archivedFile, newDirectory)
except:
pass
My guess is that you don't get command line arguments if the interpreter is called (well not that surprisingly, where should it get the correct values? [or what would be the correct value?]).
os.getcwd()
Return a string representing the current working directory.
Would return the working dir, but presumably that's not what you want.
Not tested, but I think os.path.dirname(os.path.realpath( __ file__)) should work presumably (Note: remove the space there; I should look at the formatting options in detail some time~)
Related
I'm trying to train a neural network to play Halite 3. The provided interface is a bash script which:
1. compiles my bot
2. calls the binary file with a string to run the bot java myBot
I'm trying to run this script from Java to train the network.
I've tried using a ProcessBuilder to run the script as well as the binary in the script. Running the script produces no output, and using echo I've determined that the program terminates when javac is called in the script. Removing that call, it terminates when the program is run.
I've tried calling the program directly as well using ProcessBuilder, and this does indeed produce output. The issue is it doesn't run the bots properly saying it can't find the file. I've tried changing the path to be relative to different directory levels as well as the absolute path (the java command doesn't seem to like absolute paths?).
Calling the binary directly:
List<String> cmd = new ArrayList<>();
cmd.add(dir+ "/src/halite");
// Replay
cmd.add("--replay-directory");
cmd.add(dir+"/replays/");
// Options
cmd.add("--results-as-json");
cmd.add("--no-logs");
// Dimensions
cmd.add("--width");
cmd.add("16");
cmd.add("--height");
cmd.add("16");
// Players
cmd.add("\"java -cp . myBot\"");
cmd.add("\"java -cp . myBot\"");
Process proc = new ProcessBuilder(cmd).start();
InputStream is = proc.getInputStream();
Scanner s = new Scanner(is);
while (s.hasNext()){
System.out.println((String) s.next());
}
This code does produce a JSON, however, I get an error in my logs saying that the bots do not run.
I need the functionality like that of the rsync linux tool in my Java program. For that, I chose the rsync4j library.
Using their documentation, I wrote the following program:
import com.github.fracpete.processoutput4j.output.ConsoleOutputProcessOutput;
import com.github.fracpete.rsync4j.RSync;
public class MainClass {
public static void main(String [] args) {
System.out.println("Started");//check
RSync rsync = new RSync()
.source("/home/arth/DataSourceFolder/a.txt")
.destination("/home/arth/DataDestinationFolder/")
.recursive(true);
// or if you prefer using commandline options:
// rsync.setOptions(new String[]{"-r", "/one/place/", "/other/place/"});
CollectingProcessOutput output = null;
try {
System.out.println("Inside try");
output = rsync.execute();
System.out.println("End of try");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(output.getStdOut());
System.out.println("Exit code: " + output.getExitCode());
if (output.getExitCode() > 0)
System.err.println(output.getStdErr());
}
}
In the snippet, in out local machine, a file a.txt is copied from one location to another. This works perfectly. The file is successfully copied when I run it and here is the output:
Started
Inside try
End of try
Exit code: 0
But my need is to sync a local directory with a directory lying at a remote host/machine. When I tried to do it using a simple rsync command from a terminal using the following command
rsync remoteUserName#23.24.25.244:/home/beth/remoteFolder/a.png /home/arth/DataSourceFolder
it works like a charm. a.png IS copied to local machine at path specified, although a password of remote machine is asked first.
But the problem when I use the above Java program to do the same operation, by replacing line # 11 and 12 by:
.source("remoteUserName#23.24.25.244:/home/beth/remoteFolder/a.png")
.destination("/home/arth/DataDestinationFolder/")
the program gets stuck after printing Started in the console. Neither an exception is thrown nor does the program proceed.
The question is that how do I fix this problem?
(old post, I know, but here it goes...) The rsync4j library does not allow interaction. In your case, the underlying rysnc binary prompts for a password in the process that the Java library created, but never receives one.
Starting with release 3.2.3-7, you can supply an instance of the sshpass wrapper to feed in the password (see this comment for an example).
I have a macbook and our school told us to use TextMate if we don't have a pc. I can do this in a pc, but I'm having trouble with the syntax in a mac OS since they are different. This is what I'm using and even though I created a file named Data.txt, the prompt that pops up says it doesn't exist.
import java.io.File;
class FileClassTutorial
{
public static void main(String[]args)
{
File x= new File("MacintoshHD/Users/Alexis/Desktop/Data.txt");
if(x.exists())
System.out.println(x.getName() + " exists!!!");
else
System.out.println("This file doesn't exist");
}
}
new File("something/other") is assumed to be "./something/other" where '.' is the current working directory where jvm is started. It's what you need ?
Otherwise, you can start a path by '/' to have an absolute path from super-root of your file disk
I have instruction to run program in command line, for example:
java SetTest < alice30.txt
I wonder how to do this in Eclipse. I tried to put this in Run Configuration like this:
Another thing I don't know is where to put this file (alice30.txt). Is this in root of project or in src folder where source files are located?
I know these are beginner questions but I am stuck and need help.
EDIT:
As #Kane suggested I passed File and opened stream.
Instead of:
Scanner in = new Scanner(System.in);
I now use:
Scanner in = new Scanner(new File("alice30.txt"));
You can pass full file path in arguments (e.g. c:/.../alice30.txt))
The eclipse root directory is the base directory of the project (i.e., not the src/ directory, directly under the project.)
It's generally good style to have a 'resources' folder for txt, graphics, etc.
Rather than trying to pass a stream you could just pass the filename and open the stream yourself.
The reason what you're doing in Eclipse isn't working is because your command prompt/shell/dos/bash/whatever is handling creating the input stream out of the file for you. Eclipse doesn't do this. So, from the command line: < alice.txt means "run this program with no arguments, and create a stream to system.in", while doing that in Eclipse means "run this program with two arguments '<' and 'alice.txt'
you need do like this:
add:
import java.io.IOException;
import java.nio.file.Paths;
then:
replace"Scanner in = new Scanner(System.in);"to"Scanner in =new Scanner(Paths.get("alice30.txt"));" .
and you also need do this : "public static void main(String args[]) throws IOException "
With information from this link/page and several tries, I figure out a way to pass argument and file using the local route in eclipse Run -> Run Configurations.. , though it is not recommended as Kane said.
For my case: I need to do " $java someClass tinyW.txt < tinyT.txt " (This is an example from Algorithms book by Robert Sedgewick)
In my case, " tinyW.txt " is a argument, so in the eclipse environment, you can set in Run -> Run Configurations -> Arguments -> Program arguments: /local address/tinyW.txt. For my Ubuntu: /home/****/tinyW.txt
" < tinyT.txt " is a file that pipe to the main arguments, so you can set the route and file in " Run -> RUn Configurations -> Common ", click the "Input File", use the File System icon and select the file from local compute. See the figure. So in Input File: /local_address/tinyT.txt. My case is: /home/***/tinyT.txt. Hope it also works for you.
I have been looking for an answer for how to execute a java jar file through python and after looking at:
Execute .jar from Python
How can I get my python (version 2.5) script to run a jar file inside a folder instead of from command line?
How to run Python egg files directly without installing them?
I tried to do the following (both my jar and python file are in the same directory):
import os
if __name__ == "__main__":
os.system("java -jar Blender.jar")
and
import subprocess
subprocess.call(['(path)Blender.jar'])
Neither have worked. So, I was thinking that I should use Jython instead, but I think there must a be an easier way to execute jar files through python.
Do you have any idea what I may do wrong? Or, is there any other site that I study more about my problem?
I would use subprocess this way:
import subprocess
subprocess.call(['java', '-jar', 'Blender.jar'])
But, if you have a properly configured /proc/sys/fs/binfmt_misc/jar you should be able to run the jar directly, as you wrote.
So, which is exactly the error you are getting?
Please post somewhere all the output you are getting from the failed execution.
This always works for me:
from subprocess import *
def jarWrapper(*args):
process = Popen(['java', '-jar']+list(args), stdout=PIPE, stderr=PIPE)
ret = []
while process.poll() is None:
line = process.stdout.readline()
if line != '' and line.endswith('\n'):
ret.append(line[:-1])
stdout, stderr = process.communicate()
ret += stdout.split('\n')
if stderr != '':
ret += stderr.split('\n')
ret.remove('')
return ret
args = ['myJarFile.jar', 'arg1', 'arg2', 'argN'] # Any number of args to be passed to the jar file
result = jarWrapper(*args)
print result
I used the following way to execute tika jar to extract the content of a word document. It worked and I got the output also. The command I'm trying to run is "java -jar tika-app-1.24.1.jar -t 42250_EN_Upload.docx"
from subprocess import PIPE, Popen
process = Popen(['java', '-jar', 'tika-app-1.24.1.jar', '-t', '42250_EN_Upload.docx'], stdout=PIPE, stderr=PIPE)
result = process.communicate()
print(result[0].decode('utf-8'))
Here I got result as tuple, hence "result[0]". Also the string was in binary format (b-string). To convert it into normal string we need to decode with 'utf-8'.
With args: concrete example using Closure Compiler (https://developers.google.com/closure/) from python
import os
import re
src = test.js
os.execlp("java", 'blablabla', "-jar", './closure_compiler.jar', '--js', src, '--js_output_file', '{}'.format(re.sub('.js$', '.comp.js', src)))
(also see here When using os.execlp, why `python` needs `python` as argv[0])
How about using os.system() like:
os.system('java -jar blabla...')
os.system(command)
Execute the command (a string) in a subshell. This is implemented by calling the Standard C function system(), and has the same limitations. Changes to sys.stdin, etc. are not reflected in the environment of the executed command.