35

I have a problem with Reflections library. 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).

Dependency and build in 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?

P.S Sorry for English :)

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
Lukasz
  • 517
  • 1
  • 8
  • 20
  • Possible duplicate of [Error creating entityManagerFactory due to error tying to scan ](http://stackoverflow.com/questions/24281235/error-creating-entitymanagerfactory-due-to-error-tying-to-scan-jar-file) – AlikElzin-kilaka Jul 25 '16 at 13:07

6 Answers6

53

If you look at this table, you’ll see that “constant type: 18” refers to the CONSTANT_InvokeDynamic attribute whose tag value is 18 (0x12).

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.

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

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

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
Holger
  • 285,553
  • 42
  • 434
  • 765
  • 2
    I saw this solution but I used newest version of these libs. Finally I removed reflection lib and wrote own reflection for sub types of class with Guava lib. Thanks for reply. – Lukasz May 20 '15 at 07:14
  • 2
    Same problem here : I had different versions of javassist in 3 frameworks (HikariCP, Orika and Swagger-jaxrs) and Maven picked the oldest one as automatic resolution (3.16-1.-GA instead of the latest one 3.19.0-GA) – Tristan Dec 16 '16 at 16:05
  • 1
    javassist is also in powermock – jediz Jul 14 '17 at 19:09
  • 1
    bingo, it was brought transitively by `jersey-client` and `jersey-core` in my case. all jersey versions ranging from 2.23.2 to 2.25.1 have 3.18-1.-GA bundled. Filed an issue github.com/jersey/jersey/issues/3618 – jediz Jul 14 '17 at 20:12
17

I solved this problem that;

First upgrade javassist jar to -> 3.18.2-GA

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

Secondly add weblogic.xml

 <wls:package-name>javassist.*</wls:package-name>
mehmetunluu
  • 300
  • 2
  • 5
10

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 (javassist for the old one and org.javassist for the new one, imported by org.reflections), so maven handled them as different artifacts.

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

Bruno Medeiros
  • 2,251
  • 21
  • 34
0

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-web-app>
    <container-descriptor>
        <prefer-application-packages>
            <package-name>javassist.*</package-name>
...

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

jediz
  • 4,459
  • 5
  • 36
  • 41
0

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.

Pino
  • 7,468
  • 6
  • 50
  • 69
-6

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.

linhadiretalipe
  • 907
  • 7
  • 8