编辑:这是项目设置:
IDE:Eclipse:
Project1:“服务器”
src:
com/mainpackage/main.java
libs:
commons-x-0.jar
PluginInterface.jar
libs-folder中的所有jar都在buildpath上。
Project2:“PluginInterface”
src:
com/interfaces/plugininterface
Project3:“插件”
src:
com/package/class1.java - (this implements plugininterface)
libs:
library1.jar
PluginInterface.jar
libs-folder中的所有jar都在buildpath上
所以当我导出插件(Project3)时,我得到一个这样的jar(从导出中排除PluginInterface.jar)
com/
com/package/
com/package/class1.class
com/package/class1.java
libs/
libs/library1.jar
library1.jar看起来如下 - 它不是我写的:
com/
com/stuff/
com/stuff/libclass.java
com/stuff/libclass.class
现在我想通过界面在“服务器”中使用class1:
ClassLoader loader=URLClassLoader.newInstance(
new URL[]{new URL("file:path/to/plugin.jar")},
ClassLoader.getSystemClassLoader()
);
Class<?> pluginclass = Class.forName("com.package.class1", true, loader);
plugininterface ref = (plugininterface)pluginclass.newInstance();
我现在可以使用项目知道的接口调用class1中的方法,因为它们在构建路径中都包含“PluginInterface.jar”。
问题:
“服务器”无法识别“libclass”,因为它既不在路径中,也不从插入library1的plugin.jar中加载类。
如果在服务器上无法导入库,我该如何访问此类?
感谢您的帮助!
编辑:只是为了有人再次遇到这个问题,我会添加ANT文件的构建目标,使其工作:
<target name="build">
<javac destdir="bin" includeantruntime="false" source="1.7" target="1.7">
<src path="src"/>
<classpath refid="Plugin.classpath"/>
</javac>
<unzip src="${libs}/library1.jar" dest="bin/">
<patternset>
<include name="**/*.class"/>
</patternset>
</unzip>
<jar destfile="plugin.jar" basedir="bin"></jar>
</target>
只需将Library-jar的内容复制到构建目录(在我的情况下为./bin/)。然后甚至不需要将库类提供给类加载器,它在加载类时会找到它们使用它们。
答案 0 :(得分:11)
标准类加载器不支持嵌套的jar文件。您可以以编程方式提取jar,或编写自己的类加载器,它将按需解压缩嵌套文件。但是,你会逆流而行:这种包装不推荐。相反,建议将嵌套jar分解为其父级。例如,这是Maven依赖插件的作用,以及使用Leiningen发布Clojure应用程序的默认方式。
为了从Eclipse实现您的目标,最好的方法似乎是:
让Eclipse的Export JAR向导保存它在内部生成的ant构建脚本,以构建您的JAR;
调整生成的脚本以满足您的特定需求;
将来不再运行向导,而是蚂蚁脚本。
答案 1 :(得分:0)
正如Marko所提到的,您的标准类加载器不会扫描嵌套的jar和嵌套的jar。但是,如果您愿意使用TrueZip,则无需提取档案或任何内容即可轻松完成此操作。更好的是,您可以在嵌套档案中尽可能深地嵌套档案。所以你的路径看起来像:
/path/to/foo.jar/bar/foo/my.zip/containing/some.tar/com/foo/My.class
如果您觉得使用TrueZip编写自己的类加载器感觉很舒服,这将是一种巧妙的方法。如果没有,那么您必须编写一个实用程序类来解析路径并首先提取存档,然后再将其提供给标准URLClassloader
。