Skip to content

Commit

Permalink
The hack for modifying a final field doesn't work on Java 12 and newer
Browse files Browse the repository at this point in the history
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal net.orfjackal.retrolambda:retrolambda-maven-plugin:2.5.7-SNAPSHOT:process-main (default) on project end-to-end-tests: 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:120)
	at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:355)
	at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:155)
	at org.apache.maven.cli.MavenCli.execute(MavenCli.java:584)
	at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:216)
	at org.apache.maven.cli.MavenCli.main(MavenCli.java:160)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	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:161)
	at net.orfjackal.retrolambda.maven.ProcessClassesMojo.execute(ProcessClassesMojo.java:133)
	at net.orfjackal.retrolambda.maven.ProcessMainClassesMojo.execute(ProcessMainClassesMojo.java:17)
	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
	... 19 more
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at net.orfjackal.retrolambda.maven.ProcessClassesMojo.processClassesInCurrentProcess(ProcessClassesMojo.java:157)
	... 23 more
Caused by: java.lang.IllegalStateException: Cannot initialize dumper; unexpected JDK implementation. Please run Retrolambda using the Java agent (enable forking in the Maven plugin).
	at net.orfjackal.retrolambda.lambdas.LambdaClassDumper.install(LambdaClassDumper.java:38)
	at net.orfjackal.retrolambda.Retrolambda.run(Retrolambda.java:67)
	at net.orfjackal.retrolambda.Retrolambda.run(Retrolambda.java:25)
	... 28 more
	Suppressed: java.lang.RuntimeException: java.lang.IllegalAccessException: class net.orfjackal.retrolambda.lambdas.LambdaClassDumper cannot access a member of class java.lang.invoke.InnerClassLambdaMetafactory (in module java.base) with modifiers "private static final"
		at net.orfjackal.retrolambda.lambdas.LambdaClassDumper.uninstall(LambdaClassDumper.java:48)
		at net.orfjackal.retrolambda.lambdas.LambdaClassDumper.close(LambdaClassDumper.java:55)
		at net.orfjackal.retrolambda.Retrolambda.run(Retrolambda.java:102)
		... 29 more
	Caused by: java.lang.IllegalAccessException: class net.orfjackal.retrolambda.lambdas.LambdaClassDumper cannot access a member of class java.lang.invoke.InnerClassLambdaMetafactory (in module java.base) with modifiers "private static final"
		at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:376)
		at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:639)
		at java.base/java.lang.reflect.Field.checkAccess(Field.java:1075)
		at java.base/java.lang.reflect.Field.set(Field.java:778)
		at net.orfjackal.retrolambda.lambdas.LambdaClassDumper.uninstall(LambdaClassDumper.java:46)
		... 31 more
Caused by: java.lang.NoSuchFieldException: modifiers
	at java.base/java.lang.Class.getDeclaredField(Class.java:2416)
	at net.orfjackal.retrolambda.lambdas.LambdaClassDumper.makeNonFinal(LambdaClassDumper.java:59)
	at net.orfjackal.retrolambda.lambdas.LambdaClassDumper.install(LambdaClassDumper.java:32)
	... 30 more
  • Loading branch information
luontola committed Jan 23, 2020
1 parent 0842425 commit e62c38b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 12 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ yourself or pay someone to do it, if you think it's worth the effort. ;)
Version History
---------------

### Upcoming

- Improved error messages for Java 12 and newer, which have been confirmed
to not work without the Java agent

### Retrolambda 2.5.6 (2018-11-30)

- Fix a `NullPointerException` crash in the Maven plugin on Java 10 & 11
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2013-2014 Esko Luontola <www.orfjackal.net>
// Copyright © 2013-2020 Esko Luontola and other Retrolambda contributors
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

Expand Down Expand Up @@ -56,10 +56,16 @@ public void close() {
}

private static void makeNonFinal(Field field) throws Exception {
Field modifiers = field.getClass().getDeclaredField("modifiers");
modifiers.setAccessible(true);
int mod = modifiers.getInt(field);
modifiers.setInt(field, mod & ~Modifier.FINAL);
try {
Field modifiers = field.getClass().getDeclaredField("modifiers");
modifiers.setAccessible(true);
int mod = modifiers.getInt(field);
modifiers.setInt(field, mod & ~Modifier.FINAL);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Failed to make a field non-final (" + field + "). " +
"This known to fail on Java 12 and newer. Prefer using Java 8 or try using the Java agent " +
"(fork=true in the Maven plugin).", e);
}
}

private static Object newProxyClassesDumper(Path dumpDir) throws Exception {
Expand Down
8 changes: 1 addition & 7 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,7 @@ JAVA_HOME="$JAVA11_HOME" mvn clean verify \
--errors \
| tee build.log && check_build_log

JAVA_HOME="$JAVA12_HOME" mvn clean verify \
--errors \
| tee build.log && check_build_log

JAVA_HOME="$JAVA13_HOME" mvn clean verify \
--errors \
| tee build.log && check_build_log
# (Java 12+ fails without forking because java.lang.invoke.InnerClassLambdaMetafactory#dumper cannot be made non-final)

# Make sure that the Java agent works on all new Java versions

Expand Down

2 comments on commit e62c38b

@csoroiu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a way for jdk 12 & 13 to make a field non-final using VarHandle.
The code to do it is explained here: https://stackoverflow.com/a/56043252/2749648

@luontola
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pointer.

Please sign in to comment.