Spring Boot升级后部署报错:无法访问MongoClientDelegate类
Spring Boot升级后MongoDB部署报错问题
我正在将Spring Boot应用从2.2.7.RELEASE版本升级至2.6.7.RELEASE版本,当前应用使用spring-data-mongodb 2.2.12.RELEASE和mongodb-java-driver 3.8.2。应用构建成功,但部署时出现报错,核心为java.lang.IllegalAccessError:无法从com.mongodb.Mongo类访问com.mongodb.client.internal.MongoClientDelegate类。
报错堆栈
java.lang.IllegalStateException: Error starting child at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:729) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:698) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1024) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1911) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:825) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:475) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1667) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:315) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1162) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1365) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1369) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1347) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/DOPE-OP-web]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726) ... 24 more Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoFactory' defined in class path resource [eai-app-profile.xml]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.SimpleMongoDbFactory]: Constructor threw exception; nested exception is java.lang.IllegalAccessError: failed to access class com.mongodb.client.internal.MongoClientDelegate from class com.mongodb.Mongo (com.mongodb.client.internal.MongoClientDelegate and com.mongodb.Mongo are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @2c785774) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:315) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:296) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5219) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ... 25 more Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.core.SimpleMongoDbFactory]: Constructor threw exception; nested exception is java.lang.IllegalAccessError: failed to access class com.mongodb.client.internal.MongoClientDelegate from class com.mongodb.Mongo (com.mongodb.client.internal.MongoClientDelegate and com.mongodb.Mongo are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @2c785774) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311) ... 47 more Caused by: java.lang.IllegalAccessError: failed to access class com.mongodb.client.internal.MongoClientDelegate from class com.mongodb.Mongo (com.mongodb.client.internal.MongoClientDelegate and com.mongodb.Mongo are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @2c785774) at com.mongodb.Mongo.<init>(Mongo.java:319) at com.mongodb.Mongo.<init>(Mongo.java:308) at com.mongodb.Mongo.<init>(Mongo.java:304) at com.mongodb.MongoClient.<init>(MongoClient.java:326) at org.springframework.data.mongodb.core.SimpleMongoDbFactory.<init>(SimpleMongoDbFactory.java:48) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211) ... 49 more
依赖配置
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>2.2.12.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>2.6.3</version> </dependency>
MongoConfig代码
public class MongoConfig implements FactoryBean<MongoClientURI> { private String uri; @Value("${mongo_socketTimeout}") private int socketTimeout; @Value("${mongo_uri}") public void setUri(String uri) { this.uri = uri; } @Override public MongoClientURI getObject() throws Exception { return new MongoClientURI(uri, MongoClientOptions.builder().socketTimeout(socketTimeout)); } @Override public Class<?> getObjectType() { return MongoClientURI.class; } @Override public boolean isSingleton() { return true; } }
解决方案
问题原因
- 依赖版本不匹配:Spring Boot 2.6.7.RELEASE对应的spring-data-mongodb版本应为3.3.4.RELEASE,当前使用的2.2.12.RELEASE版本过低,与升级后的Spring Boot版本不兼容。
- MongoDB驱动版本冲突:mongodb-java-driver 3.8.2与高版本Spring Data MongoDB存在内部类访问权限问题,
com.mongodb.client.internal.MongoClientDelegate是MongoDB驱动内部类,低版本驱动配合高版本Spring Data时会出现访问权限异常。 - spring-data-commons版本不一致:spring-data-commons 2.6.3与spring-data-mongodb 2.2.12.RELEASE版本不匹配,Spring Data体系内各模块版本需保持统一。
解决步骤
- 移除手动指定的版本依赖:利用Spring Boot的依赖管理机制自动匹配兼容版本,修改依赖配置如下:
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> </dependency>
Spring Boot 2.6.7.RELEASE对应的spring-data-mongodb为3.3.4.RELEASE,spring-data-commons为2.6.7.RELEASE。
- 升级MongoDB驱动:使用Spring Boot管理的mongodb-driver-sync(原mongodb-java-driver拆分后的模块),版本为4.4.3:
<dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-sync</artifactId> </dependency>
- 更新MongoConfig配置类:适配新版本API,替换过时的
MongoClientURI和MongoClientOptions:
import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.annotation.Value; public class MongoConfig implements FactoryBean<MongoClientSettings> { @Value("${mongo_uri}") private String uri; @Value("${mongo_socketTimeout}") private int socketTimeout; @Override public MongoClientSettings getObject() throws Exception { return MongoClientSettings.builder() .applyConnectionString(new ConnectionString(uri)) .socketSettings(com.mongodb.connection.SocketSettings.builder() .socketTimeout(socketTimeout) .build()) .build(); } @Override public Class<?> getObjectType() { return MongoClientSettings.class; } @Override public boolean isSingleton() { return true; } }
同时调整mongoFactory配置,使用MongoClientSettings创建SimpleMongoDbFactory,或直接使用Spring Boot自动配置的MongoDB Bean。
- 清理依赖并重新构建:执行
mvn clean install清理旧依赖缓存,确保所有依赖版本兼容。
内容的提问来源于stack exchange,提问作者Prem
相关产品推荐
相关产品推荐

