33

我对Reflections库有疑问。我正在尝试动态加载所有实现特定接口的类。只要我不在这些类(java 8)中使用 lambda 表达式,一切正常(所有类都已加载)。我尝试升级lib版本但效果相同(java.io.IOException:无效常量类型:18)。

依赖和构建在 pom.xml

      <dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>0.9.10</version>
        <exclusions>
            <exclusion>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.19.0-GA</version>
    </dependency>
    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
    </build>

不排除是同样的效果。

代码:

    URL jarUrl = jarFile.toURI().toURL();
    URLClassLoader child = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader());
    ConfigurationBuilder builder = new ConfigurationBuilder()
            .addClassLoader(child)
            .addUrls(jarUrl)
            .setScanners(new SubTypesScanner());
    Reflections r = new Reflections(builder);
    return r.getSubTypesOf(cls);

如何使用 lambda 表达式加载类?

PS对不起英语:)

4

6 回答 6

49

如果您查看此表,您会看到“常量类型:18”指的是CONSTANT_InvokeDynamic标签值为 的属性18

因此,您使用的库具有与 Java 8 不兼容的类解析器。实际上,这个类解析器甚至不兼容 Java 7,因为这个常量值是从 Java 7 开始指定的。它只是摆脱了这个,因为普通的 Java 代码在 Java 7 中不使用这个特性。但是当与不同的代码产生的交互时JVM 的编程语言,它甚至可能在 Java 7 中失败。

反射的错误跟踪器中有一个项目描述了您的问题。在底部,您会发现通知:

通过此修复:https: //issues.jboss.org/browse/JASSIST-174 javassist 支持此常量。因此,对于 3.18.2-GA,不会发生此错误。

于 2015-05-19T08:23:01.013 回答
15

我解决了这个问题;

首先将javassistjar升级到->3.18.2-GA

  <dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.18.2-GA</version>
  </dependency>

其次添加 weblogic.xml

 <wls:package-name>javassist.*</wls:package-name>
于 2018-05-09T16:10:34.033 回答
10

我刚刚在这里解决了一个类似的问题。就我而言,我的类路径上有两个 javassist jar。我使用 maven,它应该避免这种情况,但是其中一个依赖项使用了不同的 groupId(javassist对于旧的和org.javassist新的,由 导入org.reflections),因此 maven 将它们作为不同的工件处理。

我只是将依赖于旧的库更改为依赖于新的库,一切都已修复!

于 2016-08-21T18:33:14.680 回答
0

如果您使用 weblogic,它可能与它的类加载器已经加载的库发生冲突。您可以通过放置来覆盖它们

...
<weblogic-web-app>
    <container-descriptor>
        <prefer-application-packages>
            <package-name>javassist.*</package-name>
...

在您的 Web 项目的weblogic.xml配置文件中。请注意,真正的 java 包只是javassist,而不是org.javassist(maven groupId)。

于 2017-07-19T08:48:03.287 回答
0

在 Websphere 上,我通过为该应用程序启用“最后一个父级”类加载器解决了这个问题,这样与应用程序一起打包的 JAR 优先于服务器提供的 JAR。

于 2019-02-20T16:41:57.787 回答
-6

我遇到了这个问题,所以我暂时从我的 jdk 进行了降级,EXPORT JAVA_HOME="/home/user/jdk1.7.0_55" 一切正常。

于 2017-04-17T12:20:15.430 回答