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

Support for CGLIB BeanMap utility on JDK 17 #27802

Closed
livk-cloud opened this issue Dec 11, 2021 · 5 comments
Closed

Support for CGLIB BeanMap utility on JDK 17 #27802

livk-cloud opened this issue Dec 11, 2021 · 5 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@livk-cloud
Copy link

I put the problem in MD

@livk-cloud livk-cloud changed the title JDK JDK17 And SpringBoot-3.0.0-SNAPSHOT Dec 11, 2021
@livk-cloud
Copy link
Author

SpringBoot
version: 3.0.0-SNAPSHOT
environment: Oracle JDK17 Win10 Maven-3.8.4
problem: {@org.springframework.cglib.beans.BeanMap}
example:

public class BeanMapTest {
    public static void main(String[] args) {
        var livkBean = new LivkBean(1, "1");
        var beanMap = BeanMap.create(livkBean);
        System.out.println(beanMap);
    }
}

record LivkBean(int id, String msg) {

}

Exception:

Exception in thread "main" org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @233c0b17
	at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:525)
	at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363)
	at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)
	at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)
	at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
	at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
	at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134)
	at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319)
	at org.springframework.cglib.beans.BeanMap$Generator.create(BeanMap.java:127)
	at org.springframework.cglib.beans.BeanMap.create(BeanMap.java:59)
	at com.livk.spring.beanmap.BeanMapTest.main(BeanMapTest.java:16)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @233c0b17
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
	at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
	at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:494)
	... 12 more

Process finished with exit code 1

JDK17 prohibits reflection of java.base package
Hope to fix it soon
problem.md

@snicoll snicoll transferred this issue from spring-projects/spring-boot Dec 11, 2021
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 11, 2021
@livk-cloud
Copy link
Author

livk-cloud commented Dec 16, 2021

I upgraded to 6.0.0-M1,but this problem is still not resolved

`public class BeanMapTest {
public static void main(String[] args) {
var bean = new Bean(1, "1");
var beanMap = BeanMap.create(bean);
System.out.println(beanMap);
}
}

record Bean(int n, String msg) {

}`

`Exception in thread "main" org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @270421f5
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:525)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319)
at org.springframework.cglib.beans.BeanMap$Generator.create(BeanMap.java:127)
at org.springframework.cglib.beans.BeanMap.create(BeanMap.java:59)
at BeanMapTest.main(BeanMapTest.java:14)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @270421f5
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:494)
... 12 more

Process finished with exit code 1
`

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>6.0.0-M1</version> </dependency>
@spring-projects-issues

@jhoeller
Copy link
Contributor

This issue seems to be pretty specifically about the BeanMap utility in CGLIB which we are not specifically supporting yet. The problem there is the lack of a contextClass on the class generator which is needed for JDK 9+ compliant class definitions. You could try the following for the time being:

BeanMap.Generator gen = new BeanMap.Generator();
gen.setBean(bean);
gen.setContextClass(bean.getClass());
BeanMap beanMap = gen.create();

We can do this out of the box in a patched version of the standard CGLIB BeanMap class. I'll adapt this issue title accordingly. However, please note that we might also decide to drop the BeanMap utility from our repackaged CGLIB fork completely.

@jhoeller jhoeller changed the title JDK17 And SpringBoot-3.0.0-SNAPSHOT Support for CGLIB BeanMap utility on JDK 17 Dec 16, 2021
@jhoeller jhoeller self-assigned this Dec 16, 2021
@jhoeller jhoeller added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Dec 16, 2021
@jhoeller jhoeller added this to the 6.0.x milestone Dec 16, 2021
@livk-cloud
Copy link
Author

livk-cloud commented Jan 19, 2022

I found that adding the burningwave package solved the problem

github:

maven

<dependency>
            <groupId>org.burningwave</groupId>
            <artifactId>core</artifactId>
            <version>12.41.2</version>
        </dependency>

code

StaticComponentContainer.Modules.exportAllToAll();
        User user = new User();
        user.setId(0);
        user.setUsername("livk");
        user.setPassword("123456");
        @SuppressWarnings("unchecked")
        Map<String, Object> beanMap = BeanMap.create(user);
        System.out.println(beanMap);

@spring-projects-issues

Will this package be added to Spring-core?

@janeisklar
Copy link

I am unfortunately still seeing this issue with M5 and created a new ticket with a small project to reproduce the issue: #28860

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants