Debug java util MissingResourceException
java.util.MissingResourceException Can't find bundle for base name, locale...How did I get this exception? The crux of this problem is the requested resource, in most cases, a properties file, is not configured correctly in the classpath. For example, you have a properties file, connection.properties, in the same source directory as Java source files. Javac will compile *.java into *.class in a target directory such as build/classes, which is in your runtime classpath. But connection.properties is not copied into build/classes directory unless you either add a <copy> task after <javac> in the Ant build file, or do so manually.
How to fix it? Make sure this resource is configured correctly in the classpath through one of the following:
- Like I said above, copy the resource from source directory to
build/classesdirectory, which is in the classpath.
- If your code is like
ResourceBundle.getBundle("connection"),then after copying you should havebuild/classes/connection.properties. - If your code is like
ResourceBundle.getBundle("com.javahowto.test.connection"),then after copying you should havebuild/classes/com/javahowto/test/connection.properties.
- Or you can choose package resources into a jar file, say,
connection-info.jar, which is included in runtime classpath (not needed in Javac classpath).
- If your code is like
ResourceBundle.getBundle("connection"),thenconnection-info.jarshould contain this entry:connection.properties. - If your code is like
ResourceBundle.getBundle("com.javahowto.test.connection"), thenconnection-info.jarshould contain this entry:com/javahowto/test/connection.properties.
- Or you can choose to put the resource in a separate
resourcesdirectory, includeresourcesdirectory in runtime classpath. This way you don't have to duplicate the resource in multiple directories/jar. The disadvantage is it's a little inconvenient at development time to have resource in a separate directory than Java code.
- If your code is like
ResourceBundle.getBundle("connection"), then you should haveresources/connection.properties. - If your code is like
ResourceBundle.getBundle("com.javahowto.test.connection"), then you should haveresources/com/javahowto/test/connection.properties.
tags: Java, MissingResourceException, debug, ResourceBundle
12 comments:
ResourceBundle.getBundle() is really intended to look up translatable resources. In the example you give (connections.properties), it sounds like you're using it as a general mechanism for loading properties files from the classpath.
Although that works, it's relatively inefficent (it first tries to find locale specific versions of the properties file, which incurs a classloading overhead, and then must create a PropertiesResourceBundle instance for your properties file). If you're loading a nontranslated file, you can achieve the same effect using something like:
URL resUrl = myclass.getResource( "/org/acme/connection.properties" );
Properties props = new Properties();
properties.load( resUrl.openStream() );
Brian, thanks for the comments. I agree ResourceBundle should be used for i18n purpose. But I also found it's often used (misused) for general properties-loading. Maybe I should change the example connection.properties to messages_en.properties.
I guess you mean myclass.getClassLoader().getResource();
Nevertheless, the same techniques still apply, since ClassLoader.getResource() works the same as ResourceBundle.getBundle();
Using ResourceBundle.getBundle() gives you an option to localize your properties in the future. For instance, I may want to use localized properties such as database.name, user.name, db.password, etc.
Thank you very much!! I dont know why no one clearly describes the solution like you have done. Excellent!
It was really useful, thanks a lot, I have always faced the same problem and i didnt know what was it about
I agree with all that have been said. A straight-forward explanation that you cannot find even in educational stuff. Thank you so much it saved me days and days of work.
Thanks for posting this clear explanation.
I stumbled on this error while trying to define a spring ResourceBundleViewResolver, thinking my properties had to be located in the /WEB-INF directory.
Your post helped me see the light :)
Thanks a lot... Even I was facing the same issue was trying to fix it for a whole day. Thanks a lot for your post.
Good explanation of an all to common error. Unfortunately I've found installs where adding the .prop to the under classes does note solve the problem IF the prop file is referenced in a code lib referenced in the classpath of the web project.
For instance, a servlet is using some custom logging lib (log.jar). It's referenced by the project. The logging methods are visible to the servlet and everything compiles. Assuming the log.jar needs values in the .prop file, it fails to find it when exercised IF the resource is located outside of the jar. Thus defeating the purpose of externalizing the jar to your particular web app instance. There are workarounds, but none are really satisfying.
Post a Comment