反射 - Java 8 - 无效的常量类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30313255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 09:26:25  来源:igfitidea点击:

Reflections - Java 8 - invalid constant type

javajava-8javassistgoogle-reflections

提问by Lukasz

I have a problem with Reflectionslibrary. I am trying to load dynamically all classes which implement specific interface. Everything works fine (all classes are loaded) as long as I do not use lambda expression in these classes (java 8). I tried upgrade lib version but effect was the same (java.io.IOException: invalid constant type: 18).

我有反射库的问题。我正在尝试动态加载实现特定接口的所有类。只要我不在这些类中使用 lambda 表达式(java 8),一切都正常(所有类都已加载)。我尝试升级 lib 版本但效果是一样的(java.io.IOException: invalid constant type: 18)。

Dependency and build in pom.xml

依赖并在 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>

without exclusion is the same effect.

不排除是一样的效果。

Code:

代码:

    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);

How can I load classes with lambda expression?

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

P.S Sorry for English :)

PS对不起英语:)

采纳答案by Holger

If you look at this table, you'll see that “constant type: 18” refers to the CONSTANT_InvokeDynamicattribute whose tag value is 18.

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

So you are using a library which has a class parser which is not Java?8 compatible. Actually, this class parser even isn't Java?7 compatible as this constant value is specified since Java?7. It just got away with that as ordinary Java code doesn't use this feature in Java?7. But when interacting with code produced by different programming languages for the JVM, it could even fail with Java?7.

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

There's an item in the bug tracker of Reflectionsdescribing your problem. At the bottom, you will find the notice:

Reflections 的错误跟踪器中一个项目描述了您的问题。在底部,您会看到通知:

With this fix: https://issues.jboss.org/browse/JASSIST-174javassist got support for this constant. So with 3.18.2-GA this error doesn't occur.

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

回答by BrunoJCM

I just fixed a similar issue here. In my case, there were two javassist jars on my class-path. I use maven and it was supposed to avoid that, but one of the dependencies used a different groupId (javassistfor the old one and org.javassistfor the new one, imported by org.reflections), so maven handled them as different artifacts.

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

I just changed the library depending the old one to depend on the new one and everything is fixed!

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

回答by linhadiretalipe

I had this problem so I did the downgrade temporarily from my jdk, EXPORT JAVA_HOME="/home/user/jdk1.7.0_55" and everything worked fine.

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

回答by jediz

If you use weblogic it may be a conflict with the libraries already loaded by it's classloader. You can override them by putting

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

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

in your web projects's weblogic.xmlconfig file. Note the real java package is just javassist, not org.javassist(maven groupId).

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

回答by mehmetunluu

I solved this problem that;

我解决了这个问题;

First upgrade javassistjar to -> 3.18.2-GA

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

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

Secondly add weblogic.xml

其次添加weblogic.xml

 <wls:package-name>javassist.*</wls:package-name>

回答by Pino

On Websphere I solved the problem by enabling the "parent last" classloader for that application so that the JARs packaged with the application take precedence over the ones provided by the server.

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