思考 - Java 8 - 无效的常量类型

时间:2015-05-18 21:40:13

标签: java java-8 javassist google-reflections

我的Reflections库存在问题。 我试图动态加载实现特定接口的所有类。 只要我不在这些类中使用lambda表达式(java 8),一切正常(所有类都已加载)。 我试过升级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表达式加载类?

P.S抱歉英语:)

6 个答案:

答案 0 :(得分:36)

如果查看this table,您会看到“常量类型:18”指的是标记值为18的{​​{3}}属性。

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

CONSTANT_InvokeDynamic描述了您的问题。在底部,您会看到通知:

  

通过此修复:an item in the bug tracker of Reflections javassist获得了对此常量的支持。因此,对于3.18.2-GA,不会发生此错误。

答案 1 :(得分:7)

我刚刚解决了类似的问题。就我而言,我的类路径上有两个javassist jar。我使用maven并且应该避免这种情况,但是其中一个依赖项使用了另一个groupId(javassist用于旧的{1}用于新org.javassist,由org.reflections导入,所以maven将它们当作不同的文物处理。

我只是根据旧库更改库以依赖新库,一切都已修复!

答案 2 :(得分:7)

我解决了这个问题;

首先将javassist jar升级为 - &gt; 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>

答案 3 :(得分:0)

如果你使用weblogic,它可能与它已经由它的类加载器加载的库发生冲突。您可以通过添加

来覆盖它们
...
<weblogic-web-app>
    <container-descriptor>
        <prefer-application-packages>
            <package-name>javassist.*</package-name>
...

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

答案 4 :(得分:0)

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

答案 5 :(得分:-3)

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