如何在install4j的自定义代码JAR中添加本地化文件?
问题:install4j自定义代码JAR中本地化消息无法加载
我正在开发一个JAR形式的库,要作为install4j项目的「Custom Code(自定义代码)」使用。需求是:库内使用的本地化消息优先定义在库本身,但允许install4j项目中的定义覆盖这些消息。
已尝试的操作:
- 将Context对象传入库的相关函数,通过
context.getMessage("my-message-key")获取翻译文本 - 把包含对应键的本地化文件
messages_en.utf8放到库JAR内的messages文件夹中 - 将该JAR添加到install4j的「Custom Code」区域
执行后抛出异常:
java.util.MissingResourceException: Can't find resource for bundle com.install4j.runtime.util.FileResourceBundle, key my-message-key
如果把同一个JAR放到install4j安装目录的extensions文件夹作为扩展使用,消息键能被正确识别,代码运行正常。但这种方式需要给团队每台开发机和构建服务器都配置,库更新时还要重复操作,所以更倾向于用「Custom Code」的方案。请问操作哪里出了问题?
问题原因及解决办法
原因分析
install4j的资源束查找机制对「Custom Code」和「extensions」的处理不同:
- 放到
extensions目录的JAR会被install4j自动扫描,其内部的资源束会被加入到install4j全局资源查找路径中,所以context.getMessage()能找到对应的键 - 作为「Custom Code」添加的JAR,install4j只会加载其中的类,但不会将其资源束纳入全局查找路径,因此
context.getMessage()只会去查找install4j项目本身定义的消息,找不到库JAR里的内容
解决办法
不要依赖context.getMessage()直接加载库内的消息,而是手动用库自身的类加载器加载资源束,同时保留install4j项目消息的覆盖优先级:
- 先尝试通过
context.getMessage()获取消息(如果install4j项目中定义了该键,优先使用) - 若抛出
MissingResourceException,再加载库JAR内的资源束
示例代码:
public String getLocalizedMessage(Context context, String key) { try { // 优先使用install4j项目中定义的消息 return context.getMessage(key); } catch (MissingResourceException e) { // 加载库自身的本地化资源,使用库的类加载器确保能找到JAR内的文件 ResourceBundle bundle = ResourceBundle.getBundle( "messages.messages", context.getLocale(), getClass().getClassLoader() ); return bundle.getString(key); } }
注意事项
- 确保库JAR内的资源文件路径正确:如果你的
messages_en.utf8在messages文件夹下,资源束的基名就是messages.messages(对应类路径下的messages/messages_en.utf8) - 资源文件的命名要符合Java ResourceBundle的规范,比如
messages_en.utf8、messages_zh_CN.utf8等
内容的提问来源于stack exchange,提问作者Denis Lohner
相关产品推荐
相关产品推荐

