记一次SpringContextHolder.getBean出现异常NoClassDefFoundError: Could not initialize class
代码如下:
public class TestUtils {
private static UserDao logDao = SpringContextHolder.getBean(UserDao.class);
public static String getLog(String type){
return "!23";
}
}
在controller中使用这Utils的时候出现如下错误:
奇怪的是在容器中又能得到UserDao,为何初始化这个TestUtils的时候就失败了呢。
经过一番排查,发现项目启动的时候有这么一段日志
2019-10-29 15:36:22.839 WARN 21948 --- [ main] o.mybatis.spring.SqlSessionFactoryBean : Cannot load the 'file [D:\*\utils\TestUtils.class]'. Cause by java.lang.NoClassDefFoundError: Could not initialize class com.*.utils.TestUtils
所以觉得是mybatis的问题,mybaits在扫描所有entity的时候逻辑(mybatis-spring-boot-starter是2.1.1对应的mybatis-spring的版本2.0.3)
if (hasLength(this.typeAliasesPackage)) {
scanClasses(this.typeAliasesPackage, this.typeAliasesSuperType).stream()
.filter(clazz -> !clazz.isAnonymousClass()).filter(clazz -> !clazz.isInterface())
.filter(clazz -> !clazz.isMemberClass()).forEach(targetConfiguration.getTypeAliasRegistry()::registerAlias);
}
private Set<Class<?>> scanClasses(String packagePatterns, Class<?> assignableType) throws IOException {
Set<Class<?>> classes = new HashSet<>();
String[] packagePatternArray = tokenizeToStringArray(packagePatterns,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
for (String packagePattern : packagePatternArray) {
//会先扫描出所有typeAliasesPackage下面所有的类
Resource[] resources = RESOURCE_PATTERN_RESOLVER.getResources(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(packagePattern) + "/**/*.class");
for (Resource resource : resources) {
try {
ClassMetadata classMetadata = METADATA_READER_FACTORY.getMetadataReader(resource).getClassMetadata();
//此时会先加载这个类,加载类的时候里面的静态属性会初始化,但是此时容器中还有UserDao的Bean实例,所以导致初始化失败,触发异常
Class<?> clazz = Resources.classForName(classMetadata.getClassName());
//此时才判断superType
if (assignableType == null || assignableType.isAssignableFrom(clazz)) {
classes.add(clazz);
}
} catch (Throwable e) {
LOGGER.warn(() -> "Cannot load the '" + resource + "'. Cause by " + e.toString());
}
}
}
return classes;
}
上面就是导致出现问题的原因。
看了一下之前的项目,逻辑一样,但为啥没出现问题呢,发现之前项目引用的mybatis-spring-boot-starter是1.3.2版本,对应的mybatis-spring的版本的1.3.2。
那么里面的实现是怎么样呢?为何没出现类似的错误呢?
if (hasLength(this.typeAliasesPackage)) {
String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
for (String packageToScan : typeAliasPackageArray) {
configuration.getTypeAliasRegistry().registerAliases(packageToScan,
typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Scanned package: '" + packageToScan + "' for aliases");
}
}
}
public void registerAliases(String packageName, Class<?> superType){
ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
//会先过滤superType
resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();
for(Class<?> type : typeSet){
// Ignore inner classes and interfaces (including package-info.java)
// Skip also inner classes. See issue #6
if (!type.isAnonymousClass() && !type.isInterface() && !type.isMemberClass()) {
registerAlias(type);
}
}
}
两个解决办法:
1.降低mybatis-spring-boot-starter 的版本到(经测试mybatis-spring.jar的2.0.0及以下版本都可以,其他版本没看源码)
2.精确指定到entity的目录(建议此,减少扫描和遍历的次数)
记一次SpringContextHolder.getBean出现异常NoClassDefFoundError: Could not initialize class的更多相关文章
- 异常:Caused by: java.lang.NoClassDefFoundError: Could not initialize class net.sf.log4jdbc.Properties
参考文章: 使用Log4jdbc-log4j2监听MyBatis中运行的SQL和Connection 使用 log4jdbc格式化输出SQL,maven配置如下: <dependency> ...
- Java 上传文件到 SFTP 抛异常 java.lang.NoClassDefFoundError: Could not initialize class sun.security.ec.SunEC 的解决办法
最近从 Op 那里报来一个问题,说是SFTP上传文件不成功.拿到的 Exception 如下: Caused by: java.lang.NoClassDefFoundError: Could not ...
- 异常-----java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.core.KeyFactory
SSH 类库问题 java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer2009- ...
- 日志异常:java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.impl.StaticLoggerBinder
今天启动开发的项目,碰到了一个日志上的bug:java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.impl.Sta ...
- 验证码无法显示,服务器端出现异常:Could not initialize class sun.awt.X11GraphicsEnvironment
异常信息: Caused by: java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11GraphicsEnvir ...
- hibernate 解决 java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.internal.engine.xxx 这类的问题
<!-- 解决 java.lang.NoClassDefFoundError: Could not initialize class org.hibernate.validator.intern ...
- @Autowired注解和静态方法 NoClassDefFoundError could not initialize class 静态类
NoClassDefFoundError could not initialize class 静态类 spring boot 静态类 java.lang.ExceptionInInitializer ...
- java.lang.NoClassDefFoundError: Could not initialize class异常处理
借鉴:http://blog.csdn.net/sleepdancer/article/details/9207425 static { InputStream in = XXX.class.getR ...
- weblogic .NoClassDefFoundError: Could not initialize class sun.awt.X11Graphi
这个是常见问题,可以通过增加Weblogic的启动参数来解决: -Djava.awt.headless=true 你可以修改 startWebLogic.sh 文件. export JAVA_OPTI ...
随机推荐
- Layui学习笔记(一)—— 关于模块的扩展
在使用layui的时候,总有官方自带模块不够用想自己扩展的时候,这时候我们就需要扩展模块了. 模块扩展有两种: (一)普通地扩展 layui.define( function (exports) { ...
- vue + elementui 使用多选按钮实现单选功能
CommonRadio.vue <template> <div> <el-checkbox-group v-model="checkList" @ch ...
- Flask之基础
一,flask Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求 ...
- Flink 原理(六)——异步I/O(asynchronous I/O)
1.前言 本文是基于Flink官网上Asynchronous I/O的介绍结合自己的理解写成的,若有不正确的欢迎大伙留言交流,谢谢! 2.Asynchronous I/O简介 将Flink用于流计 ...
- LFS7.10——构造临时Linux系统
参考:LFS编译——准备Host系统 前言 在准备好Host环境后,接下来构造一个临时Linux系统.该系统包含****构建所需要的工具.构造临时Linux系统分两步: 构建一个宿主系统无关的新工具链 ...
- 解决zabbix_web显示中文乱码问题
zabbix图形中文显示设置 如果想将zabbix的界面改成中文,点击类似于管理员头像,可以直接修改 检测中---图形,却显示乱码,这个问题是由于zabbix的web端没有中文字库,我们最需要把中文字 ...
- GCC使用总结
概念 GCC一开始是linux系统集成的用来编译C程序的编译器(GNU C Compiler),目前GCC已经不仅仅支持C语言了,因而其缩写名单意义也变成(GNU Compiler Collectio ...
- mysql技术内幕--innodb存储引擎图解
1. Innodb存储引擎 2. Innodb文件 3. Innodb表 4. Innodb事务 5. innodb索引与算法 6 ...
- git 如何忽略已经加入到版本控制的文件
增加 .gitignore 文件,里面添加需要忽略的文件(file_not_wanted): 执行命令 git rm -r --cached . 注意,最后的点.不要省略. 最后重新将所有文件添加 ...
- Kotlin属性揭秘与延迟初始化特性
在上一次https://www.cnblogs.com/webor2006/p/11210181.html学习了Kotlin的伴生对象,这次来学习属性相关的东东. 属性揭秘: 先声明一个属性: 没啥可 ...