我想看看前两天发布的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
结尾,以便 java
可执行文件忽略 shebang 行。您可以使用不同的扩展名,或者根本没有扩展名(这是他们在 JEP 示例中所做的,也是我推荐的)。
来自 JEP 330(已添加强调):
当启动器读取源文件时, 如果该文件不是 Java 源文件(即不是名称以 .java 结尾的文件) 并且如果第一行以 #! 开头,则该行的内容在确定要传递给编译器的源代码时,最多但不包括第一个换行符将被忽略。第一行之后出现的文件内容必须包含 Java 语言规范版本中第 7.3 节中定义的有效 CompilationUnit,该版本适合 --source 选项中给出的平台版本(如果存在),或者如果 --source 选项不存在,则用于运行程序的平台版本。
不需要特意以“.sh”结尾;另外,这可能会产生误导,因为该文件实际上并不是 shell 脚本。
一些尝试和错误给了我正确的解决方案。 正是文件扩展名
.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
执行它
根据您链接到的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 方法。