missingresourceexception 是运行时抛出的 runtimeexception,表示 resourcebundle.getbundle() 未找到或无法加载指定资源文件(如 messages.properties),常见于路径错误、locale 不匹配、编码不兼容(如 utf-8 中文未转义)或 classpath 未包含资源。

MissingResourceException 是什么错误
它不是编译报错,而是运行时抛出的 RuntimeException,说明程序在调用 ResourceBundle.getBundle() 时,根本没找到对应资源文件(.properties),或者找到了但加载失败。常见现象是启动就崩、i18n 文字全变乱码或 key 名本身(比如显示 login.title 而不是“登录”)。
检查 classpath 下资源路径是否匹配 bundleName
ResourceBundle.getBundle("messages") 不会去找 messages.properties 文件,而是按规则拼路径:messages → messages_en_US.properties → messages_en.properties → messages.properties,且必须在 classpath 根目录或对应包路径下。
容易踩的坑:
- 把
messages.properties放在src/main/resources/i18n/,却用getBundle("i18n.messages")—— 正确写法是getBundle("i18n.messages")对应i18n/messages.properties,不是i18n/messages_en.properties - IDE 编译后没把
.properties复制进target/classes/(Maven 默认会,但 Gradle 或手动构建可能漏) - 文件名含空格或中文,比如
消息配置.properties—— JVM 加载器不认,必须是合法标识符命名 + UTF-8 无 BOM
验证默认 Locale 和 fallback 行为
ResourceBundle.getBundle() 默认用当前 Locale.getDefault() 查找,比如系统设成 zh_CN,就会先找 messages_zh_CN.properties;找不到才退到 messages_zh.properties,再退到 messages.properties。但如果你只提供了 messages_en.properties,而环境是中文,就会直接抛 MissingResourceException。
立即学习“Java免费学习笔记(深入)”;
实操建议:
- 调试时显式传入 Locale:
ResourceBundle.getBundle("messages", Locale.ENGLISH),快速确认是不是 Locale 导致的 - 确保存在无语言后缀的 base 文件(如
messages.properties),它是所有 Locale 的兜底 - 不要依赖
Locale.getDefault()做测试 —— 它随操作系统/IDE/JVM 启动参数变化,CI 环境常是en_US
字符编码和文件格式问题
Java 6+ 的 ResourceBundle 默认用 ISO-8859-1 解析 .properties 文件,哪怕你用 UTF-8 保存,中文也会变乱码,甚至导致解析失败、触发 MissingResourceException(因为 key 找不到)。
解决方案只有两个:
- 用
native2ascii工具转义中文(如\u4F60\u597D),然后存为 ISO-8859-1 编码 —— 过时但最兼容 - 改用
PropertyResourceBundle手动读取 UTF-8 流:new PropertyResourceBundle(new InputStreamReader( Thread.currentThread().getContextClassLoader() .getResourceAsStream("messages.properties"), "UTF-8")),绕过getBundle()的编码限制
注意:IntelliJ 默认新建 .properties 是 UTF-8,但 Maven Resources 插件若没配 encoding,打包时可能损坏内容;Gradle 更要确认 processResources 的 encoding = "UTF-8"。
最常被忽略的是:异常堆栈里 MissingResourceException 的 message 很简陋,只说“Can't find bundle”,真正线索其实在 cause(比如 IOException 或 IllegalArgumentException)—— 一定要看完整 stack trace,别只扫第一行。









