You know java is looking for a properties file in a specific locale. You may be baffled why java keeps complaining it can't find a properties file that is right there. A few things to keep in mind when debugging this type of errors:
- These resource properties files are loaded by classloader, similar to java classes. So you need to include them in your runtime
classpath.
- These resources have fully-qualified-resource-name, similar to a fully-qualified-class-name, excerpt you can't import a resource into your java source file. Why? because its name takes the form of a string.
ResourceBundle.getBundle("config") tells the classloader to load a resource named "config" with default package (that is, no package). It does NOT mean a resource in the current package that has the referencing class.
ResourceBundle.getBundle("com.cheng.scrap.config") tells the classloader to load a resource named "config" with package "com.cheng.scrap." Its fully-qualified-resource-name is"com.cheng.scrap.config"
For instance, you have a project like
C:/ws/netbeans5/scrap>| build.xml+---build| /---classes| /---com| /---cheng| /---scrap| Scrap.class|+---src| /---com| /---cheng| /---scrap| config.properties| Scrap.java
For this statement in Scrap.java: ResourceBundle config = ResourceBundle.getBundle("config"); to work, you will need to cp src/com/cheng/scrap/config.properties build/classes/ such that config.propertiesis directly
under classes, and at the same level as com. Alternatively, you can put config.properties into aconfig.jar such that config.properties is at the root of config.jar without any subdirectories,
and includeconfig.jar in the classpath.
For this statement in Scrap.java: ResourceBundle config = ResourceBundle.getBundle("com.cheng.scrap.config"); to work, you will need to cp src/com/cheng/scrap/config.properties build/classes/com/cheng/scrap/ such
that config.propertiesis directly under classes/com/cheng/scrap/, and at the same level as scrap. Alternatively, you can putcom/cheng/scrap/config.properties (along
with the long subdirectories) into a config.jar, and includeconfig.jar in the classpath.
You may be wondering why it is made so confusing? The benefits are two-fold, as I see it:
- Location transparency. At runtime, config.properties is NOT a file, it's just a a loadable resource. config.properites may not exist in your project at all, and the person who wrote Scrap.java may have never seen this resource. A URLClassLoader can find
it in a network path or URL at runtime. This is especially important for server-side components such as EJB, Servlet, JSP, etc, who are normally not allowed to access file systems. When you ask classloaders for a resource, its physical location becomes irrelevant.
- Namespace mechanism. Having a package allows multiple packages to have resources with the same short name without causing conflicts. This is no different from java packages and xml namespaces.
再做翻譯。問題已經解決。主要是在寫自己的resource bundle的時候,如果是在定製開源架構的Messages(如jmesa或者ec),必須明確的是resource是用classloader在運行時讀入的,也就是不是在讀檔案,不能將.properties檔案放在某個檔案夾中,然後在web.xml中param-value寫檔案夾路徑。應該是寫class路徑,而且不能有.properties尾碼。web配置要細心啊,param-value寫檔案夾路徑的時候不能忘記前面的forward slash(前斜杠),而classPath則不需要這個。