Search code examples
pythongraalvmgraalpython

GraalVM polyglot native image with Python


I'm trying to run a polyglot native image with java/python. I'm able to create the native image with this command line:

 native-image --language:python javapython

But when a run it with ./javapython it throws me this error:

Startup failed, could not read core library from /lib-graalpython/builtins.py. Maybe you need to set python.CoreHome and python.StdLibHome.

Looking for this instruction I found this:

--python.CoreHome=<String>
--python.StdLibHome=<String>

I tried adding it with graalpython, with CoreHome it looks like it works, but with StdLibHome throws me another error:

Original exception was:

Traceback (most recent call last): File "/importlib/_bootstrap.py", line 986, in _find_and_load ModuleNotFoundError: No module named 'site'

Then run again ./javapython but it shows me the same error.

Does anyone know how to configure those paths or why this happened? Thanks


Solution

  • Starting from version 23.1, all GraalVM additional languages can now be easily embedded in Java, including non-Graal JDKs (but with caveats!) by using Maven artifacts published on Mavencentral. Those artifacts embed and transparently on-demand extract the necessary files.

    With regards to native-image, the languages now behave just like any other Java library that supports native-image. There are no extra options necessary for native-image, just put the relevant jars on modulepath (preferably) or classpath.

    Using GraalPy in Java is now as simple as adding this to pom.xml (or equivalent code for the build system of your choice):

        <dependencies>
            <dependency>
                <groupId>org.graalvm.polyglot</groupId>
                <artifactId>polyglot</artifactId>
                <version>23.1.0</version>
            </dependency>
            <dependency>
                <groupId>org.graalvm.polyglot</groupId>
                <artifactId>python-community</artifactId>
                <version>23.1.0</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    

    then one can run Python code via GraalPy just like so:

    try (var ctx = org.graalvm.polyglot.Context.create()) {
        ctx.eval("python", "print('Hello world')"); 
    }
    

    To generate native-image, one can use the Maven plugin for native-image.

    More GraalPy documentation.


    Old answer applicable to versions < 23.1

    GraalPython needs to know where to look for its core library files and also Python standard library files. Normally, the launcher ($GRAALVM_HOME/bin/graalpython) configures this, but if you embed GraalPython in your app, you need to provide it yourself.

    One possibility is to export GRAAL_PYTHONHOME pointing to $GRAALVM_HOME/jre/languages/python (on JDK11 based GraalVM builds it would be $GRAALVM_HOME/languages/python). Another is to provide all the options when building the context:

    Context context = Context.newBuilder()
                  .option("python.CoreHome", "/path/to/graalvm/jre/languages/python/lib-graalpython")
                  .option("python.StdLibHome", "/path/to/graalvm/jre/languages/python/lib-python/3")
                  // ...
                  .build()