Skip to content

Latest commit

 

History

History
220 lines (160 loc) · 7.25 KB

File metadata and controls

220 lines (160 loc) · 7.25 KB

Embedding Python in Java

This guide shows you how to embed Python code directly in Java applications using GraalPy. You can use GraalPy with any JDK (GraalVM JDK, Oracle JDK, or OpenJDK).

GraalPy provides dedicated Maven and Gradle plugins that handle all the complexity for you. If you are using other build systems (Ant, Make, CMake), manual configuration is required.

Maven Quick Start

The fastest way to get started is with GraalPy's Maven archetype, which generates a complete starter project for you.

  1. Generate a new project using the GraalPy Maven archetype:

    mvn archetype:generate \
      -DarchetypeGroupId=org.graalvm.python \
      -DarchetypeArtifactId=graalpy-archetype-polyglot-app \
      -DarchetypeVersion=25.0.2

    This generates the following project structure:

    └── polyglot-app
        ├── pom.xml
        ├── src
        │   └── main
        │       ├── java
        │       │   └── com
        │       │       └── example
        │       │           └── Main.java
        │       └── resources
        └── target/
  2. Build a native executable using the GraalVM native-image tool that was added for you automatically:

    mvn -Pnative package
  3. Once completed, run the executable:

    ./target/polyglot_app

    You should see "hello java" printed to the console.

The generated project includes everything you need: the GraalVM Polyglot API for Python execution, Python virtual environment management, and examples showing how to integrate Python packages. The generated pom.xml and Java code are well-documented with explanations of all features.

For advanced plugin configuration, deployment options, and dependency management, see the Embedding Build Tools guide.

Cross-Platform Distribution

For creating cross-platform JARs with native Python packages, see the Virtual Filesystem deployment section in the Build Tools guide.

Gradle Quick Start

If you prefer Gradle, here is how to set up a new project with GraalPy embedding:

  1. Create a new Java application with Gradle:

    gradle init --type java-application \
                --project-name interop  \
                --package interop \
                --no-split-project

    This generates the following project structure:

    └── app
        ├── build.gradle
        └── src
            └── main
                ├── java
                │   └── interop
                │       └── App.java
                └── resources
  2. Add GraalPy dependencies to your app/build.gradle file.

    • Include the GraalPy support and the GraalVM Polyglot API in the dependencies section:

      implementation("org.graalvm.polyglot:polyglot:25.0.2")
      implementation("org.graalvm.python:python-embedding:25.0.2")
  3. Replace the App.java content with this simple Python embedding example:

    package interop;
    
    import org.graalvm.polyglot.*;
    import org.graalvm.python.embedding.GraalPyResources;
    
    class App {
        public static void main(String[] args) {
            try (var context = GraalPyResources.createContext()) {
                System.out.println(context.eval("python", "'Hello Python!'").asString());
            }
        }
    }
  4. Run the application with Gradle:

    ./gradlew run

    The application prints "Hello Python!" to the console.

    Note: GraalPy's performance depends on the JDK you are using. For optimal performance, see the Runtime Optimization Support guide.

Adding Python Dependencies

To use third-party Python packages like NumPy or Requests in your embedded application:

  1. Add the GraalPy Gradle plugin and configure dependencies in app/build.gradle:

    plugins {
        id "java"
        id "application"
        id "org.graalvm.python" version "25.0.2"
    }
    
    graalPy {
       packages = ["termcolor==2.2"]
    }
  2. Update your Java code to use the Python package:

    package interop;
    
    import org.graalvm.polyglot.*;
    import org.graalvm.python.embedding.GraalPyResources;
    
    class App {
        public static void main(String[] args) {
            try (Context context = GraalPyResources.contextBuilder().build()) {
                String src = """
                from termcolor import colored
                colored_text = colored("hello java", "red", attrs=["reverse", "blink"])
                print(colored_text)
                """;
                context.eval("python", src);
            }
        }
    }

For complete plugin configuration options, deployment strategies, and dependency management, see Embedding Build Tools.

Other Build Systems (Ant, CMake, Makefile)

If you are using build systems like Ant, Makefiles, or CMake that do not directly support Maven dependencies, you can still use GraalPy. Projects like Apache Ivy™ can resolve Maven dependencies for these systems, you might prefer a simpler approach. GraalPy provides a tool to download the required JAR files directly.

Manual Setup

  1. Set up your project structure with a directory for dependencies:

    ├── lib/           # JAR dependencies 
    │   └── *.jar
    └── src/           # Your Java source files
        └── *.java
  2. Download GraalPy dependencies using the bundled tool:

    First, install GraalPy and ensure graalpy is in your PATH.

    Then run the appropriate command for your system:

    On Linux/macOS:

    export GRAALPY_HOME=$(graalpy -c 'print(__graalpython__.home)')
    export GRAALPY_VERSION=$(graalpy -c 'import __graalpython__; print(__graalpython__.version)')
    "${GRAALPY_HOME}/libexec/graalpy-polyglot-get" -a python -o lib -v "${GRAALPY_VERSION}"

    On Windows (PowerShell):

    $GRAALPY_HOME = graalpy -c "print(__graalpython__.home)"
    $GRAALPY_VERSION = graalpy -c "import __graalpython__; print(__graalpython__.version)"
    & "$GRAALPY_HOME/libexec/graalpy-polyglot-get" -a python -o lib -v "$GRAALPY_VERSION"

    This downloads all required GraalPy JARs into your lib directory.

  3. Write your embedding code:

    import org.graalvm.polyglot.*;
    
    public class Hello {
        public static void main(String[] args) {
            try (var context = Context.newBuilder()
                    .option("engine.WarnInterpreterOnly", "false")
                    .build()) {
                System.out.println(context.eval("python", "'Hello Python!'").asString());
            }
        }
    }

    Make sure your build system includes all JARs from the lib directory in the classpath.