在我最终弄清楚为什么 JWS 1.6.0_29 无法启动 1.4.2_12 应用程序(请参阅此问题)之后,我在启动 1.4.2_12 应用程序时遇到了另一个异常。使用 JWS 1.6.0_29。
加载 ResourceBundle 时出现 MissingResourceException。然而,message.properties 文件确实存在于与加载它的类相同的包中。
当使用 JWS 1.4 或 1.5 启动应用程序时,不会引发异常。
仅在启动应用程序时引发异常。使用 JWS 1.6。
完整的堆栈跟踪是:
java.lang.ExceptionInInitializerError
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.util.MissingResourceException: Can't find bundle for base name com.test.hello.messages, locale fr_FR
at java.util.ResourceBundle.throwMissingResourceException(Unknown Source)
at java.util.ResourceBundle.getBundleImpl(Unknown Source)
at java.util.ResourceBundle.getBundle(Unknown Source)
at com.test.hello.Main.<clinit>(Main.java:10)
... 9 more
重现的测试用例
JNLP 描述符是:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://localhost:80/meslegacy/apps" href="testJwsXXTo142.jnlp">
<information>
<title>JWS TEST 1.6 -> 1.4.2</title>
<vendor>Hello World Vendor</vendor>
<description>Hello World</description>
</information>
<security>
<all-permissions />
</security>
<resources>
<j2se version="1.4.2_12" href="http://java.sun.com/products/autodl/j2se" />
<jar href="jar/helloworld.jar" main="true" />
</resources>
<application-desc main-class="com.test.hello.Main" />
</jnlp>
com.test.hello.Main 类是:
package com.test.hello;
import java.util.ResourceBundle;
import javax.swing.JFrame;
public class Main {
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(Main.class.getPackage().getName()+".messages");
public static void main(String[] args) {
JFrame frame = new JFrame("Hello world !");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,600);
frame.setVisible(true);
}
}
补充测试
- 为 ResourceBundle.getBundle() 方法指定 ClassLoader 和 Locale 并不能解决问题。
- Main.class.getClassLaoder() 和 Thread.currentThread().getContextClassLaoder() 已经过测试并产生相同的异常。
- “手动”加载资源确实有效(见下文)。
手动加载资源的测试代码:
ClassLoader cl = Main.class.getClassLoader();
String resourcePath = baseName.replaceAll("\\.", "/");
System.out.println(resourcePath);
URL resourceUrl = cl.getResource(resourcePath+".properties");
System.out.println("Resource manually loaded :"+resourceUrl);
将产生:
com/test/hello/messages.properties
Resource manually loaded :jar:http://localhost:80/meslegacy/apps/jar/helloworld.jar!/com%2ftest%2fhello%2fmessages.properties
- 但是,虽然可以找到资源,但无法获取资源内容。
例子:
ClassLoader cl = Main.class.getClassLoader();
String resourcePath = baseName.replaceAll("\\.", "/") + ".properties";
URL resourceUrl = cl.getResource(resourcePath);
// here, resourceUrl is not null. Then build bundle by hand
ResourceBundle prb = new PropertyResourceBundle(resourceUrl.openStream());
哪个产生:
java.io.FileNotFoundException: JAR entry com%2ftest%2fhello%2fmessages.properties not found in C:\Documents and Settings\firstname.lastname\Application Data\Sun\Java\Deployment\cache\6.0\18\3bfe5d92-3dfda9ef
at com.sun.jnlp.JNLPCachedJarURLConnection.connect(Unknown Source)
at com.sun.jnlp.JNLPCachedJarURLConnection.getInputStream(Unknown Source)
at java.net.URL.openStream(Unknown Source)
at com.test.hello.Main.main(Main.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javaws.Launcher.executeApplication(Unknown Source)
at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
at com.sun.javaws.Launcher.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
似乎更像是一种缓存问题...
我有任何一个提示,将不胜感激,
谢谢阅读。