Java 从类路径加载 ResourceBundle

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20524950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 02:32:44  来源:igfitidea点击:

Load ResourceBundle from classpath

javaclasspathbundle

提问by svager

I have two jar files. One of the jars needs to read language pack from another jar. Here is basic structure of both jars

我有两个 jar 文件。其中一个 jar 需要从另一个 jar 中读取语言包。这是两个罐子的基本结构

jar1    
   |--com.example.BundleLoader 



jar2
   |--strings
         |--language.properties
         |--language_fr.properties

Language pack is on the classpath. In order to read language packs by the BundleLoader I am trying to use ResourseBundle in conjunction with ClassLoader.

语言包在类路径上。为了通过 BundleLoader 读取语言包,我尝试将 ResourseBundle 与 ClassLoader 结合使用。

This is how I am attempting to do that

这就是我尝试这样做的方式

<--snipet-->
private ResourceBundle englishStrings = null;
private ResourceBundle frenchStrings = null;
<--end of snippet--->


<---snippet--->
        System.out.println("About to load url from classpath for properties file "+bundleLocation);
        URL url=ClassLoader.getSystemResource(bundleLocation);
        bundleLocation=url.toString();
        System.out.println("Ok loaded it");
        System.out.println("url is "+(url==null?"not available":url.toString())); //Got the folder location

        try {
            URL[] urls = {new URL(bundleLocation)}; //created array of ULRs to be loaded by URLClassLoader
            this.englishStrings = ResourceBundle.getBundle("validationStrings", Locale.getDefault(),new URLClassLoader(urls)); //Exception here
            this.frenchStrings = ResourceBundle.getBundle("validationStrings", Locale.FRENCH,new URLClassLoader(urls));             
            } catch (MalformedURLException e1)
            {// TODO Auto-generated catch block
                e1.printStackTrace();
            }

    }
<--End of Snippet-->

The Exception that I get is

我得到的例外是

java.lang.ExceptionInInitializerError
    at com.example.Model.model.dObject.doCommon(dObject.java:70)
    at com.example.Model.model.dObject.validate(dObject.java:42)
    at com.example.Model.model.test.dObjectTest.testChpValidate(dObjectTest.java:49)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access
this.englishStrings = ResourceBundle.getBundle("strings.language");
this.frenchStrings = ResourceBundle.getBundle("strings.language", Locale.FRENCH);
0(ParentRunner.java:53) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: java.util.MissingResourceException: Can't find bundle for base name validationStrings, locale en_CA at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499) at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322) at java.util.ResourceBundle.getBundle(ResourceBundle.java:1028) at com.example.util.Strings.<init>(Strings.java:51) at com.example.util.Strings.<clinit>(Strings.java:26) ... 27 more

Basically I can't find bundles even though property files are in the folder. Have anyone ran into this? I assume that someone dealt with this before.

基本上,即使属性文件在文件夹中,我也找不到包。有没有人遇到过这个?我假设之前有人处理过这个问题。

Thank you.

谢谢你。

采纳答案by Kelsey Francis

ResourceBundle.getBundle("validationStrings", Locale.FRENCH)will look in any JAR on the classpath for a file called validationStrings_fr.propertiesdirectly under the root directory. If it can't find that, it will try validationStrings.properties.

ResourceBundle.getBundle("validationStrings", Locale.FRENCH)将在类路径上的任何 JAR 中查找validationStrings_fr.properties直接在根目录下调用的文件。如果找不到,它会尝试validationStrings.properties

If you aren't able to change the structure of the language pack JAR, try replacing your entire second snippet with just

如果您无法更改语言包 JAR 的结构,请尝试将整个第二个代码段替换为

##代码##

The englishStringsline will look for files strings/language_en_CA.properties(assuming your default locale is en_CA), and then fall back to strings/language.propertieswhen it cannot find that. The frenchStringsline will look for strings/language_fr.properties.

englishStrings行将查找文件strings/language_en_CA.properties(假设您的默认语言环境是en_CA),然后strings/language.properties在找不到文件时返回。该frenchStrings行将查找strings/language_fr.properties.