从WAR文件中的JAR构建类路径

奥利维尔·罗杰(Olivier Roger)

我正在尝试从给定的WAR文件中动态提取配置。我的目标是找到实现某些接口(Parameter)的所有类

war文件不在类路径中,因此我创建了一个临时类加载器来检查其类。

URL webClasses = new URL("jar","","file:" + new File(path).getAbsolutePath() + "!/WEB-INF/classes/");
URLClassLoader cl = URLClassLoader.newInstance(new URL[] { webClasses });
Reflections reflections = new Reflections(ClasspathHelper.forClassLoader(cl), new SubTypesScanner(), cl);
Set<Class<? extends Parameter>> params = reflections.getSubTypesOf(Parameter.class);

这很好。Parameter在我的webapp中找到了所有的实现

现在,我想对中的每个jar执行相同的操作WEB-INF/lib不幸的是,在这种情况下,我还没有找到一种构建类加载器的方法。类加载器似乎忽略了jar URLjar:<url>!/WEB-INF/lib/{entry}.jar)。

当我运行下面的代码时,Reflections没有找到任何类

Set<URL> libs = findLibJars(warUrl));
// The URLs are in the following format : {myWar}.war!/WEB-INF/lib/{myLib}.jar
URLClassLoader cl = URLClassLoader.newInstance(urls.toArray(new URL[urls.size()]));
cl.loadClass("my.company.config.AppParameter");

如果可能的话,我想避免不得不WEB-INF/lib/*.jar从WAR文件中提取并单独分析它们。

我在这里想念什么吗?(执行此操作的其他方法,创建类加载器的其他方法,...任何线索都将有所帮助)。也许可以在不使用Reflections库的情况下完成此操作?

谢尔盖·塔切诺夫(Sergei Tachenov)

当然有可能。这是一个丑陋的例子:

String warName = "wlaj.war";
ClassLoader loader = new ClassLoader() {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // This probably needs fixing:
        String fileName = name.replace('.', '/') + ".class";
        try {
            try (ZipFile zf = new ZipFile(warName)) {
                ZipEntry jar = zf.getEntry("WEB-INF/lib/jlaj.jar");
                if (jar == null)
                    throw new ClassNotFoundException("No jlaj.jar");
                try (ZipInputStream jarInput = new ZipInputStream(zf.getInputStream(jar))) {
                    for (ZipEntry cl; (cl = jarInput.getNextEntry()) != null; ) {
                        if (fileName.equals(cl.getName())) {
                            ByteArrayOutputStream data = new ByteArrayOutputStream();
                            byte[] buffer = new byte[4096];
                            for (int len; (len = jarInput.read(buffer)) != -1; ) {
                                data.write(buffer, 0, len);
                            }
                            buffer = data.toByteArray();
                            return defineClass(name, buffer, 0, buffer.length);
                        }
                    }
                }
            }
            throw new ClassNotFoundException();
        } catch (IOException ex) {
            throw new ClassNotFoundException("Error opening class file", ex);
        }
    }
};
loader.loadClass("jlaj.NewJFrame");

问题:

  1. 需要一种绝妙的万无一失的方法来将类名转换为JAR中的文件路径。就我而言"jlaj.NewJFrame" -> "jlaj/NewJFrame.class",但是在尝试加载内部类时可能变得非常丑陋,甚至在某些其他情况下我甚至都无法考虑。
  2. 读取类数据可能应该属于某种实用程序readAll方法,因为它看起来非常凌乱。
  3. 显然,这需要将WAR名称和内部JAR名称都传递给构造函数的非匿名类。ZipFileZipEntry,如果您想在外部进行迭代。

从积极的方面来说,它是有效的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

JBoss:EAR中的WAR文件在类路径上找不到JAR库

如何从JAR中的类路径读取文件?

在Java jar(ear,war,...)文件中搜索类/方法

Jar在类路径中

从Android Studio中的Gradle路径中删除文件/ jar /类

将生成的类捆绑到jar中,并将其添加到构建类路径中

WAR文件的Java类路径补丁概念

从文件夹中的现有jar创建类路径

Spring 在类路径中找不到文件,但它就在 war 文件的根目录中

JAR 中的类文件似乎被忽略了;而是从类路径上的目录中提取类文件

jar中的类路径资源

无法构建war文件:无法删除目标目录中的validation-api-2.0.1.Final.jar

Gradle构建的.war文件中的文件重复

运行其他jar文件时,Ant buildfile无法将jar文件放在类路径中

包含JAR中的JAR的类路径

Linux cmd可以在jar中搜索一个类文件,而与jar路径无关

用多个类构建Jar文件

Spring Boot Maven如何构建war和jar文件

设置类路径以包含.jar文件

Java编译失败与jar文件的类路径

无法加载类路径上的jar文件

如何在Gradle JAR类路径构建脚本中包含com.sun.tools JAR并与IDE同步?

即使在类路径中包含了jar文件,也无法在运行时找到类

在JAR文件和运行时库路径中包括子项目gradle构建输出

使用生成的 jar 文件中的类路径编译 Java 源文件

将文件夹中的所有jar文件添加到类路径

如何在Eclipse中将充满Jar文件的文件夹添加到类路径中?

使用已经建立了路径的jar文件中的类文件

通过包含Avro自动生成的类来构建War文件