GraalVM嵌入Python多文件Java项目遇导入问题求助
Absolutely, you can make this work! The core issue here is that GraalVM's Python runtime (GraalPy) doesn't automatically add your project root to its module search path (sys.path)—unlike when you run python3 __main__.py directly. Let's walk through immediate fixes and longer-term packaging options tailored to your needs.
Immediate Fix: Add Project Root to GraalPy's sys.path
First, we'll adjust your Java code to explicitly tell GraalPy where to find your src module. We'll also handle the external requests dependency, since your CPython .venv won't work with GraalPy.
Step 1: Update Java Code
Modify your Runner class to add the project root to sys.path before loading your main script:
import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Source; import org.graalvm.polyglot.Value; import java.io.File; import java.io.IOException; public class Runner { public static void main(String[] args) throws IOException { // Define your project root (use absolute path) File projectRoot = new File("/path/to/my-project"); Context context = Context.newBuilder("python") .allowExperimentalOptions(true) .allowAllAccess(true) .allowIO(true) .build(); try (context) { // Add project root to GraalPy's module search path context.eval("python", String.format( "import sys; sys.path.append('%s')", projectRoot.getAbsolutePath() )); // Load and execute your main script Value reference = context.eval( Source.newBuilder("python", new File(projectRoot, "__main__.py")).build() ); // Invoke your lambda and service method as before Value service = reference.execute("http://google.com"); System.out.println("Response: " + service.getMember("invoke").execute()); } } }
Step 2: Install requests for GraalPy
Your existing .venv is for CPython, so you need to install requests directly into GraalPy's environment. Run this command in your terminal (use GraalVM's bundled graalpy executable):
graalpy -m pip install requests
Longer-Term: Python Packaging Tools (Like Webpack for Python)
If you want a cleaner, more maintainable setup (especially for larger projects), use one of these packaging tools to bundle your code and dependencies:
1. PyInstaller
PyInstaller packages your entire Python project (including dependencies) into a single executable or directory. It works well with GraalPy if you use GraalPy's pip to install it:
- Install PyInstaller:
graalpy -m pip install pyinstaller - Bundle your project from the root directory:
graalpy -m PyInstaller __main__.py --name my-project - You can then load the bundled script in GraalVM by pointing to the generated executable or the
__main__.pyinside thedistfolder.
2. setuptools (For Installable Packages)
If you want to treat your project as a proper Python module (like third-party libraries), use setuptools to package it as a wheel or egg. This lets you install it directly into GraalPy, eliminating manual sys.path tweaks:
- Create a
setup.pyfile in your project root:from setuptools import setup, find_packages setup( name="my-project", version="0.1", packages=find_packages(), install_requires=["requests"], ) - First, rename your lambda in
__main__.pyto make it importable:from src.Service import Service # Give the lambda a named reference create_service = lambda url: Service(url) - Package and install your project with GraalPy:
graalpy setup.py sdist bdist_wheel graalpy -m pip install dist/my-project-0.1.tar.gz - Now you can load it directly in Java without file paths:
Value reference = context.eval("python", "from my_project.__main__ import create_service"); Value service = reference.execute("http://google.com");
Key Notes
- GraalPy is GraalVM's Python implementation—make sure all commands use GraalVM's
graalpy(not your system'spython3) to avoid compatibility issues. - Unlike JavaScript, Python's module system relies heavily on
sys.path, so explicit path configuration or proper packaging is required for multi-file projects in GraalVM.
内容的提问来源于stack exchange,提问作者Kamil Budka




