Java 11:通过Shebang执行源文件不起作用

2022-09-01 22:51:35

我想看看两天前发布的java 11的一些新功能。JEP 330 指出,我可以在不编译的情况下启动 Java 源代码程序。它还应该支持Shebang-Files的使用。

因此,我写了这个小的Hello-World程序:Test.java

#!/opt/java/jdk-11/bin/java --source 11

public class Test
{
    public static void main(String[] args)
    {
        System.out.println("Hello World!");
    }
}

下载了JDK 11并将其解压缩到.因此,Shebang本身正在发挥作用。即执行给我/opt/java/opt/java/jdk-11/bin/java --version

openjdk 11 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

在制作可执行文件(使用)后,执行失败。即 给我:Test.javachmod +x Test.java./Test.java

./Test.java:1: error: illegal character: '#'
#!/opt/java/jdk-11/bin/java --source 11
^
./Test.java:1: error: class, interface, or enum expected
#!/opt/java/jdk-11/bin/java --source 11
^
2 errors
error: compilation failed

一旦我从Shebang-Line中删除并开始它,一切都像一个魅力一样工作,我得到了预期的输出:Test.java/opt/java/jdk-11/bin/java --source 11 Test.javaHello World!

我的计算机正在运行 。我已经链接到JDK 11中的那个(即执行给)。Ubuntu 17.04javacjavac -versionjavac 11


答案 1

文件名不得以 结尾,以便可执行文件忽略 shebang 行。您可以使用其他扩展,或者根本没有扩展(这是他们在 JEP 示例中所做的,也是我建议的)。.javajava

JEP 330(着重号是后加的):

当启动器读取源文件时,如果该文件不是 Java 源文件(即它不是名称以 .java 结尾的文件),并且如果第一行以 #! 开头,则在确定要传递给编译器的源代码时,将忽略该行的内容,但不包括第一个换行符。出现在第一行之后的文件内容必须由 Java 语言规范版本中 §7.3 定义的有效 CompilationUnit 组成,该编译单元适用于 --source 选项中给定的平台版本(如果存在),或者如果 --source 选项不存在,则为用于运行程序的平台版本。

它不需要以“.sh”结尾;此外,这可能会产生误导,因为该文件实际上不是shell脚本。


答案 2

经过一些反复试验,我得到了正确的解决方案。是文件扩展名导致了这些问题。.java

即,如果我将文件重命名为一切正常。Test.sh

这是一个完整的Hello-World-Shebang-示例:

创建包含类似内容的文件Test.sh

#!/opt/java/jdk-11/bin/java --source 11

public class Test
{
    public static void main(String[] args)
    {
        System.out.println("Hello World!");
    }
}

使其可执行(即 )。chmod +x Test.sh

最后但并非最不重要的一点是使用./Test.sh


推荐