Skip to content
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

Fix NullPointerException in ClassInfo accepting java.lang.Object #113

Merged
merged 1 commit into from
Jan 10, 2017
Merged

Fix NullPointerException in ClassInfo accepting java.lang.Object #113

merged 1 commit into from
Jan 10, 2017

Conversation

lyubomyr-shaydariv
Copy link
Contributor

I'm trying to experiment with bootclasspath in Java and I'm trying to enhance java.lang.Object. Let's say, by adding simple id() method:

package java.lang;

public class Object {

    // BEGIN extensions

    public final int id() {
        return System.identityHashCode(this);
    }

    // END extensions

... <<the original java.lang.Object source code goes here>> ...

}

I've already managed to make the bootclasspath option work for JRE 1.8 and the following code is now valid in my experiment:

System.out.println(new Object().id());

As a point of interest, I would also like to experiment with Android inspired by this article. So I need RetroLambda to downgrade the bytecode because I'm using JDK 1.8. However, using retrolambda-maven-plugin:2.3.0 I've got the following exception:

[ERROR] Failed to execute goal net.orfjackal.retrolambda:retrolambda-maven-plugin:2.3.0:process-main (default) on project android-j8-backport-2-app: Failed to run Retrolambda: NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal net.orfjackal.retrolambda:retrolambda-maven-plugin:2.3.0:process-main (default) on project android-j8-backport-2-app: Failed to run Retrolambda
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: Failed to run Retrolambda
    at net.orfjackal.retrolambda.maven.ProcessClassesMojo.processClassesInCurrentProcess(ProcessClassesMojo.java:136)
    at net.orfjackal.retrolambda.maven.ProcessClassesMojo.execute(ProcessClassesMojo.java:106)
    at net.orfjackal.retrolambda.maven.ProcessMainClassesMojo.execute(ProcessMainClassesMojo.java:17)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    ... 20 more
Caused by: java.lang.NullPointerException
    at net.orfjackal.retrolambda.asm.Type.getObjectType(Type.java:228)
    at net.orfjackal.retrolambda.interfaces.ClassInfo.<init>(ClassInfo.java:33)
    at net.orfjackal.retrolambda.interfaces.ClassAnalyzer.analyze(ClassAnalyzer.java:27)
    at net.orfjackal.retrolambda.interfaces.ClassAnalyzer.analyze(ClassAnalyzer.java:23)
    at net.orfjackal.retrolambda.Retrolambda$1.visitClass(Retrolambda.java:56)
    at net.orfjackal.retrolambda.files.ClasspathVisitor.visitFile(ClasspathVisitor.java:29)
    at net.orfjackal.retrolambda.files.ClasspathVisitor.visitFile(ClasspathVisitor.java:11)
    at java.nio.file.Files.walkFileTree(Files.java:2670)
    at java.nio.file.Files.walkFileTree(Files.java:2742)
    at net.orfjackal.retrolambda.Retrolambda.visitFiles(Retrolambda.java:92)
    at net.orfjackal.retrolambda.Retrolambda.run(Retrolambda.java:53)
    at net.orfjackal.retrolambda.maven.ProcessClassesMojo.processClassesInCurrentProcess(ProcessClassesMojo.java:134)
    ... 24 more

This only occurs for java.lang.Object. Having just a quick look (excuse me for being not very deep about it) I discovered that org.objectweb.asm.Type.getObjectType just cannot accept null. So the ClassInfo(ClassReader) constructor should not invoke that method with null and, probably, since I'm not really sure, its superclass should just be null. The build passes if adding the NPE check to the ClassInfo(ClassReader) constructor and then building using the 2.3.1-SNAPSHOT version. Dumping the patched java.lang.Object class gives the following result:

$ hexdump target/classes/java/lang/Object.class | head -1
0000000 feca beba 0000 3200 5e00 0001 6a10 7661

It looks like RetroLambda has downgraded its byte code from 34 to 32. Sorry can't prove the experiment succeeds in the future, but this seems to beat the NPE.

@lyubomyr-shaydariv lyubomyr-shaydariv changed the title Fixed NPE in ClassInfo accepting java.lang.Object Fix NullPointerException in ClassInfo accepting java.lang.Object Nov 8, 2016
@luontola luontola merged commit 5069d30 into luontola:master Jan 10, 2017
@luontola
Copy link
Owner

This has been included in Retrolambda 2.4.0. Sorry about taking so long to merge.

@lyubomyr-shaydariv
Copy link
Contributor Author

lyubomyr-shaydariv commented Jan 11, 2017

@orfjackal No problem, I'm glad you've accepted and merged it! And thank you for the great tool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants