简体   繁体   English

在运行时加载资源包

[英]Load resource bundle at runtime

Here is what I would like to achieve. 这是我想要实现的。 We have an application that is running as a servlet on an IBM Domino server. 我们有一个在Tivoli Domino服务器上作为servlet运行的应用程序。 The application uses resource bundle to get translated messages and labels according to the browser language. 该应用程序使用资源束根据浏览器语言获取翻译后的消息和标签。

We want to enable customers to override some of the values. 我们希望使客户能够覆盖某些值。 We cannot modify the bundle_lang.properties files in the .jar at runtime. 我们无法在运行时修改.jar中的bundle_lang.properties文件。 So the idea was to provide additional bundleCustom_lang.properties files along with the .jar 因此,该想法是提供附加的bundleCustom_lang.properties文件以及.jar文件

This bundle could be loaded at runtime using 可以使用以下命令在运行时加载该捆绑包

private static void addToClassPath(String s) throws Exception {
    File file = new File(s);
    URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
    java.lang.reflect.Method m = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
    m.setAccessible(true);
    m.invoke(cl, new Object[] { file.toURI().toURL() });
}

So far, so good, this works in Eclipse. 到目前为止,一切都很好,这在Eclipse中有效。 Here I had the bundleCustom files in a directory outside the workspace ( /volumes/DATA/Temp/ ) 在这里,我在工作区之外的目录中有bundleCustom文件(/ volumes / DATA / Temp /)

Once the addition ResourceBundle is available, We check this bundle for the key first. 一旦附加ResourceBundle可用,我们将首先检查此捆绑包中的密钥。 If it returns a value than this value is being used for the translation. 如果返回一个值,则此值将用于转换。 If no value is returned, or the file does not exist, the value from the bundle inside the .jar is used. 如果没有返回值,或者文件不存在,则使用.jar包中的值。

My full code is here 我的完整代码在这里

public class BundleTest2 {

    static final String CUSTOM_BUNDLE_PATH      = "/volumes/DATA/Temp/";
    static final String CUSTOM_BUNDLE_MODIFIER  = "Custom";

    public static void main(String[] args) {
        try {
            addToClassPath(CUSTOM_BUNDLE_PATH);

            System.out.println(_getTranslation("LabelBundle", "OutlineUsersAllVIP"));
        } catch (Exception e) {
        }
    }



    private static String _getTranslation(String bundle, String translation) {
        return _getTranslation0(bundle, new Locale("de"), translation);
    }

    private static String _getTranslation0(String bundle, Locale locale, String key) {
        String s = null;
        try {
            try {
                ResourceBundle custom = ResourceBundle.getBundle(bundle + CUSTOM_BUNDLE_MODIFIER, locale);
                if (custom.containsKey(key)) {
                    s = custom.getString(key);
                }
            } catch (MissingResourceException re) {
            System.out.println("CANNOT FIND CUSTOM RESOURCE BUNDLE: " + bundle + CUSTOM_BUNDLE_MODIFIER);
            }

            if (null == s || "".equals(s)) {
                s = ResourceBundle.getBundle(bundle, locale).getString(key);
            }
        } catch (Exception e) {
        }
        return s;
    }

    private static void addToClassPath(String s) throws Exception {
        File file = new File(s);
        URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
        java.lang.reflect.Method m = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
        m.setAccessible(true);
        m.invoke(cl, new Object[] { file.toURI().toURL() });
    }
}

When I try the same from inside the servlet, I get a MissingResourceException. 当我从servlet内部尝试相同操作时,会收到MissingResourceException。

I also tried to put the .properties files into a customization.jar and provide the full path ( incl. the .jar ) when invoking addToClassPath(). 我还尝试了将.properties文件放入customization.jar中,并在调用addToClassPath()时提供完整路径(包括.jar)。 Apparently, the customization.jar is loaded ( it is locked in the file system ), but I still get the MissingResourceException. 显然,customization.jar已加载(它已锁定在文件系统中),但是我仍然收到MissingResourceException。

We already use the same code in addToClassPath to load a Db2 driver and this is working as expected. 我们已经在addToClassPath中使用了相同的代码来加载Db2驱动程序,并且该程序可以按预期工作。

What am I missing? 我想念什么?

Why don't you use Database to store the overriden translations? 为什么不使用数据库存储替代翻译? Persisting something crated by client in the local deployment of application is generally not a good idea, what will happen if you redeploy the app, will these resources be deleted? 在应用程序的本地部署中坚持由客户端创建的内容通常不是一个好主意,如果重新部署应用程序会发生什么,这些资源会被删除吗? What if you have to run another node of your app, how will you replicate the custom properties file? 如果必须运行应用程序的另一个节点怎么办,您将如何复制自定义属性文件?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM