[MAGNOLIA-8958] Guice method interceptions fails with "Unsupported class file major version 61" on JRE 17 Created: 16/Jun/23 Updated: 16/Jan/24 Resolved: 28/Jun/23 |
|
| Status: | Closed |
| Project: | Magnolia |
| Component/s: | None |
| Affects Version/s: | 6.2.35 |
| Fix Version/s: | 6.2.37 |
| Type: | Bug | Priority: | Neutral |
| Reporter: | Michael Duerig | Assignee: | Michael Duerig |
| Resolution: | Done | Votes: | 0 |
| Labels: | maintenance | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Template: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Acceptance criteria: |
Empty
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Task DoD: |
[X]*
Doc/release notes changes? Comment present?
[X]*
Downstream builds green?
[X]*
Solution information and context easily available?
[X]*
Tests
[X]*
FixVersion filled and not yet released
[ ] 
Architecture Decision Record (ADR)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bug DoR: |
[X]*
Steps to reproduce, expected, and actual results filled
[X]*
Affected version filled
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Testcase included: |
Yes
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Release notes required: |
Yes
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Date of First Response: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Team: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Work Started: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Approved: |
Yes
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description |
Steps to reproducepublic class InterceptorTest { interface Base<T>{ void foo(T arg); } // Inheriting from a parametrized base class causes the JVM to generate a bridge method, which in // turn will trigger the code path in bindInterceptor() that leads to the problem. public static class Impl implements Base<String > { @Override public void foo(String arg) { } } @Test void test() { Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bindInterceptor( Matchers.any(), Matchers.any(), invocation -> null ); bind(Impl.class); } }); } } Compile and run InterceptorTest with Java 17. Note: it is not clear how to automate this test as Magnolia 6.2 does not compile and build against Java 17 currently. Expected resultsThe test passes. Actual resultsThe test fails: com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalArgumentException: Unsupported class file major version 61 at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2051) at com.google.common.cache.LocalCache.get(LocalCache.java:3951) at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974) at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4958) at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4964) at com.google.inject.internal.FailableCache.get(FailableCache.java:51) at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:48) at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:155) at com.google.inject.internal.InjectorImpl.initializeBinding(InjectorImpl.java:581) at com.google.inject.internal.AbstractBindingProcessor$Processor$1.run(AbstractBindingProcessor.java:176) at com.google.inject.internal.ProcessedBindingData.initializeBindings(ProcessedBindingData.java:49) at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:122) at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106) at com.google.inject.Guice.createInjector(Guice.java:87) at com.google.inject.Guice.createInjector(Guice.java:69) at com.google.inject.Guice.createInjector(Guice.java:59) at info.magnolia.addon.commons.cache.InterceptorTest.test(InterceptorTest.java:37) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229) at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197) at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 61 at com.google.inject.internal.asm.$ClassReader.<init>(ClassReader.java:184) at com.google.inject.internal.asm.$ClassReader.<init>(ClassReader.java:166) at com.google.inject.internal.asm.$ClassReader.<init>(ClassReader.java:152) at com.google.inject.internal.asm.$ClassReader.<init>(ClassReader.java:273) at com.google.inject.internal.cglib.core.$DuplicatesPredicate.<init>(DuplicatesPredicate.java:93) at com.google.inject.internal.cglib.proxy.$Enhancer.getMethods(Enhancer.java:557) at com.google.inject.internal.cglib.proxy.$Enhancer.getMethods(Enhancer.java:535) at com.google.inject.internal.ProxyFactory.<init>(ProxyFactory.java:87) at com.google.inject.internal.ConstructorInjectorStore.createConstructor(ConstructorInjectorStore.java:82) at com.google.inject.internal.ConstructorInjectorStore.access$000(ConstructorInjectorStore.java:29) at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:37) at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:33) at com.google.inject.internal.FailableCache$1.load(FailableCache.java:40) at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) ... 81 more WorkaroundUse Java 11. Development notes
Root cause analysisThe is caused by Guice 4.2.2's shaded version of asm not being compatible with Java 17. In ClassFileReader it checks the class file version and fails: if (checkClassVersion && this.readShort(classFileOffset + 6) > 58) { throw new IllegalArgumentException("Unsupported class file major version " + this.readShort(classFileOffset + 6)); } To fix this we need to upgrade to Guice 5.1.0. See DEV-2014 for the related effort on 6.3. |