反思 - Java 8 - 无效的常量类型
Posted
技术标签:
【中文标题】反思 - Java 8 - 无效的常量类型【英文标题】:Reflections - Java 8 - invalid constant type 【发布时间】:2015-05-18 21:40:13 【问题描述】: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 表达式加载类?
P.S 对不起英语:)
【问题讨论】:
Error creating entityManagerFactory due to error tying to scan <jar-file>的可能重复 【参考方案1】:如果您查看this table,您会看到“常量类型:18”指的是标签值为18
的CONSTANT_InvokeDynamic
属性。
因此,您使用的库具有与 Java 8 不兼容的类解析器。实际上,这个类解析器甚至与 Java 7 不兼容,因为这个常量值是从 Java 7 开始指定的。它只是摆脱了这个,因为普通的 Java 代码在 Java 7 中不使用这个特性。但是当与不同生成的代码交互时JVM 的编程语言,它甚至可能在 Java 7 上失败。
an item in the bug tracker of Reflections 描述了您的问题。在底部,您会发现通知:
有了这个修复:https://issues.jboss.org/browse/JASSIST-174 javassist 得到了对这个常量的支持。所以在 3.18.2-GA 中不会出现这个错误。
【讨论】:
我看到了这个解决方案,但我使用了这些库的最新版本。最后,我删除了反射库,并使用 Guava 库为类的子类型编写了自己的反射。感谢您的回复。 同样的问题:我在 3 个框架(HikariCP、Orika 和 Swagger-jaxrs)中有不同版本的 javassist,Maven 选择了最旧的一个作为自动解析(3.16-1.-GA 而不是最新的一个 3.19.0-GA) javassist 也在 powermock 中 宾果游戏,就我而言,它是由jersey-client
和jersey-core
传递的。从 2.23.2 到 2.25.1 的所有球衣版本都捆绑了 3.18-1.-GA。提交问题 github.com/jersey/jersey/issues/3618【参考方案2】:
我解决了这个问题;
第一次升级javassist
jar 到 -> 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>
【讨论】:
哪个文件必须用于 webshere?【参考方案3】:我刚刚在这里修复了一个类似的问题。就我而言,我的类路径上有两个 javassist jar。我使用 maven,它应该避免这种情况,但是其中一个依赖项使用了不同的 groupId(javassist
用于旧的,org.javassist
用于新的,由org.reflections
导入),因此 maven 将它们处理为不同人工制品。
我只是将依赖于旧的库更改为依赖于新的库,一切都已修复!
【讨论】:
【参考方案4】:如果你使用 weblogic,它可能与它的类加载器已经加载的库发生冲突。您可以通过放置来覆盖它们
...
<weblogic-web-app>
<container-descriptor>
<prefer-application-packages>
<package-name>javassist.*</package-name>
...
在您的 Web 项目的 weblogic.xml
配置文件中。注意真正的java包只是javassist
,而不是org.javassist
(maven groupId)。
【讨论】:
【参考方案5】:在 Websphere 上,我通过为该应用程序启用“最后一个父级”类加载器解决了这个问题,这样与应用程序一起打包的 JAR 优先于服务器提供的 JAR。
【讨论】:
【参考方案6】:我遇到了这个问题,所以我暂时从我的 jdk 进行了降级,EXPORT JAVA_HOME="/home/user/jdk1.7.0_55" 一切正常。
【讨论】:
您应该考虑原始问题中的所有限制,降级并不能真正解决任何问题。以上是关于反思 - Java 8 - 无效的常量类型的主要内容,如果未能解决你的问题,请参考以下文章