JDK从8升级到10时出现java.rmi.ServerError异常求助
Hey there, I’ve run into this exact issue when migrating older RMI-based apps to JDK 9+, so let’s break down what’s happening and how to fix it.
The Root Cause
JDK 8 and earlier kept java.sql.Timestamp (and most core classes) in the global classpath, so RMI could easily find them. But starting with JDK 9, the Java Platform Module System (JPMS) split the JDK into discrete modules. java.sql.Timestamp lives in the java.sql module now, and if your RMI server (or client) doesn’t explicitly declare access to this module, the JVM will throw that NoClassDefFoundError.
Step-by-Step Solutions
1. If Your App is Modular (Uses module-info.java)
If you’ve already migrated to a modular project, update your module-info.java to:
module com.yourcompany.yourrmi { // Declare dependency on the java.sql module requires java.sql; // Allow RMI to reflectively access your service classes (critical for RMI) opens com.yourcompany.yourrmi.service to java.rmi; // If your service returns objects that use Timestamp, you might also need: exports com.yourcompany.yourrmi.dto to java.rmi; }
requires java.sqlgives your module access to all classes in thejava.sqlmodule, includingTimestamp.opensis mandatory for RMI, since it uses reflection to serialize/deserialize objects across the network.
2. If Your App is Non-Modular (Traditional Classpath)
If you haven’t moved to modules yet, add JVM arguments when starting your RMI server to expose the java.sql module to the unnamed classpath:
# Option 1: Add the entire java.sql module to the runtime java --add-modules java.sql -jar your-rmi-server.jar # Option 2: Explicitly export the java.sql package to the unnamed module java --add-exports java.sql/java.sql=ALL-UNNAMED -jar your-rmi-server.jar
Either of these will make java.sql.Timestamp accessible to your RMI code running on the classpath.
3. Check Client-Side Compatibility
If your RMI client is still on JDK 8, you shouldn’t hit issues (since Timestamp is in the core classpath there), but make sure:
- The client has the same version of the serialized classes as the server.
- You’re not using any JDK 10+ exclusive APIs in the objects being passed over RMI.
4. Avoid Classpath/Module Path Conflicts
Double-check that you’re not mixing --classpath and --module-path in your startup commands unless you intentionally need to. Mixing them can cause unexpected class resolution issues.
Quick Verification
After applying the fix, start your server and test the RMI call. If the NoClassDefFoundError goes away, you’re good to go. If you still see issues, check if other JDK modules are missing (like java.rmi itself, though that’s usually included by default).
内容的提问来源于stack exchange,提问作者Clite lzy

