我想检查一下两天前发布的Java 11的一些新功能。 JEP 330指出我可以不编译就启动Java源代码程序。 它还应支持使用Shebang文件。
因此,我已经编写了这个小型的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!");
}
}
我downloaded JDK 11并将其提取到/opt/java
。
因此,Shebang本身正在工作。
即执行/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
)后,执行失败。
即./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
)。
答案 0 :(得分:15)
文件名不能以.java
结尾,以便java
可执行文件忽略shebang行。您可以使用其他扩展名,也可以根本不扩展名(这是他们在JEP示例中所做的,也是我建议的扩展名。)
来自JEP 330(添加了重点):
启动器读取源文件时,如果该文件不是Java源文件(即不是名称以.java结尾的文件),并且第一行以#开头! ,那么在确定要传递给编译器的源代码时,该行的内容(但不包括第一个换行符)将被忽略。在第一行之后出现的文件内容必须由有效的CompilationUnit组成,如Java语言规范版本中的§7.3所定义,该版本与--source选项中提供的平台版本(如果存在)相对应,或没有--source选项时用于运行程序的平台版本。
它不必以“ .sh”结尾;同样,这可能会引起误解,因为该文件实际上不是Shell脚本。
答案 1 :(得分:6)
反复试验为我提供了正确的解决方案。
引起这些问题的是文件扩展名.java
。
即如果我将文件重命名为Test.sh
,则一切正常。
以下是完整的Hello-World-Shebang-Example:
创建内容为{p>的文件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 :(得分:1)
根据您链接到的JEP(请参见shebang files section),shebang文件用于启动Java进程,而不用作Java的参数:
使用源文件模式调用Java启动器的shebang文件必须以类似以下内容的开头:
#!/path/to/java --source version
例如,我们可以将“ Hello World”程序的源代码放入#!/ path / to / java --source 10的初始行之后,将其放入名为hello的文件中,然后将文件标记为可执行文件。然后,如果文件在当前目录中,则可以使用以下命令执行该文件:
$ ./hello
换句话说,您要做的是使Test.java
可执行。您还必须重命名它,因为当它命名为* .java时,它不能像shebang一样工作并删除第一行。
$ move Test.java test
$ chmod +x test
$ ./test
这将启动shebang处理器,该处理器将删除第一行,并将脚本的其余部分传递到/ path / to / java,Java将编译脚本并运行main方法。