Pregunta

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

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. This is how I am attempting to do that

private ResourceBundle englishStrings = null;
private ResourceBundle frenchStrings = null;

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
    englishStrings = ResourceBundle.getBundle("validationStrings", Locale.getDefault(),
            new URLClassLoader(urls)); // Exception here
    frenchStrings = ResourceBundle.getBundle("validationStrings", Locale.FRENCH, 
            new URLClassLoader(urls));
} catch (MalformedURLException e1) {
    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$1.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$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.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.

¿Fue útil?

Solución

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

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

this.englishStrings = ResourceBundle.getBundle("strings.language");
this.frenchStrings = ResourceBundle.getBundle("strings.language", Locale.FRENCH);

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top