【问题标题】:copying a jar file in bootstrap class path not working在引导类路径中复制 jar 文件不起作用
【发布时间】:2017-01-05 12:56:30
【问题描述】:

A 有一个 Java 代码为:

public class Hello
{
        public void print()
        {
                System.out.println("Hi");
        }
}

我编译它并创建了一个 Hello.class。我将它添加到一个 Jar 文件 hello.jar 中:

$jar -cvf hello.jar Hello.class

我又写了一个程序:

class Test1
{
        public static void main(String[] args)
        {
                new Hello().print();
                System.out.println(Hello.class.getClassLoader());
        }
}

并从当前目录中删除了Hello.class。

然后我将 hello.jar 复制到扩展类路径中。我的程序运行良好:

$sudo cp hello.jar /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext
$ java Test1
Hi
sun.misc.Launcher$ExtClassLoader@28d93b30
$ 

如果我从扩展类路径中删除 hello.jar 并将其复制到包含 rt.jar 的引导类路径 (usr/lib/jvm/java-8-openjdk-amd64/jre/lib/) 中,那么我的程序不工作。

$ java Test1
Exception in thread "main" java.lang.NoClassDefFoundError: Hello
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Hello
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

据我所知,bootstrap 或扩展类加载器中的所有 jar 文件都可以在程序中使用。如果它是正确的,为什么 Java 会抛出该异常?如果我不正确,请指导我。

【问题讨论】:

    标签: java jar jvm classloader


    【解决方案1】:

    Bootstrap 类默认是非常具体的,它们只包括 rt.jar 的类和其他几个重要的 jar 文件,因为它是受保护的,不能只扩展 扩展类 旨在通过将 jar 文件添加到 jre/lib/ext/ 来进行扩展。

    但是,您可以修改定义 Open JDK 上的 Bootstrap 类的类路径,方法是如下启动 JVM:

    java -Xbootclasspath/a:"/path/to/my/folder/classes" Test1
    

    -Xbootclasspath/a:path

    指定directires、JAR 档案和ZIP 的冒号分隔路径 要附加到默认引导类路径的存档。

    -Xbootclasspath/p:path

    指定以冒号分隔的directires、JAR 档案和ZIP 档案的路径,以在前面添加 默认引导类路径。注意:使用此选项的应用程序 为了覆盖 rt.jar 中的类,不应部署 因为这样做会违反 Java 2 Runtime Environment 二进制文件 代码许可证。

    这是一个具体的例子https://wiki.openjdk.java.net/display/mlvm/BootClassPath

    【讨论】:

      【解决方案2】:

      我使用的是 java 7 而不是 8,我希望这适用于所有 java 版本。

      在 java 7 中,如果你进入这个 lib 文件夹,你可以看到一个名为 classlist 的文件,如果你打开它,你可以看到所有的基本类都在里面列出(大约 2202 个班级)。这些类是从 lib 文件夹中的所有 jar 文件中加载的。这些文件夹仅包含 JAVA api。因此,为了访问您的 jar,您必须将其包含在 classlist 文件中

      【讨论】:

        【解决方案3】:

        Java 启动器如何查找引导类

        引导类是实现 Java 2 平台的类。引导类位于 rt.jar 和 jre/lib 目录中的其他几个 jar 文件中。这些存档由存储在 sun.boot.class.path 系统属性中的引导类路径的值指定。此系统属性仅供参考,请勿直接修改。

        您不太可能需要重新定义引导类路径。非标准选项 -Xbootclasspath 允许您在需要使用不同核心类集的极少数情况下这样做。

        以上陈述将为您的问题提供答案。

        [Check Oracle Doc]

        System.out.println(System.getProperty("sun.boot.class.path"));
        
        C:\Program Files\Java\jdk1.8.0_74\jre\lib\resources.jar;
        C:\Program Files\Java\jdk1.8.0_74\jre\lib\rt.jar;
        C:\Program Files\Java\jdk1.8.0_74\jre\lib\sunrsasign.jar;
        C:\Program Files\Java\jdk1.8.0_74\jre\lib\jsse.jar;
        C:\Program Files\Java\jdk1.8.0_74\jre\lib\jce.jar;
        C:\Program Files\Java\jdk1.8.0_74\jre\lib\charsets.jar;
        C:\Program Files\Java\jdk1.8.0_74\jre\lib\jfr.jar;
        C:\Program Files\Java\jdk1.8.0_74\jre\classes
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-04-28
          • 2018-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-19
          • 1970-01-01
          相关资源
          最近更新 更多