我必须依赖第三方库,它希望某些事情在类路径中。好像用了
ResourceBundle.getBundle("cmbcmenv");
获取属性文件。此文件的位置由安装连接器时设置的环境变量指定(它创建一个指向包含该文件的目录的变量“IBMCMROOT”)。我不能在类路径中使用相对路径或绝对路径,因为连接器的安装目录可能会有所不同。
我尝试过像这样手动添加新的ClassLoader:
ClassLoader defaultLoader = Thread.currentThread().getContextClassLoader();
String config = System.getenv().get("IBMCMROOT")+"/cmgmt";
URLClassLoader loader = URLClassLoader.newInstance(new URL[]{new File(config).toURI().toURL()},defaultLoader);
Thread.currentThread().setContextClassLoader(loader);
getBundle也失败了。由于它是第三方库,我不能使用
ResourceBundle.getBundle("cmbcmenv",Locale.getDefault(),loader);
否则不会有这个问题..
如何强制ResourceBundle使用特定的ClassLoader?似乎getBundle使用CallerClassloader或SystemClassloader但是没有办法影响它,对吧?
答案 0 :(得分:1)
您可以欺骗ResourceBundle
类使用与用于密钥中实际查找的ClassLoader
不同的ResourceBundle rb=ResourceBundle.getBundle("Resources", new ResourceBundle.Control() {
@Override
public long getTimeToLive(String baseName, Locale locale) {
return Long.MAX_VALUE;
}
@Override
public ResourceBundle newBundle(String baseName, Locale locale,
String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
return super.newBundle(baseName, locale, format, defaultLoader, reload);
}
});
来缓存捆绑包实例。
getBundle
请注意,ClassLoader
调用使用的是默认的SystemClassLoader(或调用者ClassLoader
),因为没有指定类加载器。这是用于缓存结果的密钥中使用的Control
。但是,在查找真实捆绑包时,自定义ClassLoader
实施会将defaultLoader
替换为您的ResourceBundle
实例。
请注意,您应该在第三方库的查找操作之前执行此操作。此控件表示bundle永远不会过期,但当JVM内存不足时,它仍可能被释放。
请注意,{{1}}也会缓存失败,因此在其他人尝试查找该捆绑包之前,必须 这个技巧。