New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReflectionException: Cannot read class file for some JDK9 classes #152

Closed
don-vip opened this Issue Sep 1, 2016 · 19 comments

Comments

Projects
None yet
2 participants
@don-vip
Contributor

don-vip commented Sep 1, 2016

What steps will reproduce the problem?

Run JOSM JUnit tests with JDK9: https://josm.openstreetmap.de/jenkins/job/Java-EarlyAccess-JOSM/jdk=JDK9/lastCompletedBuild/testReport/

What is the code that triggers this problem? (first case)

@FunctionalInterface
public interface Destroyable {
    void destroy();
}

public abstract class JosmAction extends javax.swing.AbstractAction implements Destroyable {
}

public class CombineWayAction extends JosmAction {

    /**
     * A pair of nodes.
     */
    public static class NodePair {
        private final Node a;
        private final Node b;

        /**
         * Constructs a new {@code NodePair}.
         * @param a The first node
         * @param b The second node
         */
        public NodePair(Node a, Node b) {
            this.a = a;
            this.b = b;
        }

        @Override
        public int hashCode() {
            return Objects.hash(a, b);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null || getClass() != obj.getClass()) return false;
            NodePair nodePair = (NodePair) obj;
            return Objects.equals(a, nodePair.a) && Objects.equals(b, nodePair.b);
        }
    }
}

    /**
     * Unit test of methods {@link NodePair#equals} and {@link NodePair#hashCode}.
     */
    @Test
    public void testEqualsContract() {
        EqualsVerifier.forClass(NodePair.class).usingGetClass()
            .withPrefabValues(Node.class, new Node(1), new Node(2))
            .verify();
    }

What is the code that triggers this problem? (second case)

public class ExtensionFileFilter extends javax.swing.filechooser.FileFilter implements java.io.FileFilter {

    private final String extensions;
    private final String description;
    private final String defaultExtension;

    @Override
    public int hashCode() {
        return Objects.hash(extensions, description, defaultExtension);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        ExtensionFileFilter that = (ExtensionFileFilter) obj;
        return Objects.equals(extensions, that.extensions) &&
               Objects.equals(description, that.description) &&
               Objects.equals(defaultExtension, that.defaultExtension);
    }
}

    /**
     * Unit test of methods {@link ExtensionFileFilter#equals} and {@link ExtensionFileFilter#hashCode}.
     */
    @Test
    public void testEqualsContract() {
        EqualsVerifier.forClass(ExtensionFileFilter.class).usingGetClass()
            .verify();
    }

What error message or stack trace does EqualsVerifier give?

junit.framework.AssertionFailedError: ReflectionException: Cannot read class file for AbstractAction.
Suppress Warning.ANNOTATION to skip annotation processing phase.
    at nl.jqno.equalsverifier.EqualsVerifier.handleError(EqualsVerifier.java:381)
    at nl.jqno.equalsverifier.EqualsVerifier.verify(EqualsVerifier.java:370)
    at org.openstreetmap.josm.actions.CombineWayActionTest.testEqualsContract(CombineWayActionTest.java:67)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-ea/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-ea/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-ea/DelegatingMethodAccessorImpl.java:43)

junit.framework.AssertionFailedError: ReflectionException: Cannot read class file for FileFilter.
Suppress Warning.ANNOTATION to skip annotation processing phase.
    at nl.jqno.equalsverifier.EqualsVerifier.handleError(EqualsVerifier.java:381)
    at nl.jqno.equalsverifier.EqualsVerifier.verify(EqualsVerifier.java:370)
    at org.openstreetmap.josm.actions.ExtensionFileFilterTest.testEqualsContract(ExtensionFileFilterTest.java:45)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-ea/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-ea/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-ea/DelegatingMethodAccessorImpl.java:43)

What did you expect?

Test success, like with JDK8

Which version of EqualsVerifier are you using?

2.1.5

Please provide any additional information below.

Complete source code:
https://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
https://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Sep 4, 2016

Owner

Hi,

Thanks for reporting this. Unfortunately, I haven't had time to investigate Java 9 yet. I've just installed it, and I can reproduce your problem. I managed to reduce it to the following little program:

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;

import java.io.InputStream;

public class Example {
    public static void main(String[] args) throws Exception {
        Class<?> c = javax.swing.filechooser.FileFilter.class;
//        Class<?> c = Example.class;
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Type asmType = Type.getType(c);
        String url = asmType.getInternalName() + ".class";
        System.out.println(asmType + " -- " + url);
        InputStream is = cl.getResourceAsStream(url);
        new ClassReader(is);
    }
}

(It depends on ASM 5.1.)

The program terminates without problem om Java 8, but it throws this exception on Java 9:

Ljavax/swing/filechooser/FileFilter; -- javax/swing/filechooser/FileFilter.class
Exception in thread "main" java.io.IOException: Class not found
    at org.objectweb.asm.ClassReader.a(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at Example.main(Example.java:15)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-ea/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-ea/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-ea/DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(java.base@9-ea/Method.java:535)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Process finished with exit code 1

It does the same thing for other types provided by Java (such as java.lang.String), but it does work for user-defined classes (such as Example itself).

ASM has released an alpha version that supports Java 9, but there's no official release yet. Although I can imagine that the problem lies in the way I get hold of a class loader; probably lots of things have changed here due to Project Jigsaw.

In other words, I'll have to find some time to investigate this further. If you have some ideas about this, or if you can point me to some good resources to read up on this, I'd be very grateful 😄 .

In the mean time, you can work around the issue by suppressing Warning.ANNOTATION (though you've probably already figured that out yourself.)

Owner

jqno commented Sep 4, 2016

Hi,

Thanks for reporting this. Unfortunately, I haven't had time to investigate Java 9 yet. I've just installed it, and I can reproduce your problem. I managed to reduce it to the following little program:

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;

import java.io.InputStream;

public class Example {
    public static void main(String[] args) throws Exception {
        Class<?> c = javax.swing.filechooser.FileFilter.class;
//        Class<?> c = Example.class;
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Type asmType = Type.getType(c);
        String url = asmType.getInternalName() + ".class";
        System.out.println(asmType + " -- " + url);
        InputStream is = cl.getResourceAsStream(url);
        new ClassReader(is);
    }
}

(It depends on ASM 5.1.)

The program terminates without problem om Java 8, but it throws this exception on Java 9:

Ljavax/swing/filechooser/FileFilter; -- javax/swing/filechooser/FileFilter.class
Exception in thread "main" java.io.IOException: Class not found
    at org.objectweb.asm.ClassReader.a(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at Example.main(Example.java:15)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-ea/Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-ea/NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-ea/DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(java.base@9-ea/Method.java:535)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Process finished with exit code 1

It does the same thing for other types provided by Java (such as java.lang.String), but it does work for user-defined classes (such as Example itself).

ASM has released an alpha version that supports Java 9, but there's no official release yet. Although I can imagine that the problem lies in the way I get hold of a class loader; probably lots of things have changed here due to Project Jigsaw.

In other words, I'll have to find some time to investigate this further. If you have some ideas about this, or if you can point me to some good resources to read up on this, I'd be very grateful 😄 .

In the mean time, you can work around the issue by suppressing Warning.ANNOTATION (though you've probably already figured that out yourself.)

@jqno jqno added the accepted label Sep 4, 2016

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip

don-vip Sep 4, 2016

Contributor

Thanks for the heads up! FYI we already use ASM 6.0_Alpha with Findbugs 3.1.0_preview2 and we didn't notice any error.

Contributor

don-vip commented Sep 4, 2016

Thanks for the heads up! FYI we already use ASM 6.0_Alpha with Findbugs 3.1.0_preview2 and we didn't notice any error.

openstreetmap-mirror pushed a commit to openstreetmap/josm that referenced this issue Sep 4, 2016

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Sep 4, 2016

Owner

Perhaps the particular use case that I use ASM for, doesn't come up with FindBugs. I tried replacing EqualsVerifier's version of ASM with the 6.0_ALPHA, but that didn't work, unfortunately.

I'll let you know when I find a solution.

Owner

jqno commented Sep 4, 2016

Perhaps the particular use case that I use ASM for, doesn't come up with FindBugs. I tried replacing EqualsVerifier's version of ASM with the 6.0_ALPHA, but that didn't work, unfortunately.

I'll let you know when I find a solution.

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Oct 1, 2016

Owner

I have good news and bad news.
The good news is, I have found a way to solve this issue. Upgrading to ASM 6.0_ALPHA was necessary, but not enough. I have some proof-of-concept grade code that fixes the problem, though.
The bad news is, I can't release it, for several reasons. The most important one is that both JaCoCo and the Maven Shade plugin crash when they encounter the new ASM jar. Looks like they can't handle Java 9 class files and/or jars yet...

I'm attaching the patch file to this issue, so you can try it out locally if you like, and so that I won't forget about it when these issues are fixed :). Keep in mind though, this is still proof of concept code; I wouldn't release this code in the state it's in now. Use at your own risk ;).

issue-152-java-9.patch.txt

Owner

jqno commented Oct 1, 2016

I have good news and bad news.
The good news is, I have found a way to solve this issue. Upgrading to ASM 6.0_ALPHA was necessary, but not enough. I have some proof-of-concept grade code that fixes the problem, though.
The bad news is, I can't release it, for several reasons. The most important one is that both JaCoCo and the Maven Shade plugin crash when they encounter the new ASM jar. Looks like they can't handle Java 9 class files and/or jars yet...

I'm attaching the patch file to this issue, so you can try it out locally if you like, and so that I won't forget about it when these issues are fixed :). Keep in mind though, this is still proof of concept code; I wouldn't release this code in the state it's in now. Use at your own risk ;).

issue-152-java-9.patch.txt

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip

don-vip Oct 1, 2016

Contributor

Did you try Jacoco 0.7.7 or latest snapshot of 0.7.8? We currently use 0.7.8 snapshot to get Java 9 fixes, see jacoco/jacoco#434

Contributor

don-vip commented Oct 1, 2016

Did you try Jacoco 0.7.7 or latest snapshot of 0.7.8? We currently use 0.7.8 snapshot to get Java 9 fixes, see jacoco/jacoco#434

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Oct 1, 2016

Owner

I used Jacoco 0.7.7. I could indeed try the snapshot, but I can (and do) work around it by simply compiling from Java 7 or 8. EqualsVerifier needs to be compatible with all three anyway. Not being able to do Jacoco from Java 9 is very inconvenient, but the real show stopper is the Maven Shade plugin. Without that, I can't build a jar file to publish on Maven Central.

If you have a workaround for that as well, I'd be very grateful :).

Owner

jqno commented Oct 1, 2016

I used Jacoco 0.7.7. I could indeed try the snapshot, but I can (and do) work around it by simply compiling from Java 7 or 8. EqualsVerifier needs to be compatible with all three anyway. Not being able to do Jacoco from Java 9 is very inconvenient, but the real show stopper is the Maven Shade plugin. Without that, I can't build a jar file to publish on Maven Central.

If you have a workaround for that as well, I'd be very grateful :).

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Oct 3, 2016

Owner

Found the issue in Apache's Jira: https://issues.apache.org/jira/browse/MSHADE-234

Owner

jqno commented Oct 3, 2016

Found the issue in Apache's Jira: https://issues.apache.org/jira/browse/MSHADE-234

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip

don-vip May 25, 2017

Contributor

According to https://issues.apache.org/jira/browse/MSHADE-242 they are also waiting for the next ASM release to support Java 9.

Contributor

don-vip commented May 25, 2017

According to https://issues.apache.org/jira/browse/MSHADE-242 they are also waiting for the next ASM release to support Java 9.

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno May 30, 2017

Owner

I tried reproducing this issue today, and upgrading to ASM 6.0_ALPHA fixes it. I don't even need the patch anymore that I mentioned before, so that's a plus. However, I'm not comfortable relying on this ALPHA release. I'd rather wait until there's a final version.

The JaCoCo issue has been resolved; Maven Shade is indeed also still waiting on a final release for ASM 6.0.

Owner

jqno commented May 30, 2017

I tried reproducing this issue today, and upgrading to ASM 6.0_ALPHA fixes it. I don't even need the patch anymore that I mentioned before, so that's a plus. However, I'm not comfortable relying on this ALPHA release. I'd rather wait until there's a final version.

The JaCoCo issue has been resolved; Maven Shade is indeed also still waiting on a final release for ASM 6.0.

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip

don-vip May 30, 2017

Contributor

I agree it's best to wait. Oracle has the obligation to release the final draft of JPMS (module system) next week, we can hope for a new release of ASM not long after, as the maintainer is also in the Expert Group :)

Contributor

don-vip commented May 30, 2017

I agree it's best to wait. Oracle has the obligation to release the final draft of JPMS (module system) next week, we can hope for a new release of ASM not long after, as the maintainer is also in the Expert Group :)

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip
Contributor

don-vip commented Jul 16, 2017

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Jul 18, 2017

Owner

Thanks for the heads-up!

I'll play around with it. If they come up with a final version soon, I'll try to have a Java 9 compatible version soon after. If it takes a while longer, I may release a beta version of EqualsVerifier based on ASM's beta in the mean time. It depends a little on when I have time to work on it.

Owner

jqno commented Jul 18, 2017

Thanks for the heads-up!

I'll play around with it. If they come up with a final version soon, I'll try to have a Java 9 compatible version soon after. If it takes a while longer, I may release a beta version of EqualsVerifier based on ASM's beta in the mean time. It depends a little on when I have time to work on it.

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip

don-vip Aug 4, 2017

Contributor

ASM 6.0 beta is finally available on Maven Central: https://twitter.com/rfscholte/status/893511314575851521

Contributor

don-vip commented Aug 4, 2017

ASM 6.0 beta is finally available on Maven Central: https://twitter.com/rfscholte/status/893511314575851521

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Aug 4, 2017

Owner

Again, thanks for the heads-up; we've been waiting for this for quite a while :). I'll try it out this weekend!

Owner

jqno commented Aug 4, 2017

Again, thanks for the heads-up; we've been waiting for this for quite a while :). I'll try it out this weekend!

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Aug 6, 2017

Owner

I just released version 2.3.2 which uses ASM 6.0_BETA as a dependency. It passes all my tests. Could you give it a try and see if it works for you too?

Owner

jqno commented Aug 6, 2017

I just released version 2.3.2 which uses ASM 6.0_BETA as a dependency. It passes all my tests. Could you give it a try and see if it works for you too?

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip

don-vip Aug 6, 2017

Contributor

Yes, it works! Thanks a lot!

Contributor

don-vip commented Aug 6, 2017

Yes, it works! Thanks a lot!

@don-vip don-vip closed this Aug 6, 2017

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Aug 6, 2017

Owner

I'm very glad to hear that! Thanks for your help :).

Owner

jqno commented Aug 6, 2017

I'm very glad to hear that! Thanks for your help :).

@don-vip

This comment has been minimized.

Show comment
Hide comment
@don-vip

don-vip Aug 22, 2017

Contributor

Maven Shade plugin 3.1.0 is available, see tcurdt/jdependency#11 (comment) :)

Contributor

don-vip commented Aug 22, 2017

Maven Shade plugin 3.1.0 is available, see tcurdt/jdependency#11 (comment) :)

@jqno

This comment has been minimized.

Show comment
Hide comment
@jqno

jqno Aug 23, 2017

Owner

Thanks for letting me know about this! I upgraded, and it works like a charm.

Owner

jqno commented Aug 23, 2017

Thanks for letting me know about this! I upgraded, and it works like a charm.

floscher pushed a commit to floscher/josm that referenced this issue Oct 12, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment