首页 > 解决方案 > 在 java shebang 脚本中加载库

问题描述

从 JDK-11 开始,我们可以直接运行 java 源代码。这段代码

import org.apache.commons.codec.digest.Md5Crypt;

public class Oneliner {
  public static void main(String[] args){
    System.out.println(Md5Crypt.md5Crypt("ok".getBytes(), "$1$saltsalt"));
  }
}

可以运行

$ /usr/lib/jvm/jdk-11/bin/java --source 8 -cp /home/imaskar/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar jscript.java

但是以 shell 脚本形式(shebang)

#!/usr/lib/jvm/jdk-11/bin/java --source 8 --class-path /home/imaskar/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar

import org.apache.commons.codec.digest.Md5Crypt;

public class Oneliner {
  public static void main(String[] args){
    System.out.println(Md5Crypt.md5Crypt("ok".getBytes(), "$1$saltsalt"));
  }
}

我收到一个错误:

$ ./jscript.sh
Error: Could not find or load main class ..jscript.sh
Caused by: java.lang.ClassNotFoundException: //jscript/sh

问题是--class-path第一行的论点。由于某种原因--souce,争论得到了通过,但--class-path没有。

标签: javashelljava-11

解决方案


通常不适用于 OpenJDK <= 11.0.7。这是否是一个错误并得到修复尚不清楚。有一个开放的错误报告:

https://bugs.openjdk.java.net/browse/JDK-8242911

--class-path至少使用OpenJDK12.0.214.0.1. 所以我假设对 Java 12 所做的一些改进解决了这个问题。

所以问题中的那一行应该可以工作,不需要改变:

#!/usr/lib/jvm/jdk-11/bin/java --source 8 --class-path /home/imaskar/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar

关于其他答案和评论中提到的其他事情的一些说明:

  • --source 必须是第一个参数。在 shebang 文件中,第一行被视为#!$COMMAND $ONE-SINGLE-ARGUMENT. 所以外壳不会分隔$ONE-SINGLE-ARGUMENTby 空格。因此,Java 启动器将用空格分割参数,如果它以空格开头--source并进一步处理其他参数。
  • 我无法完全解释 muttonUp 的工作示例。我怀疑这与 macOS 的使用有关。也许使用过的 shell 已经拆分了 shebang 参数。
  • 因此,这个问题可能仅限于某些 shell。我已经用 Ubuntubashdash.

推荐阅读