Java11: 通过 Shebang 执行源文件不工作
Java 11: Executing Source File via Shebang is not working
我想看看两天前发布的 java 11 的一些新功能。
JEP 330 声明我可以在不编译的情况下启动 Java-Source-Code-Program。
它还应该支持 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!");
}
}
我downloaded 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
导致了这些问题。
即如果我将文件重命名为 Test.sh
一切正常。
这是一个完整的 Hello-World-Shebang-Example:
创建一个文件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 files section),shebang 文件将用于启动 java 进程,而不是用作 java:
A shebang file to invoke the Java launcher using source-file mode must begin with something like:
#!/path/to/java --source version
For example, we could take the source code for a "Hello World" program, and put it in a file called hello, after an initial line of #!/path/to/java --source 10, and then mark the file as executable. Then, if the file is in the current directory, we could execute it with:
$ ./hello
换句话说,您要做的是使 Test.java
可执行。您还必须重命名它,因为当它被命名为 *.java.
时,它不会像 shebang 和删除第一行一样工作
$ move Test.java test
$ chmod +x test
$ ./test
这将启动 shebang 处理器,它将去除第一行并将脚本的其余部分传递给 /path/to/java,Java 将编译脚本和 运行 主要方法。
文件名不得以 .java
结尾,以便 java
可执行文件忽略 shebang 行。您可以使用不同的扩展名,或者根本没有扩展名(这是他们在 JEP 示例中所做的,也是我推荐的)。
来自 JEP 330(已强调):
When the launcher reads the source file, if the file is not a Java source file (i.e. it is not a file whose name ends with .java) and if the first line begins with #!, then the contents of that line up to but not including the first newline are ignored when determining the source code to be passed to the compiler. The content of the file that appears after the first line must consist of a valid CompilationUnit as defined by §7.3 in the edition of the Java Language Specification that is appropriate to the version of the platform given in the --source option, if present, or the version of the platform being used to run the program if the --source option is not present.
不需要特别以“.sh”结尾;此外,这可能会产生误导,因为该文件实际上并不是 shell 脚本。
我想看看两天前发布的 java 11 的一些新功能。 JEP 330 声明我可以在不编译的情况下启动 Java-Source-Code-Program。 它还应该支持 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!");
}
}
我downloaded 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
导致了这些问题。
即如果我将文件重命名为 Test.sh
一切正常。
这是一个完整的 Hello-World-Shebang-Example:
创建一个文件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 files section),shebang 文件将用于启动 java 进程,而不是用作 java:
A shebang file to invoke the Java launcher using source-file mode must begin with something like:
#!/path/to/java --source version
For example, we could take the source code for a "Hello World" program, and put it in a file called hello, after an initial line of #!/path/to/java --source 10, and then mark the file as executable. Then, if the file is in the current directory, we could execute it with:
$ ./hello
换句话说,您要做的是使 Test.java
可执行。您还必须重命名它,因为当它被命名为 *.java.
$ move Test.java test
$ chmod +x test
$ ./test
这将启动 shebang 处理器,它将去除第一行并将脚本的其余部分传递给 /path/to/java,Java 将编译脚本和 运行 主要方法。
文件名不得以 .java
结尾,以便 java
可执行文件忽略 shebang 行。您可以使用不同的扩展名,或者根本没有扩展名(这是他们在 JEP 示例中所做的,也是我推荐的)。
来自 JEP 330(已强调):
When the launcher reads the source file, if the file is not a Java source file (i.e. it is not a file whose name ends with .java) and if the first line begins with #!, then the contents of that line up to but not including the first newline are ignored when determining the source code to be passed to the compiler. The content of the file that appears after the first line must consist of a valid CompilationUnit as defined by §7.3 in the edition of the Java Language Specification that is appropriate to the version of the platform given in the --source option, if present, or the version of the platform being used to run the program if the --source option is not present.
不需要特别以“.sh”结尾;此外,这可能会产生误导,因为该文件实际上并不是 shell 脚本。