Reflection + libraries java



编辑:这是项目设置:

IDE:Eclipse:

项目1:"服务器"

src:
com/mainpackage/main.java
libs:
commons-x-0.jar
PluginInterface.jar

libs文件夹中的所有jar都在构建路径上。

项目2:"插件接口"

src:
com/interfaces/plugininterface

项目3:"插件"

src:
com/package/class1.java - (this implements plugininterface)
libs:
library1.jar
PluginInterface.jar

libs文件夹中的所有jar都在构建路径上

所以当我导出插件(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/)。然后甚至不需要将库类馈送到Classloader,它在加载Classes时会找到它们。

标准类加载器不支持嵌套的jar文件。您可以通过编程方式提取jar,或者编写自己的类加载器,根据需要解压缩嵌套文件。然而,你会逆流而行:这样的包装是不推荐的。相反,建议将嵌套的jar分解为其父jar。例如,这就是Maven依赖插件所做的,也是使用Leiningen发布Clojure应用程序的默认方式。

为了实现Eclipse的目标,最好的方法似乎是:

  1. 让Eclipse的ExportJAR向导保存它内部生成的ant构建脚本来构建JAR;

  2. 调整生成的脚本以满足您的特定需求;

  3. 以后不再运行向导,而是运行ant脚本。

正如Marko所提到的,您的标准类加载器不会扫描嵌套的jar和其中的嵌套jar。然而,如果你愿意玩TrueZip,你可以很容易地做到这一点,而不必提取档案或任何东西。更好的是,您可以在嵌套的归档中拥有任意深度的嵌套归档。所以你的路径可能看起来像:

/path/to/foo.jar/bar/foo/my.zip/containing/some.tar/com/foo/My.class

如果你觉得用TrueZip编写自己的类加载器很舒服,这将是一个很好的方法。如果不是,那么你必须编写一个实用程序类,先解析路径并提取档案,然后再将其输入标准URLClassloader

相关内容

  • 没有找到相关文章

最新更新