Calling Python(Code, executable or some other form) from Java

TLDR;

I have a java desktop application that runs on Mac, Linux & Windows and I have a python library. I am trying to call the python package’s function from Java. As long as python can be packaged in the installer of my application and will work on the user’s machines without additional setups.

Details:

I have a java maven project. I have seen it to work on windows. I have seen java call the python and return the response.

    <properties >
        <project.build.sourceLevel>21</project.build.sourceLevel>
        <project.build.targetLevel>21</project.build.targetLevel>

        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest</artifactId>
            <version>2.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>
        <dependency>
            <groupId>org.python</groupId>
            <artifactId>jython-slim</artifactId>
            <version>2.7.3b1</version>
        </dependency>
    </dependencies>

Java

    @Test
    public void getWhispered() throws Exception {
        ProcessBuilder processBuilder = new ProcessBuilder("python", resolvePythonScriptPath("foo5/main.py"), "stringdata");
        processBuilder.redirectErrorStream(true);

        Process process = processBuilder.start();
        List<String> results = readProcessOutput(process.getInputStream());

        assertThat("Results should not be empty", results, is(not(empty())));
        assertThat("Results should contain output of script", results, 
 hasItem(containsString("Argument List"))); // Please excuse in accuracy ... I am adapting a bit.

        int exitCode = process.waitFor();
        assertEquals("No errors should be detected", 0, exitCode);
    }

    private List<String> readProcessOutput(InputStream inputStream) throws IOException {
        try (BufferedReader output = new BufferedReader(new InputStreamReader(inputStream))) {
            return output.lines()
                .collect(Collectors.toList());
        }
    }

    private String resolvePythonScriptPath(String filename) {
        File file = new File("src/test/resources/" + filename);
        return file.getAbsolutePath();
    }

main.py

import sys

print ('Number of arguments:', len(sys.argv), 'arguments.')
print ('Argument List:', str(sys.argv))

But now I see the error … java.io.IOException: Cannot run program "python": CreateProcess error=2, The system cannot find the file specified

I ran both times (when I see it to work. And now when I do not see it working) without python instllation. I uninstalled all python and ran it… I saw it working. But now I do not see it working.

I suspect that I did not restart the windows hence may be there was a cached form of python available somewhere …

Quesiton:

In this invocation is Java calling actual PythonRun time available on the command line in the host machine or is Java’s jar providing the interpreter its self ?

And if someone can help me call a python in a way that I can call some python executable/code/package and get the result … without installing additional things and needing to set up additional things on user’s machines.

Thank you

  • 1

    Python isn’t in your path. Either add python to the PATH, or use the full path to the python binary.

    – 

  • Is there a way to fully package the python content including python interpreter / runtime ? Like a self contained jar analogy ?

    – 

  • That’s way beyond my knowledge, sorry.

    – 

Leave a Comment