【问题标题】:How can I load a class which is not in the same jar archive as the current class?如何加载与当前类不在同一个 jar 存档中的类?
【发布时间】:2011-11-07 12:21:28
【问题描述】:

情况:

我正在制作一个用于绘制算法时间复杂度的模拟器。学生可以添加加载自己的 .java 文件来运行它。 我的程序编译(使用'JavaCompiler').java 文件。然后它会尝试加载 .class 文件:

loadedClass = loadClass("customAlgorithms."+this.getClassName()+"");

在 Eclipse 中运行我的程序时,一切正常,学生可以完美地使用该程序。

问题:

然后我将我的项目导出到一个可执行的 jar 文件。编译部分仍然有效,但加载类失败,因为它在 jar 文件中搜索它内部

我想知道为什么我不能这样做:(用 / 改变 .)

loadedClass = loadClass("customAlgorithms/"+this.getClassName()+"");

有哪些可能的选择?以下是我能想到的:

  • 将已编译的 .class 文件添加到当前运行的 .jar 文件中。这还能用吗?

    我知道可以编辑 jar 存档。但是这可以在运行时工作而无需重新启动程序吗?

  • 使用 'loadClass()' 的其他方式?这样我就可以加载一个不包含在我的 jar 文件中的类文件

还有其他想法吗?

【问题讨论】:

    标签: java jar classloader java-compiler-api


    【解决方案1】:

    Java 通过 ClassLoaders 加载类。当您启动 JVM 时,您必须告诉 JVM 它的“类路径”,即类所在的文件夹或 jar 文件的列表。 JVM 会创建一个 ClassLoader(通常是 URLClassLoader 的子类),并给这个 ClassLoader 文件夹和 jar 文件的列表,以便类加载器能够加载该类。

    在您的应用程序中,当您编译 java 源文件时,它会生成一个类文件,该文件保存在某处。大概在eclipse中,保存class文件的文件夹就是classpath中包含的文件夹,这样JVM就能找到class了。

    当您将项目导出到正在运行的 jar 文件时,JVM 可能会开始在其类路径中仅包含该 JAR 文件,因此它不会在其他任何地方搜索您编译的类。

    您有多种方法可以解决此问题。按复杂度升序排列:

    1. 不要将 jar 作为可执行 jar 启动,而是使用 .bat/.sh 或任何其他可以配置类路径的 java 运行程序,将特定文件夹添加到类路径,将 java 源文件编译到该文件夹.
    2. 当您编译 java 文件时,创建一个文件夹并创建一个指向该文件夹的 URLClassLoader 的新实例。将 java 文件编译到该文件夹​​。然后使用该 URLCLassLoader 加载编译后的类。
    3. 将 java 源代码编译到 RAM,例如字节数组,并实现一个自定义类加载器,该类加载器将返回该字节数组,而不是从磁盘加载。

    解决方案1非常简单,但也有缺点:如果不再次运行整个程序,将无法重新加载已编译的java文件(一旦在类加载器中加载了一个类,就无法再次加载它,除非使用超出此问题范围的代理),它需要程序写入磁盘,这意味着权限等。

    解决方案 2 及其演变(仅 RAM)更加优雅,但也更加复杂:从与整个应用程序其余部分使用的类加载器不同的类加载器加载单个类非常棘手,您可能会遇到奇怪的类异常(如 ClassCastExceptions、ClassNotFoundException 等)由于类加载器之间的不匹配。

    【讨论】:

      【解决方案2】:

      您必须创建另一个类加载器,例如 URLClassLoader 并从中加载类。

      【讨论】:

        【解决方案3】:

        您可以使用ClassLoader defineClass method。它受到保护,但应该没有问题。

        如果方法受保护这一事实是一个问题,可能在互联网的某个地方,您可以定义一个自定义子类,该子类免费提供该功能。

        【讨论】:

          猜你喜欢
          • 2017-01-23
          • 1970-01-01
          • 2017-11-01
          • 2018-03-14
          • 1970-01-01
          • 2011-05-07
          • 1970-01-01
          • 2013-12-31
          • 1970-01-01
          相关资源
          最近更新 更多