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

时间:2018-09-27 06:09:10

标签: java shebang java-11

我想检查一下两天前发布的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)。

3 个答案:

答案 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方法。