从依赖于另一个 jar 的 jar 加载 class
Load a class from a jar having dependency on another jar
我的项目结构如下(当然非常简单):
所以在 lib-ext
下,我每天从 Jenkins 服务器下载 2 个 jar 文件 'jar1 and jar2' 以供我的程序检查,我需要一个来自 'jar1' 的文件让我们调用它:“Class2Bloaded”。
问题是这个文件实现了一个在 'jar2' 中找到的接口,让我们称之为 'Dependency'
我想做的是,从 src“ClassThatLoads.java”下我的 class,加载 'Class2Bloaded.class' 并告诉 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
调用中,因为我要加载的 class 实现了 jar 2 中的接口。
Exception in thread "main" java.lang.NoClassDefFoundError: com/packagewithinJar2/Dependency
所以最终我准备了另一个指向 'jar2' 的 class 加载器,我什至得到了我需要的实际接口:
URL jar2Url = getJarUrl(jar2);
ClassLoader jar2classLoader = new URLClassLoader(new URL[] { jar2Url });
Class<?> Interface2Bloaded = Class.forName(fullClassName, false, jar2classLoader );
第二种情况下的 'fullClassName' 是 'Class2Bloaded' 所依赖的接口的完全限定名称。
只是我无法在 ClassLoader
的 javadoc 中找到任何允许我 'inject' 附加 class 依赖项加载器的东西。
我希望我的解释清楚。
首先要做的是将 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...
}
}
我的项目结构如下(当然非常简单):
所以在 lib-ext
下,我每天从 Jenkins 服务器下载 2 个 jar 文件 'jar1 and jar2' 以供我的程序检查,我需要一个来自 'jar1' 的文件让我们调用它:“Class2Bloaded”。
问题是这个文件实现了一个在 'jar2' 中找到的接口,让我们称之为 'Dependency'
我想做的是,从 src“ClassThatLoads.java”下我的 class,加载 'Class2Bloaded.class' 并告诉 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
调用中,因为我要加载的 class 实现了 jar 2 中的接口。
Exception in thread "main" java.lang.NoClassDefFoundError: com/packagewithinJar2/Dependency
所以最终我准备了另一个指向 'jar2' 的 class 加载器,我什至得到了我需要的实际接口:
URL jar2Url = getJarUrl(jar2);
ClassLoader jar2classLoader = new URLClassLoader(new URL[] { jar2Url });
Class<?> Interface2Bloaded = Class.forName(fullClassName, false, jar2classLoader );
第二种情况下的 'fullClassName' 是 'Class2Bloaded' 所依赖的接口的完全限定名称。
只是我无法在 ClassLoader
的 javadoc 中找到任何允许我 'inject' 附加 class 依赖项加载器的东西。
我希望我的解释清楚。
首先要做的是将 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...
}
}