根本原因是类路径、字符编码、依赖版本、main方法签名及模块配置在IDE与命令行间不一致:IDE自动管理而命令行需手动精确配置。

命令行运行报 NoClassDefFoundError 但IDE能跑通
根本原因通常是类路径(CLASSPATH)不一致。IDE(如IntelliJ或Eclipse)自动把 src、resources、所有依赖 JAR、输出目录(out/production 或 target/classes)都加进类路径;而命令行默认只认当前目录,且不会自动扫描子目录或 JAR。
- 检查命令行是否漏了
-cp或--class-path,例如:java -cp "target/classes:target/dependency/*" com.example.Main(Linux/macOS)或java -cp "target\classes;target\dependency\*" com.example.Main(Windows) - 注意
mvn exec:java和直接java命令的类路径机制完全不同:前者由 Maven 插件组装,后者完全手动控制 - IDE 可能启用了「Build project automatically」,而命令行用的是旧的 class 文件——删掉
target/classes或out/后重新编译再试
中文乱码:命令行显示 ??? 而IDE正常
这是字符编码不匹配导致的,核心在「源文件编码」「编译器编码」「终端/控制台编码」三者未对齐。Java 源文件若含中文,javac 默认按系统编码读取,而 Windows CMD 默认是 GBK,Linux 终端多为 UTF-8,IDE 却通常强制设为 UTF-8 并透传给编译器。
- 编译时显式指定编码:
javac -encoding UTF-8 src/com/example/Main.java - 运行时也建议加参数:
java -Dfile.encoding=UTF-8 com.example.Main(否则String.getBytes()等操作可能出错) - Windows 用户尤其注意:CMD 默认不支持 UTF-8,可执行
chcp 65001切换,或改用 PowerShell / WSL - Maven 项目需在
pom.xml中配置,否则UTF-8 mvn compile会忽略源码编码声明
依赖版本冲突:IDE用的是Maven管理的jar,命令行却加载了旧版或系统jar
IDE 隐式隔离了构建环境,而命令行容易误用全局 JAVA_HOME/jre/lib/ext 下的 JAR,或从 CLASSPATH 环境变量中意外引入老版本(比如 Hadoop 自带的旧版 Guava)。
- 运行前先清空
CLASSPATH环境变量:unset CLASSPATH(Linux/macOS)或set CLASSPATH=(Windows) - 避免用
java -jar app.jar同时又设Class-Path:在 MANIFEST.MF 里——它优先级低于命令行-cp,但容易被忽略 - 用
java -verbose:class观察类实际从哪加载,例如看到[Loaded java.util.ArrayList from /path/to/jdk/jre/lib/rt.jar]是正常的,但[Loaded com.google.common.collect.Lists from /usr/share/java/guava.jar]就可能有问题
main方法签名或启动类名写错:IDE自动识别入口,命令行严格校验
IDE 能通过注解(如 @SpringBootApplication)、Maven 插件配置(exec.mainClass)或图形界面选择来绕过传统 public static void main(String[] args) 的显式调用;命令行则必须精确匹配方法签名、访问修饰符、类名拼写和包路径。
立即学习“Java免费学习笔记(深入)”;
- 确认类名是完整限定名(
com.example.Main),不是文件名(Main.java) - 检查是否漏了
static或写成String... args——JVM 只认String[] args形式(尽管语义等价,但字节码签名不同) - 如果用了模块系统(
module-info.java),命令行需加--module-path和--module,IDE 可能已自动补全
CLASSPATH 里混进了旧版 log4j,再配上一个拼错的启动类名——这时候单看任一现象都像独立问题,实际得逐层剥离验证。










