4

I'm using Pythons' subprocess module to run a command.

The command is used to run java JAR file.

When I run it via terminal, it runs fine producing the desired output.

The JAVA command via terminal:

java -cp "*" -Xmx2g edu.stanford.nlp.pipeline.StanfordCoreNLP -annotators tokenize,ssplit,pos,lemma,ner,parse,dcoref,depparse -file input/input.txt

I've written a simple Python script to run the same command.

from subprocess import call
def main():
    call(['java', '-cp', '\"*\"','-Xmx2g','edu.stanford.nlp.pipeline.StanfordCoreNLP','-annotators','tokenize,pos,lemma,ner,parse,dcoref,depparse', '-file', 'input/input.txt'])

Terminal Command (from the same folder where I ran the JAVA Command):

python script.py

Output here is:

Error: Could not find or load main class     edu.stanford.nlp.pipeline.StanfordCoreNLP

I'm missing as to what is not same when I run it from python or run it from the terminal?
What is present in the terminals environment that pythons call() misses out?

Any insight or direction would kick start my project!

Viv
  • 1,488
  • 13
  • 21
  • 1
    How do I about this then? Should I put in an actual Character encoded value or ASCII value? @user2357112 – Viv Apr 10 '17 at 19:37

2 Answers2

3

When typing "*" in your terminal, it just tells Linux not to expand * to "all the contents of the current folder", and just does nothing particular on Windows (double quotes are useful to protect against spaces). In both cases, * is passed to the java command line.

But when passed to subprocess as a list (it's different when passing a string, and I don't recommend doing that), \"*\" (no need for backslashes BTW) is passed to java _literally as "*" so it's not the same as passing *

So you have to just change that argument to * like this:

call(['java', '-cp', '*','-Xmx2g', ...
Jean-François Fabre
  • 126,787
  • 22
  • 103
  • 165
1

As noted in the comments, "*" is passed directly as part of argv and is not evaluated as a glob. That's because subprocess.call() does not invoke a shell. Rather, it calls the exec() system call directly.

You could fix this by any of the following:

  1. Specify the shell. It should be the first argument, before "java".
  2. Include the shell=True argument in call().
  3. Add your classpath entries explicitly in argv.

For general cases you could take your pick, but because this is Java, #3 is probably your best option. Java is kinda weird about how it handles classpath wildcards and it varies by operating system, and in my experience, you'll have fewer headaches if you avoid wildcards in the classpath. See Setting multiple jars in java classpath

Community
  • 1
  • 1
TheCoolah
  • 519
  • 1
  • 4
  • 16