从依赖于另一个jar的jar加载一个类

时间:2017-01-04 13:13:34

标签: java classloader

我的项目结构如下(当然非常简化): project structure

所以在lib-ext我每天从Jenkins服务器2下载jar文件'jar1和jar2'下载我的程序检查,我需要一个来自'jar1'的文件让我们调用它:“Class2Bloaded” 。 问题是这个文件实现了一个可以在'jar2'中找到的接口,让我们称之为'依赖'

我想做的是,从我在src“ClassThatLoads.java”下的类加载'Class2Bloaded.class'并告诉类加载器调查'jar2'以搜索实现接口“Dependency.class”

到目前为止我的代码(省略异常处理):

    //Create the URL pointing to Jar1
  private URL getJarUrl(JarFile jarFile)
  {
      return new File(jarFile.getName()).toURI().toURL();
  }

  URL jar1Url = getJarUrl(jar1);
  ClassLoader jar1classLoader = new URLClassLoader(new URL[] { jar1Url });
  Class<?> Class2Bloaded = Class.forName(fullClassName, false, jar1classLoader );

所以问题发生在Class.forName调用中,因为我要加载的类实现了jar 2中的接口。

Exception in thread "main" java.lang.NoClassDefFoundError: com/packagewithinJar2/Dependency

所以最终我准备了另一个指向'jar2'的类加载器,我甚至得到了我需要的实际接口:

URL jar2Url = getJarUrl(jar2);
  ClassLoader jar2classLoader = new URLClassLoader(new URL[] { jar2Url });
  Class<?> Interface2Bloaded = Class.forName(fullClassName, false, jar2classLoader );

其中'fullClassName'在第二种情况下是“Class2Bloaded”所依赖的接口的完全限定名称。 只是因为我无法在ClassLoader的javadocs中找到任何允许我为依赖项“注入”额外的类加载器的东西。 我希望我的解释清楚。

1 个答案:

答案 0 :(得分:2)

首先要做的是将jar2添加到URLClassLoader读取的jar列表中:

ClassLoader jarclassLoader = new URLClassLoader(new URL[] { jar1Url, jar2Url });

但正常的做法是从头开始在类路径中添加jar1和jar2。

为此,您将使用java可执行文件的-cp参数。

例如,如果将类编译到bin目录中:

java -cp libext/jar1.jar:libext/jar2.jar:bin ClassThatLoads

这样,您可以在自己的java源代码中无缝使用这些类,并摆脱繁琐的加载部分:

public class ClassThatLoads {
  public static void main(String[] args) {
    Class2Bloaded stuff = new Class2Bloaded();
    //use stuff from here...
  }
}