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

Easymock is not compatible with JDK 22 #547

Open
lprimak opened this issue Mar 22, 2024 · 4 comments
Open

Easymock is not compatible with JDK 22 #547

lprimak opened this issue Mar 22, 2024 · 4 comments

Comments

@lprimak
Copy link

lprimak commented Mar 22, 2024

Hi,

Just want to let you know that EasyMock tests are not working with JDK 22.
Most likely, the shaded bytebuddy (and asm?) needs to be upgraded.

[INFO] Running org.apache.shiro.guice.web.PathMatchingFilterProviderTest
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.231 s <<< FAILURE! -- in org.apache.shiro.guice.web.PathMatchingFilterProviderTest
[ERROR] org.apache.shiro.guice.web.PathMatchingFilterProviderTest.testPostProcess -- Time elapsed: 0.229 s <<< ERROR!
java.lang.IllegalArgumentException: Could not create type
	at org.easymock.bytebuddy.TypeCache.findOrInsert(TypeCache.java:170)
	at org.easymock.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
	at org.easymock.internal.ClassProxyFactory.createProxy(ClassProxyFactory.java:151)
	at org.easymock.internal.MocksControl.createMock(MocksControl.java:110)
	at org.easymock.internal.MocksControl.createMock(MocksControl.java:83)
	at org.easymock.IMocksControl.mock(IMocksControl.java:44)
	at org.easymock.EasyMock.mock(EasyMock.java:70)
	at org.easymock.EasyMock.createMock(EasyMock.java:322)
	at org.apache.shiro.guice.web.PathMatchingFilterProviderTest.testPostProcess(PathMatchingFilterProviderTest.java:37)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1597)
Caused by: java.lang.IllegalArgumentException: org.apache.shiro.web.filter.PathMatchingFilter$$$EasyMock$1 must be defined in the same package as org.easymock.internal.ClassProxyFactory
	at org.easymock.bytebuddy.dynamic.loading.ClassInjector$UsingLookup.injectRaw(ClassInjector.java:1635)
	at org.easymock.bytebuddy.dynamic.loading.ClassInjector$AbstractBase.inject(ClassInjector.java:118)
	at org.easymock.bytebuddy.dynamic.loading.ClassLoadingStrategy$UsingLookup.load(ClassLoadingStrategy.java:519)
	at org.easymock.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
	at org.easymock.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6325)
	at org.easymock.internal.ClassProxyFactory.lambda$createProxy$0(ClassProxyFactory.java:161)
	at org.easymock.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
	... 11 more

Thank you

@lprimak
Copy link
Author

lprimak commented Mar 22, 2024

Blocks apache/shiro#1381

@lprimak
Copy link
Author

lprimak commented Apr 11, 2024

@henri-tremblay Any ideas please?
Thank you!

@InforBG
Copy link

InforBG commented Apr 30, 2024

Get the same error testing EasyMock 5.2.0 with JDK 22 or 22.0.1.
Investigate the codes and see the original error in org.easymock.bytebuddy.dynamic.loading.ClassInjector.UsingUnsafe.Dispatcher.CreationAction#run is:

java.lang.IllegalArgumentException: Java 22 (66) is not supported by the current version of Byte Buddy which officially supports Java 21 (65) - update Byte Buddy or set org.easymock.bytebuddy.experimental as a VM property

It is similar to raphw/byte-buddy#1609. Tried to use the latest byte-buddy/byte-buddy-agent 1.14.14 and unfortunately it doesn't work for EasyMock.

		<version.bytebuddy>1.14.14</version.bytebuddy>
			<dependency>
				<groupId>net.bytebuddy</groupId>
				<artifactId>byte-buddy</artifactId>
				<version>${version.bytebuddy}</version>
				<scope>test</scope>
			</dependency>
			<dependency>
				<groupId>net.bytebuddy</groupId>
				<artifactId>byte-buddy-agent</artifactId>
				<version>${version.bytebuddy}</version>
				<scope>test</scope>
			</dependency>

It seems that EasyMock is copy bytebuddy codes into the EasyMock bundle?

  1. It will try to get the Java version 22 from class java.lang.reflect.AccessibleObject.
  2. The org.easymock.bytebuddy.ClassFileVersion#latest method will always return JAVA_V21. Why it is hardcoded?
    public static ClassFileVersion latest() {
        return ClassFileVersion.JAVA_V21;
    }
  1. Then org.easymock.bytebuddy.utility.OpenedClassReader#of compare the 22 and 21, and throw out the exception.
    public static ClassReader of(byte[] binaryRepresentation) {
        ClassFileVersion classFileVersion = ClassFileVersion.ofClassFile(binaryRepresentation), latest = ClassFileVersion.latest();
        if (classFileVersion.isGreaterThan(latest)) {
            if (EXPERIMENTAL) {
                binaryRepresentation[6] = (byte) (latest.getMajorVersion() >>> 8);
                binaryRepresentation[7] = (byte) latest.getMajorVersion();
                ClassReader classReader = new ClassReader(binaryRepresentation);
                binaryRepresentation[6] = (byte) (classFileVersion.getMajorVersion() >>> 8);
                binaryRepresentation[7] = (byte) classFileVersion.getMajorVersion();
                return classReader;
            } else {
                throw new IllegalArgumentException(classFileVersion
                        + " is not supported by the current version of Byte Buddy which officially supports " + latest
                        + " - update Byte Buddy or set " + EXPERIMENTAL_PROPERTY + " as a VM property");
            }
        } else {
            return new ClassReader(binaryRepresentation);
        }
    }

From my view, there is no workaround except set the system property org.easymock.bytebuddy.experimental=true. But it looks not very good.
Need someone to update the EasyMock to use the latest ByteBuddy.
Please let me know if you find anything I missed. Thanks.

@henri-tremblay
Copy link
Contributor

I will ASAP. I am shading ByteBuddy and ASM because previously, not shading Cglib and ASM was causing a lot of headaches from people using the wrong version. But these frameworks are quite stable now so I probably can remove the shading.

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

No branches or pull requests

3 participants