如何在 Eclipse 中使用 GraalVM (SubstrateVM) 将 Java 编译为 Native

Jay*_*yan 5 java eclipse graalvm substratevm

我有一个研究项目(在 Java 8 中实现),在 Eclipse 中包含几个类、几个主要函数和超过 10000 行代码。当输入不小时,程序就会内存不足。

我想看看如果编译为本机应用程序,它是否会使用更少的堆栈内存。

我没有找到在 Eclipse 中执行此操作的方法。

我做到了,
$GRAALVM_HOME/bin/javac /home/appu/Downloads/2019/June/20/HelloWorld.java
它有效。我得到了一个可以工作的二进制文件。

我尝试了
/home/appu/Downloads/Apps/GraalVM/2019-06-20/graalvm-ee-19.0.2/bin/native-image /home/appu/eclipse-nimi/NimishaGraalEE19/bin/nimi/decimate/Decimate.class
我得到Main entry point class '/home/appu/eclipse-nimi/NimishaGraalEE19/bin/nimi/decimate/Decimate.class' not found.

我尝试了
/home/appu/Downloads/Apps/GraalVM/2019-06-20/graalvm-ee-19.0.2/bin/native-image /home/appu/eclipse-nimi/NimishaGraalEE19/bin/*
我得到Main entry point class '/home/appu/eclipse-nimi/NimishaGraalEE19/bin/nimi' not found.

经典

public class HelloWorld
{
    public static void main(String[] args)
    {
        System.out.println("Hello, World!");
    }
}
Run Code Online (Sandbox Code Playgroud)

被编译成“HelloWorld.class”

它给出了一个可执行文件“helloworld”,它是可执行的(application/x-executable)。

我可以从 Eclipse 得到同样的东西吗?对于多类文件,我可以从命令行获得相同的结果吗?

当我将上面的代码更改为

public class HelloWorld
{
    public static void hello()
    {
        System.out.println("Hello, World!");
    }
}
Run Code Online (Sandbox Code Playgroud)

并添加另一个类

public class Main
{
    public static void main(String[] args)
    {
        HelloWorld.hello();
    }
}
Run Code Online (Sandbox Code Playgroud)

他们编译正确,但我得到

appu[23]/home/appu/Downloads/Apps/GraalVM/2019-06-20/graalvm-ee-19.0.2/bin/native-image /home/appu/Downloads/2019/June/23/HelloWorld.class 
Build on Server(pid: 17223, port: 36631)                                                          
[/home/appu/downloads/2019/june/23/helloworld.class:17223]    classlist:     415.66 ms            
Error: Main entry point class '/home/appu/Downloads/2019/June/23/HelloWorld.class' not found.     
Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception             
Error: Image build request failed with exit status 1                                              
appu[23]ls                                                                                        
HelloWorld.class  HelloWorld.java  Main.class  Main.java
Run Code Online (Sandbox Code Playgroud)

我想要的是一个可以用作本机可执行文件的可执行文件(在我的例子中是 Gnu/Linux 可执行文件)。

我更喜欢 Eclipse 的解决方案,但也欢迎命令行、Netbeans、VS Code...或任何其他技术。


回应 BoriS 的回答:

几个小时前,我尝试制作一个罐子,并制作了一个名为 Main.jar 的文件。它不起作用。

jar cfe Main.jar Main Main.class
/home/appu/Downloads/Apps/GraalVM/2019-06-20/graalvm-ee-19.0.2/bin/native-image -jar /home/appu/Downloads/2019/June/23/Main.jar
./Main
Run Code Online (Sandbox Code Playgroud)

当我运行可执行(应用程序/x可执行)类型的 Main 时,我得到了

Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld
        at Main.main(Main.java:5)
Caused by: java.lang.ClassNotFoundException: HelloWorld
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more
Run Code Online (Sandbox Code Playgroud)

Bor*_*riS 6

文档中的两个选项(https://www.graalvm.org/docs/reference-manual/aot-compilation/):

1) 构建项目的 jar 并从中构建本机映像

native-image [options] -jar jarfile为 jar 文件构建映像。

2)正确设置原生镜像类路径,并给原生镜像你想要的main

您可以为本机映像构建提供其他选项: -cp--class-path 帮助通过单独的目录列表、JAR 存档和 ZIP 存档搜索类文件;

native-image [options] class为当前工作目录中的类构建可执行文件。调用它会执行该类的本机编译代码。