mybatis-plus
mybatis-plus copied to clipboard
Spring-Native 打包后运行报错,请问有这方面的例子吗?
06:39:40.950 [main] INFO org.springframework.boot.SpringApplication - AOT mode enabled,
2021-11-03 06:39:40.964 INFO 1 --- [ main] o.s.nativex.NativeListener : This application is bootstrapped with code generated with Spring AOT,
,
. ____ _ __ _ _,
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \,
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \,
\\/ ___)| |_)| | | | | || (_| | ) ) ) ),
' |____| .__|_| |_|_| |_\__, | / / / /,
=========|_|==============|___/=/_/_/_/,
:: Spring Boot :: (v2.6.0-RC1),
,
2021-11-03 06:39:40.966 INFO 1 --- [ main] c.b.m.s.q.QuickstartApplication : Starting QuickstartApplication using Java 11.0.13 on 1a65476b9eca with PID 1 (/workspace/com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication started by cnb in /workspace),
2021-11-03 06:39:40.966 DEBUG 1 --- [ main] c.b.m.s.q.QuickstartApplication : Running with Spring Boot v2.6.0-RC1, Spring v5.3.12,
2021-11-03 06:39:40.966 INFO 1 --- [ main] c.b.m.s.q.QuickstartApplication : No active profile set, falling back to default profiles: default,
2021-11-03 06:39:40.968 ERROR 1 --- [ main] o.s.boot.SpringApplication : Application run failed,
,
java.lang.ExceptionInInitializerError: null,
at org.mybatis.spring.mapper.MapperScannerConfigurer.postProcessBeanDefinitionRegistry(MapperScannerConfigurer.java:357) ~[com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication:2.0.6],
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[na:na],
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:142) ~[na:na],
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[na:na],
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[na:na],
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[na:na],
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:719) ~[com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication:2.6.0-RC1],
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:401) ~[com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication:2.6.0-RC1],
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication:2.6.0-RC1],
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290) ~[com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication:2.6.0-RC1],
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1279) ~[com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication:2.6.0-RC1],
at com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication.main(QuickstartApplication.java:12) ~[com.baomidou.mybatisplus.samples.quickstart.QuickstartApplication:na],
Caused by: org.apache.ibatis.logging.LogException: Error creating logger for logger org.mybatis.spring.mapper.ClassPathMapperScanner. Cause: java.lang.NullPointerException,
at org.apache.ibatis.logging.LogFactory.getLog(LogFactory.java:54) ~[na:na],
at org.apache.ibatis.logging.LogFactory.getLog(LogFactory.java:47) ~[na:na],
at org.mybatis.logging.LoggerFactory.getLogger(LoggerFactory.java:32) ~[na:na],
at org.mybatis.spring.mapper.ClassPathMapperScanner.<clinit>(ClassPathMapperScanner.java:58) ~[na:na],
... 12 common frames omitted,
Caused by: java.lang.NullPointerException: null,
at org.apache.ibatis.logging.LogFactory.getLog(LogFactory.java:52) ~[na:na],
... 15 common frames omitted,
不支持反射吧。 我记得是需要配置文件指定下要反射类信息的
不支持反射吧。 我记得是需要配置文件指定下要反射类信息的
是的呢!自己一个个去找太麻烦了。
https://github.com/mybatis/mybatis-3/issues/1552 是 mybatis 不支持吧
mybatis/mybatis-3#1552 是 mybatis 不支持吧
这个也看过,好像是的,就是不知道怎么解决。mybatis 不能用,微服务项目就暂时没法用 spring-native了。有合适的解决方案吗?
@Lee27149 跟你一样的报错,请问你解决了吗? 报错的这个地方我看了下源码,应该不能通过配置反射信息来解决吧 因为它本身就是动态传参来创建的 配置不了, org.apache.ibatis.logging.LogFactory中: public static Log getLog(String logger) { try { return logConstructor.newInstance(logger); // 这里报错 } catch (Throwable t) { throw new LogException("Error creating logger for logger " + logger + ". Cause: " + t, t); } } 。。。。 private static void setImplementation(Class<? extends Log> implClass) { try { Constructor<? extends Log> candidate = implClass.getConstructor(String.class); Log log = candidate.newInstance(LogFactory.class.getName()); if (log.isDebugEnabled()) { log.debug("Logging initialized using '" + implClass + "' adapter."); } logConstructor = candidate; // 就是因为这个反射没成功,logConstructor才空指针 } catch (Throwable t) { throw new LogException("Error setting Log implementation. Cause: " + t, t); } }
@Lee27149 我的解决办法是使用svm的targetClass, substitue,替代上面那段源码的getLog方法,亲测可行
@Lee27149 我的解决办法是使用svm的targetClass, substitue,替代上面那段源码的getLog方法,亲测可行
解决了?
很可惜几乎所有的库或多或少都用到了反射 不过graalvm好像有工具可以生成配置文件
这个自定义 reflect-config.json, 增加 { "name": "org.apache.ibatis.logging.slf4j.Slf4jImpl", "allDeclaredFields": true, "allDeclaredConstructors": true, "allDeclaredMethods": true, "allPublicMethods": true, "allDeclaredClasses": true }, { "name": "org.slf4j.Marker", "allDeclaredFields": true, "allDeclaredConstructors": true, "allDeclaredMethods": true, "allPublicMethods": true, "allDeclaredClasses": true } 配置就可以了
这个自定义 reflect-config.json, 增加 { "name": "org.apache.ibatis.logging.slf4j.Slf4jImpl", "allDeclaredFields": true, "allDeclaredConstructors": true, "allDeclaredMethods": true, "allPublicMethods": true, "allDeclaredClasses": true }, { "name": "org.slf4j.Marker", "allDeclaredFields": true, "allDeclaredConstructors": true, "allDeclaredMethods": true, "allPublicMethods": true, "allDeclaredClasses": true } 配置就可以了
Hi, I want to ask if you can explain it in detail? It would be great if you can submit a DEMO to https://github.com/mybatis/spring-boot-starter/tree/master/mybatis-spring-boot-samples .
mybatis/mybatis-3#1552 是 mybatis 不支持吧
这个也看过,好像是的,就是不知道怎么解决。mybatis 不能用,微服务项目就暂时没法用 spring-native了。有合适的解决方案吗?
This problem has been preliminarily solved by Mybatis maintainer. Would you like to try integration in Mybatis Plus at an early stage? Of course, XML files are currently supported now. Related to this link is
- https://github.com/kazuki43zoo/mybatis-spring-native
- https://github.com/mybatis/spring/issues/635
- https://twitter.com/kazuki43zoo/status/1478423774446092289?t=LiNmFCnz2Ib2Vbv_UVKOyA&s=19
https://github.com/mybatis/mybatis-3/pull/1611 mybatis 新版本是支持得
https://github.com/mybatis/mybatis-3/pull/1611 mybatis 新版本是支持得
No, to this day Mybatis full support for GraalVM is still a problem. The issue is on it.
https://github.com/kazuki43zoo/mybatis-spring-native
和spring集成只能手动集成, 自己集成mybati-plus 的 SQLSessionFactory等. 这样是可以的. 但是使用wrapper的时候有一些反射类型转换的问题. 当前版本的graalvm还不支持. 只能等等了. 或者mp改实现方式
Such as https://github.com/spring-projects-experimental/spring-native/issues/404#issuecomment-1026324672, Mybatis officially supports Spring Native, and I think it's easier than ever for us to move this process forward.
mp中的LambdaQuery会动态生成Lambda类. 这些类会被反射调用其writeReplace
/**
* 该缓存可能会在任意不定的时间被清除
*
* @param func 需要解析的 lambda 对象
* @param <T> 类型,被调用的 Function 对象的目标类型
* @return 返回解析后的结果
*/
public static <T> LambdaMeta extract(SFunction<T, ?> func) {
// 1. IDEA 调试模式下 lambda 表达式是一个代理
if (func instanceof Proxy) {
return new IdeaProxyLambdaMeta((Proxy) func);
}
// 2. 反射读取
try {
Method method = func.getClass().getDeclaredMethod("writeReplace");
return new ReflectLambdaMeta((SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
} catch (Throwable e) {
// 3. 反射失败使用序列化的方式读取
return new ShadowLambdaMeta(com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda.extract(func));
}
}
这些类如何在编译期间被graalvm 构建? 类似于
Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: SerializationConstructorAccessor class not found for declaringClass: cn.xxx.platform.xxx.web.TestController$$Lambda$8344ef4bacd60313614e73f8916982c06ef20243 (targetConstructorClass: java.lang.Object). Usually adding cn.xxx.platform.xxx.web.TestController$$Lambda$8344ef4bacd60313614e73f8916982c06ef20243 to serialization-config.json fixes the problem.
at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89) ~[na:na]
https://github.com/quarkiverse/quarkus-mybatis/issues/184 这个问题已经解决. 对与spring native 可以增加serialization-config.json
类似于:
{
"types": [
{
"name": "com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda"
},
{
"name": "com.baomidou.mybatisplus.core.toolkit.support.SFunction"
}
],
"lambdaCapturingTypes": [
{
"name": "cn.nvriot.platform.geocoding.web.TestController"
}
]
}
``` 可以解决LambdaMeta 的问题.
@siaron 不知道能否提供一个完整的案例,迫切希望能收到你的回答。
-
spring-native has gone into maintenance, and this issue should be closed and marked invalid.
-
Anyone with requests for the use of mybatis-plus in GraalVM Native Image, Should submit
mybatis-plus
GraalVM reachability metadata on the https://github.com/oracle/graalvm-reachability-metadata .
quarkiverse/quarkus-mybatis#184
https://github.com/quarkiverse/quarkus-mybatis/issues/184
看下这个issue. 里面有demo. 不过是quarkus. springboot3.0 还没测试过.
#5527 统一至此处讨论.