从MySQL迁移至MongoDB Cloud时连接失败,抛出NoClassDefFoundError异常求助
首先,你遇到的java.lang.NoClassDefFoundError: com/mongodb/MongoClient错误,核心原因有两个:
- 你的Bukkit插件项目没有正确包含MongoDB Java驱动的依赖,导致服务器的类加载器找不到对应的类;
- 你使用的
new MongoClient()是旧版MongoDB驱动的API,在新版驱动中已经被弃用,甚至可能不在默认的包路径里了。
下面是分步骤的解决方案:
1. 确保添加正确的MongoDB驱动依赖
MongoDB的Java驱动分同步、异步等版本,对于你的Bukkit插件场景,推荐使用同步驱动(mongodb-driver-sync),它包含了所有连接所需的核心类。
如果你用Maven构建项目
在pom.xml中添加以下依赖(可以替换为最新的稳定版本,比如4.11.1):
<dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver-sync</artifactId> <version>4.11.1</version> <scope>compile</scope> </dependency>
如果你用Gradle构建
在build.gradle中添加:
implementation 'org.mongodb:mongodb-driver-sync:4.11.1'
手动导入Jar包的情况
从MongoDB官网下载以下三个Jar包,放到项目的依赖目录中:
- mongodb-driver-sync.jar
- mongodb-driver-core.jar
- bson.jar
2. 修正连接代码(使用新版API)
旧的com.mongodb.MongoClient类在新版驱动中已经被标记为过时,并且推荐使用MongoClients.create()方法来创建客户端实例。同时,旧的getDB()方法也应该替换为getDatabase()(属于MongoDatabase接口,更符合新版API规范)。
修正后的代码示例:
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoCollection; import org.bson.Document; public boolean connect() { try { // 注意:把`yourActualPassword`替换成你实际的数据库密码,如果密码有特殊字符(如@、&)要做URL编码 String connectionString = "mongodb+srv://root:yourActualPassword@provincecluster.ms1am.mongodb.net/?retryWrites=true&w=majority"; // 使用新版客户端创建方式 MongoClient client = MongoClients.create(connectionString); // 获取数据库(替换旧的getDB方法) MongoDatabase mcserverdb = client.getDatabase("ProvinceDB"); // 获取集合(泛型指定Document,新版API规范) MongoCollection<Document> players = mcserverdb.getCollection("ProvinceCollection"); System.out.println("Connected to Database!"); // 保存client实例供后续操作使用 this.client = client; return true; } catch (Exception e) { System.out.println("Could not connect to database!"); e.printStackTrace(); return false; } }
3. 关键:Bukkit插件必须打包依赖到Jar中
Bukkit/Spigot的类加载机制比较特殊,如果只是添加依赖但没有把MongoDB驱动的类打包到你的插件Jar里,服务器运行时会找不到这些类。
Maven用户配置Shade插件
在pom.xml的build > plugins中添加Shade插件配置,它会把依赖的类合并到你的插件Jar中,并且可以重命名MongoDB的包路径,避免和其他插件的依赖冲突:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <relocations> <!-- 重命名MongoDB相关包,替换成你的插件包路径 --> <relocation> <pattern>org.bson</pattern> <shadedPattern>me.moritz.mongodb.bson</shadedPattern> </relocation> <relocation> <pattern>com.mongodb</pattern> <shadedPattern>me.moritz.mongodb.mongo</shadedPattern> </relocation> </relocations> </configuration> </execution> </executions> </plugin>
配置完成后,运行mvn package,生成的Jar包就包含了所有MongoDB驱动的类。
Gradle用户配置Shadow插件
如果用Gradle,可以使用Shadow插件来打包依赖,在build.gradle中添加:
plugins { id 'com.github.johnrengelman.shadow' version '7.1.2' } shadowJar { // 重命名包避免冲突 relocate 'org.bson', 'me.moritz.mongodb.bson' relocate 'com.mongodb', 'me.moritz.mongodb.mongo' } // 让build任务自动执行shadowJar build.dependsOn shadowJar
运行./gradlew build生成包含依赖的Jar包。
额外注意事项
- 如果你的数据库密码包含特殊字符(如
@、&、!等),需要对密码进行URL编码,比如pass@word要改成pass%40word; - 确保你的MongoDB Atlas集群已经把服务器的IP地址加入到白名单中,否则即使代码正确也会连接失败(不过你的错误是类找不到,所以这个是后续可能遇到的问题)。
内容的提问来源于stack exchange,提问作者Moritz L.

