0

I have next method:

public void callPython() throws IOException {
        Runtime rt = Runtime.getRuntime();
        Process pr = rt.exec("python -c \"from test import read_and_show; read_and_show()\" src/main/python");

        BufferedReader bfr = new BufferedReader(new InputStreamReader(pr.getInputStream()));
        BufferedReader bfre = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
        String outputStr = "";
        while ((outputStr = bfr.readLine()) != null) {
            System.out.println(outputStr);
        }
        while ((outputStr = bfre.readLine()) != null) {
            System.out.println(outputStr);
        }
    }

in python file next code:

import os
from stat import *

def read_and_show():
    print('worked!')

when i call this in terminal all worked correctly (before i cd to this directory):

MacBook-Pro-Nikita-2:python NG$ python -c "from test import read_and_show; read_and_show()"
worked!

when i run this code in my java code he return error:

  File "<string>", line 1
    "from
        ^
SyntaxError: EOL while scanning string literal

What i make wrong?

P.S.: i need run python method/class/file for read, parse and show graphical data. but for this need when java run python single method (def)

abbath0767
  • 946
  • 2
  • 11
  • 31

3 Answers3

1

When executing other programs from java, I've found it's easier to keep it as simple as possible in java and instead execute a batch file

Runtime.getRuntime().exec("chrome.exe www.google.com");

Would instead become

Runtime.getRuntime().exec("openChrome.bat");

and openChrome.bat:

chrome.exe www.google.com

This makes it easier to test the command without recompiling, but may get complicated if you need to pass variables as arguments

To use shell built-ins like echo and cd, the batch file works wonders (ie echo test | program)


The major downside is you will have a floating .bat file next to your code

If packaging to a .jar, you may need to first copy the .bat file out of the .jar before executing

phflack
  • 2,729
  • 1
  • 9
  • 21
0

You're missing the shebang statement that states where the python interpreter is. It should be line #1

#!/usr/bin/python
Calculus
  • 781
  • 7
  • 20
  • While it's missing from the file, how does it change behaviour of executing the same command from the command line vs from java? I thought it would fail in both cases or succeed in both cases – phflack Mar 06 '18 at 15:33
  • if you type "python", and start python from command line then you've already manually found the interpreter. If you run the script from somewhere else, you need to tell the script where the interpreter is. – Calculus Mar 06 '18 at 15:36
  • Yes, but it looks like they are passing everything as arguments instead of as user input – phflack Mar 06 '18 at 15:40
0

Runtime.exec is obsolete. It was replaced by the ProcessBuilder class a long time ago:

ProcessBuilder builder = new ProcessBuilder(
    "python", "-c", "from test import read_and_show; read_and_show()", "src/main/python");
builder.redirectInput(ProcessBuilder.Redirect.INHERIT);
Process pr = builder.start();

Notice that from test import read_and_show; read_and_show() does not have double-quote characters around it. Those quotes are something used by a shell (like bash). The python command never actually sees them, and shouldn’t see them. Executing a child process from Java (or any other language, really) does not invoke a shell; it executes the command directly. Which means the quotes wouldn’t be interpreted by any shell, and they’d be passed to the python program as part of the argument.

VGR
  • 40,506
  • 4
  • 48
  • 63