[seata]GlobalTransactionScanner#wrapIfNecessary在springboot3下无法代理导致启动失败

2024-05-09 796 views
9
环境:

**JDK:17 springboot:3.0.5 springcloud: 2022.0.2 springcloud-alibaba:2022.0.0.0-RC1

seata-all:1.6.1**

问题描述:

启动微服务客户端报错(集成了)

java.lang.reflect.InaccessibleObjectException: Unable to make field protected java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.h accessible: module java.base does not "opens java.lang.reflect" to unnamed module

在getBean初始化调用applyBeanPostProcessorsAfterInitialization时 如果当前类为代理类(已被AnnotationAwareAspectJAutoProxyCreator#applyBeanPostProcessorsAfterInitialization增强过) 调用GlobalTransactionScanner#applyBeanPostProcessorsAfterInitialization再次代理时 通过SpringProxyUtils.findInterfaces获取接口信息(内部getAdvisedSupport会反射protected java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.h) 调用h.setAccessible(true); 即出现jdk模块化后无法直接反射内部模块错误

期望解惑

目前我手动注入了GlobalTransactionScanner并设置了Order为最高优先级,让GlobalTransactionScanner在AnnotationAwareAspectJAutoProxyCreator执行后就不不会出现该问题;

  1. 希望能告知此问题产生的原因;如果不是bug:我该怎么解决这个问题
  2. 我这个解决方案有效吗,会影响事务内部代理的机制不

谢谢各位~

回答

1

“集成了“,那里我想说的是nacos、sentinel、dynamic-datasource、mybatis-plus来着

5

例如mybatis mapper代理类被jdk aop代理过一次然后GlobalTransactionScanner再次代理时

  1. 执行AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
  2. 执行AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization
  3. 执行GlobalTransactionScanner#postProcessAfterInitialization
  4. 执行SpringProxyUtils#findInterfaces出现以下异常
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sysUserMapper': Post-processing of FactoryBean's singleton object failed
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:108)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1823)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1273)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:336)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789)
    ... 17 common frames omitted
    Caused by: java.lang.RuntimeException: java.lang.reflect.InaccessibleObjectException: Unable to make field protected java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.h accessible: module java.base does not "opens java.lang.reflect" to unnamed module @644baf4a
    at io.seata.spring.annotation.GlobalTransactionScanner.wrapIfNecessary(GlobalTransactionScanner.java:322)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:318)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:434)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1885)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:105)
    ... 26 common frames omitted
    Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field protected java.lang.reflect.InvocationHandler java.lang.reflect.Proxy.h accessible: module java.base does not "opens java.lang.reflect" to unnamed module @644baf4a
    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.Field.checkCanSetAccessible(Field.java:178)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
    at io.seata.spring.util.SpringProxyUtils.getAdvisedSupport(SpringProxyUtils.java:94)
    at io.seata.spring.util.SpringProxyUtils.findInterfaces(SpringProxyUtils.java:64)
    at io.seata.spring.annotation.GlobalTransactionScanner.wrapIfNecessary(GlobalTransactionScanner.java:289)
    ... 30 common frames omitted

将以上BeanPostProcessor(第二步第三步)调换就没有这个问题:

  1. 执行AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
  2. 执行GlobalTransactionScanner#postProcessAfterInitialization
  3. 执行AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization
  4. 执行SpringProxyUtils#findInterfaces出现以下异常
3

1.7.0-native-rc2版本修复了SpringProxyUtils#getAdvisedSupport

3

我也遇到这个问题了,终于解决了,谢谢楼主老哥。

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.seata</groupId>
                <artifactId>seata-spring-boot-starter</artifactId>
                <version>1.7.0-native-rc2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>