简体   繁体   English

在 Maven 中编译 Python 源代码

[英]Compile Python Sources in Maven

I have some python source files in my project (under src/main/python ) along with java classes (under src/main/java ).我的项目中有一些 python 源文件(在src/main/python )以及 java 类(在src/main/java )。 I would like to include these python files to my maven target jar.我想将这些 python 文件包含到我的 Maven 目标 jar 中。 Is there a plugin available to do this?有没有插件可以做到这一点?

I can observe that the build artifact created by IntelliJ does include the python files but the one created by maven doesn't.我可以观察到 IntelliJ 创建的构建工件确实包含 python 文件,但 maven 创建的不包含。

As you mentioned, your current project structure has java files in src/java .正如您所提到的,您当前的项目结构在src/java有 java 文件。 This does not conform to maven standard.这不符合 maven 标准。 You should ideally be following the standard structure, makes compatibility simpler with IDEs as well as maven.理想情况下,您应该遵循标准结构,使与 IDE 和 maven 的兼容性更简单。

Java files should be kept in src/main/java that you want to package in jar. Java 文件应保存在要打包到 jar 中的src/main/java中。

Similarily, Python are just script files, not compiled.同样,Python 只是脚本文件,没有经过编译。 So you can put these files in src/main/resources .所以你可以把这些文件放在src/main/resources

src
|---main
|   |---java (Keep your java files here)
|   |---resources
|   \    |---python (You can keep you python files here)
|        \
|---test
|   |---java (Keep your java unit test files here)
|   |---resources (If you have any resources test specific)
|   \

If its not possible, you need to update pom.xml to ensure, src/python is treated as a source folder.如果不可能,则需要更新 pom.xml 以确保将src/python视为源文件夹。 Refer this plugin: build helper plugin参考这个插件: build helper plugin

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
          <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>add-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>src/python</source>
                ...
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Python does not compile into intermediate files, but just executes .py files. Python 不会编译成中间文件,而只是执行.py文件。 (Just like Node.js executes .js files.) (就像 Node.js 执行.js文件一样。)

So we are talking about including and running.所以我们正在谈论包括和运行。

src/main/python folder is not standard, in meaning that there is no plugins that would process python files. src/main/python文件夹不是标准的,这意味着没有可以处理 python 文件的插件。 You can define it as您可以将其定义为

<build>
<resources>
    <resource>
        <directory>src/main/python</directory>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
    </resource>
</resources>

Resources are just copied into jar.资源只是复制到 jar 中。

To access the file from Java从 Java 访问文件

    private static String SOURCE_FILE_NAME = "main.py";
    private static InputStream SOURCE_FILE_INPUT = YourClassName.class.getClassLoader().getResourceAsStream(SOURCE_FILE_NAME);

For running Python from Java there are too many option, each with own limitations:从 Java 运行 Python 有太多选项,每个选项都有自己的限制:

  • as OS process作为操作系统进程
  • as C/C++ library via Java JNI通过 Java JNI 作为 C/C++ 库
  • Jython (only Python, so practically outdated) Jython(只有 Python,所以实际上已经过时了)
  • GraalVM (as of 2021 experimental) GraalVM(截至 2021 年实验性)

with GraalVM使用 GraalVM


        Path path = Paths.get("venv", "bin", "graalpython");
        if (path==null){
            log("venv/ is not yet copied under target/classes/, run `mvn process-resources` or any next maven phase,");
        }
        //String VENV_EXECUTABLE = RunGraalPython3.class.getClassLoader().getResource(path.toString()).getPath();
        String VENV_EXECUTABLE = path.toString();
        log(VENV_EXECUTABLE);

        //try (Context context = Context.create()) {
        //try (Context context = Context.newBuilder(PYTHON).allowAllAccess(true).build()) {
        try (Context context = Context.newBuilder("python").
                allowAllAccess(true).
                option("python.ForceImportSite", "true").
                option("python.Executable", VENV_EXECUTABLE).
                build();) {
            context.eval(PYTHON, "print('Hello Python!')");

            context.eval(PYTHON, "import sys; print(sys.version)");


            InputStreamReader reader = new InputStreamReader(SOURCE_FILE_INPUT);
            Source source;
            try {
                source = Source.newBuilder(PYTHON, reader, SOURCE_FILE_NAME).build();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            context.eval(source);


See https://github.com/paulvi/java-python-graalvm-templatehttps://github.com/paulvi/java-python-graalvm-template

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM