OBS依赖冲突
简单介绍一下NoClassDefFoundError
JVM在编译的过程中可以找到合适的类,但是在运行阶段找不到合适的类就会导致抛出NoClassDefFoundError异常。
NoClassDefFound异常大致会出现两种情况:
- 无法找到类文件,错误信息:NoClassDefFoundError:com/obs/service/ObsClient
- 类文件初始化错误,错误信息:NoClassDefFoundError:could not * *
与之类似地一种异常是ClassNotFoundException
产生的原因是,由于Java支持使用Class.forName方法来动态地加载类,任意一个类的类名如果被作为参数传递给这个方法都将导致该类被加载到JVM内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时抛出ClassNotFoundException异常。
报错的代码片段是:
public String generatePresignedUrl(String objectName) {
if (StringUtils.isNotBlank(objectName)) {
String accessKeyId = obsConf.getAccessKeyId();
String accessKeySecret = obsConf.getAccessKeySecret();
String endpoint = obsConf.getEndpoint();
String downloadBucket = obsConf.getDownloadBucket();
ObsClient obsClient = null;
try {
//这里报错
obsClient = new ObsClient(accessKeyId, accessKeySecret, endpoint);
TemporarySignatureRequest temporarySignatureRequest = new TemporarySignatureRequest();
temporarySignatureRequest.setMethod(HttpMethodEnum.GET);
temporarySignatureRequest.setBucketName(downloadBucket);
temporarySignatureRequest.setObjectKey(objectName);
TemporarySignatureResponse temporarySignature = obsClient.createTemporarySignature(temporarySignatureRequest);
return temporarySignature.getSignedUrl();
} catch (Exception e) {
throw new BusinessException(ErrorCode.BIZ_OBS_OPERATE_ERROR,
String.format(ErrorMsg.BIZ_OBS_OPERATE_EXCEPTION_PATTERN, e.getMessage()));
} finally {
if (null != obsClient) {
try {
obsClient.close();
} catch (IOException ex) {
log.error(ex.getMessage());
}
}
}
}
return null;
}
异常信息是:
NoClassDefFoundError:Could not initialize class com.obs.service.ObsClient
本地运行过程中,初次运行时,报的是另一个错误(但是没在意)
at com.obs.log.LoggerBuilder$GetLoggerHolder.(LoggerBuilder.java:31)
at com.obs.log.LoggerBuilder.getLogger(LoggerBuilder.java:51)
at com.obs.log.LoggerBuilder.getLogger(LoggerBuilder.java:62)
ClassNotFoundException: org.apache.logging.log4j.spi.LoggerContextShutdownAware
最开始考虑是,可能disConf配置信息没有加载成功,查看日志发现obs的配置信息成功加载,排除这个可能。
查询obs的官网提供的解决方案,刚好可以查到
依赖缺失和依赖冲突的解决方案
引入的包:
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java-bundle</artifactId>
<version>3.21.12</version>
</dependency>
由于我是直接使用的Bundle包,可以排除多种第三方包依赖冲突的问题(除log4j外)
那么几乎可以确定问题症结所在了,应该是log4j包的问题
查看External library引入的log4j相关的包,发现log4j-api和log4j-core的版本不统一,问题症结所在,将log4j版本统一,问题修复。