使用 Spring-native (Spring-boot3.0.5),我尝试覆盖
ClassPathBeanDefinitionScanner
类,但在使用 AOT 时出现运行时错误。
我定义了一个扩展的新类
ClassPathBeanDefinitionScanner
:
lang=java
public class RpcComponentScanner extends ClassPathBeanDefinitionScanner {
public RpcComponentScanner(BeanDefinitionRegistry registry) {
super(registry);
}
public void registerDefaultFilters() {
this.addIncludeFilter(new AnnotationTypeFilter(MyRPCService.class));
}
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
return beanDefinitions;
}
// ....... other codes
}
并实施
BeanFactoryPostProcessor
;当 Spring 应用程序启动时,该类将调用 RpcComponentScanner.scan()
。
@Component
public class RpcComponentProcesser implements BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String basePackage ="com.demo";// value is "com.demo"
if (!(beanFactory instanceof BeanDefinitionRegistry)){
return;
}
RpcComponentScanner scanner = new RpcComponentScanner((BeanDefinitionRegistry) beanFactory);
scanner.setResourceLoader(applicationContext);
scanner.scan(RpcConstants.COMMA_SPLIT_PATTERN.split(basePackage));// This line runs success in JVM,but failed in AOT.The code compile successful with graalvm,but startup with exceptions
}
// ....... other codes
}
我已经在
RpcComponentProcesser
类中注册了RpcComponentScanner
和MyRPCService
、RuntimeHints
,它实现了RuntimeHintsRegistrar
。
详细异常日志为:
java.lang.IllegalStateException: Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:206) ~[na:na]
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:138) ~[na:na]
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.scan(ClassPathBeanDefinitionScanner.java:258) ~[nbs-bootstrap.exe:6.0.7]
at com.tplink.ignite.rpc.processer.RpcComponentProcesser.postProcessBeanFactory(RpcComponentProcesser.java:61) ~[nbs-bootstrap.exe:na]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358) ~[na:na]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:201) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:747) ~[nbs-bootstrap.exe:6.0.7]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565) ~[nbs-bootstrap.exe:6.0.7]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[nbs-bootstrap.exe:3.0.5]
at com.tplink.ignite.platform.cms.CmsApplication.main(CmsApplication.java:48) ~[nbs-bootstrap.exe:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
at [email protected]/java.lang.Class.forName(DynamicHub.java:1132) ~[nbs-bootstrap.exe:na]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:283) ~[na:na]
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:202) ~[na:na]
... 14 common frames omitted
16:37:41.885 [main] INFO c.t.i.p.c.bootstrap.SpringTrigger - ......... server start error.........
java.lang.IllegalStateException: Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:206) ~[na:na]
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:138) ~[na:na]
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.scan(ClassPathBeanDefinitionScanner.java:258) ~[nbs-bootstrap.exe:6.0.7]
at com.tplink.ignite.rpc.processer.RpcComponentProcesser.postProcessBeanFactory(RpcComponentProcesser.java:61) ~[nbs-bootstrap.exe:na]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358) ~[na:na]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:201) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:747) ~[nbs-bootstrap.exe:6.0.7]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565) ~[nbs-bootstrap.exe:6.0.7]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[nbs-bootstrap.exe:3.0.5]
at com.tplink.ignite.platform.cms.CmsApplication.main(CmsApplication.java:48) ~[nbs-bootstrap.exe:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
at [email protected]/java.lang.Class.forName(DynamicHub.java:1132) ~[nbs-bootstrap.exe:na]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:283) ~[na:na]
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:202) ~[na:na]
... 14 common frames omitted
16:37:41.895 [main] ERROR o.s.boot.SpringApplication - Application run failed
java.lang.IllegalStateException: Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:206) ~[na:na]
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:138) ~[na:na]
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.scan(ClassPathBeanDefinitionScanner.java:258) ~[nbs-bootstrap.exe:6.0.7]
at com.tplink.ignite.rpc.processer.RpcComponentProcesser.postProcessBeanFactory(RpcComponentProcesser.java:61) ~[nbs-bootstrap.exe:na]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:358) ~[na:na]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:201) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:747) ~[nbs-bootstrap.exe:6.0.7]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565) ~[nbs-bootstrap.exe:6.0.7]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[nbs-bootstrap.exe:3.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[nbs-bootstrap.exe:3.0.5]
at com.tplink.ignite.platform.cms.CmsApplication.main(CmsApplication.java:48) ~[nbs-bootstrap.exe:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
at [email protected]/java.lang.Class.forName(DynamicHub.java:1132) ~[nbs-bootstrap.exe:na]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:283) ~[na:na]
at org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:202) ~[na:na]
... 14 common frames omitted
当我删除此行时:
scanner.scan(RpcConstants.COMMA_SPLIT_PATTERN.split(basePackage));
应用程序运行成功。
那是因为
PersistenceAnnotationBeanPostProcessor
需要运行时功能,例如反射和动态代理生成。
首先,我会尝试使用 GraalVM 跟踪代理,如果它没有帮助,您可以尝试将其替换为 Spring Native 中的另一个
BeanPostProcessor
。
了解更多: