java.lang.NoClassDefFoundError: org/springframework/expression/spel/CompilablePropertyAccessor异常分析

一、报错代码

java.lang.NoClassDefFoundError: org/springframework/expression/spel/CompilablePropertyAccessor

Caused by: java.lang.ClassNotFoundException: org.springframework.expression.spel.CompilablePropertyAccessor

java.lang.NoClassDefFoundError: org/springframework/expression/spel/CompilablePropertyAccessor
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at org.springframework.data.mongodb.core.convert.MappingMongoConverter.<init>(MappingMongoConverter.java:123)
        at org.springframework.data.mongodb.core.MongoTemplate.getDefaultMongoConverter(MongoTemplate.java:2537)
        at org.springframework.data.mongodb.core.MongoTemplate.<init>(MongoTemplate.java:231)
        at org.springframework.data.mongodb.core.MongoTemplate.<init>(MongoTemplate.java:207)
        at com.awen.utils.MongodbUtils.createMongoTemplate(MongodbUtils.java:35)
        ......
Caused by: java.lang.ClassNotFoundException: org.springframework.expression.spel.CompilablePropertyAccessor
        at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 78 common frames omitted

二、报错截图

异常截图

三、报错原因

spring-contextspring-expression jar包版本不兼容,导致spring-expression包中的org.springframework.expression.spel.CompilablePropertyAccessor类找不到。

四、代码调用过程及查错思路

从开始报错的地方开始说代码的调用过程,只说与报错相关的代码。

step1:创建MongoTemplate对象

报错截图中有个第35行代码的提示,而第35行代码是创建MongoTemplate对象,进去这个构造方法里看看。

public static MongoTemplate createMongoTemplate(String databaseName) {
    int mongoPort = 27017;
    String mongoHost = "127.0.0.1";
    String mongoUserName = "awen";
    String mongoDataBase = "mongotest";
    String mongoPassword = "123456";

    // 初始化用户名,数据库名,密码
    MongoCredential credential = MongoCredential.createCredential(mongoUserName, mongoDataBase, mongoPassword.toCharArray());
    // 连接地址
    ServerAddress addr = new ServerAddress(mongoHost, mongoPort);
    // auth 连接
    MongoClient mongoClient =  new MongoClient(addr, Arrays.asList(credential));
    MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, databaseName);  // 第35行代码
    return mongoTemplate;
}
step2:调用重载的MongoTemplate构造方法,其方法内部第180行给MongoConverter mongoConverter变量赋值。

getDefaultMongoConverter()方法报错截图里有这行代码提示,进去看看。
MongoTemplate.class

step3:调用MongoTemplate.getDefaultMongoConverter()方法。

方法内部调用new MappingMongoConverter()构造方法,报错截图中有这段代码提示,进去看看。
MongoTemplate.getDefaultMongoConverter()

step4:调用MappingMongoConverter()方法。

方法内部调用DocumentPropertyAccessor.INSTANCE常量,进去这个类看看。
MappingMongoConverter.class

step5:声明初始化DocumentPropertyAccessor.INSTANCE常量。

DocumentPropertyAccessor类继承了MapAccessor类,进去这个类看看。
DocumentPropertyAccessor.class

step6:MapAccessor实现了CompliablePropertyAccessor接口。

CompliablePropertyAccessor接口正是报错的根本原因。
前面的步骤都还在spring-data-mongodb包里,step6就跳到了spring-context包,而CompliablePropertyAccessor接口是在spring-expression包里。
报错原因是因为在spring-expression包里找不到CompliablePropertyAccessor接口。
MapAccessor.class

五、解决方案

根据代码调用步骤可知,发生错误的地方在于MapAccessor类实现的CompliablePropertyAccessor接口找不到。而MapAccessor在spring-context包里,CompliablePropertyAccessor接口在spring-expression包里。

方案一:降低spring-context版本

修改为spring-context-4.1.6.RELEASE以下版本可以使用。
spring-context-4.1.6版本,MapAccessor类实现的是PropertyAccessor接口,而spring-expression里有PropertyAccessor接口。
spring=context-4.1.6
原来用的是spring-context-5.0.10版本的,MapAccessor类实现的是CompliablePropertyAccessor接口,而spring-expression包里没有这个接口,从而导致了类未找到错误。
spring-context-5.0.10

方案二:提高spring-expression版本

修改为spring-expression-5.0.10版本的可以用。
4.0.5以下版本应该不能用,因为没有CompliablePropertyAccessor接口。

六、总结

spring-context和spring-expression使用的版本尽量一致,可以避免异常。
异常分析及总结

猜你喜欢

转载自blog.csdn.net/awen6666/article/details/105585276