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

问题描述 投票:0回答:3

我想看看前两天发布的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 并将其解压到

/opt/java
。 因此 Shebang 本身正在发挥作用。 IE。执行
/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.java
可执行(使用
chmod +x Test.java
)后执行失败。 IE。
./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

一旦我从

Test.java
中移除 Shebang-Line 并以
/opt/java/jdk-11/bin/java --source 11 Test.java
启动它 一切都很顺利,我得到了预期的输出:
Hello World!

我的机器正在运行

Ubuntu 17.04
。 我已将
javac
链接到 JDK 11 中的那个(即执行
javac -version
给出
javac 11
)。

java shebang java-11
3个回答
34
投票

文件名不得以

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

来自 JEP 330(已添加强调):

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

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


7
投票

一些尝试和错误给了我正确的解决方案。 正是文件扩展名

.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

执行它

2
投票

根据您链接到的JEP(请参阅shebang文件部分),shebang文件将用于启动java进程,而不是用作java的参数:

使用源文件模式调用 Java 启动器的 shebang 文件必须以以下内容开头:

#!/path/to/java --source version

例如,我们可以获取“Hello World”程序的源代码,并将其放入名为 hello 的文件中,在初始行 #!/path/to/java --source 10 之后,然后标记文件作为可执行文件。然后,如果该文件位于当前目录中,我们可以使用以下命令执行它:

$ ./hello

换句话说,你想做的就是使

Test.java
可执行。您还必须重命名它,因为当它被命名为 *.java 时,它不会像 shebang 一样工作并删除第一行。

$ move Test.java test
$ chmod +x test
$ ./test 

这将启动 shebang 处理器,它将剥离第一行并将脚本的其余部分传递到 /path/to/java,Java 将编译脚本并运行 main 方法。

© www.soinside.com 2019 - 2024. All rights reserved.