You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

GraalVM嵌入Python多文件Java项目遇导入问题求助

Solution for Multi-File Python Projects in GraalVM

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__.py inside the dist folder.

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.py file 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__.py to 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's python3) 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

火山引擎 最新活动