2017-02-07 15 views
0

У меня действительно странная проблема. У меня нет логического объяснения. В сущности, я пытаюсь читать ResourceBundle через имя UpperCase от внешнего .jar. Например. ResourceBundle называется MessageBundle, и я прочитал его с MESSAGEBUNDLE. Странное поведение, которое я испытываю, описано ниже.Чтение ResourceBundle с именем верхнего регистра показывает странное поведение

Рассмотрим следующий простой макет проекта:

ResourceBundleProject

Она в основном состоит из 2 небольших проектов. Проект ResourceBundleDependency состоит только из файла свойств. Проект ResourceBundleReader состоит из файла свойств, метода main и имеет зависимость от проекта ResourceBundleDependency.

В методе main из BundleReader, я стараюсь читать оба ResourceBundles двумя способами. Оба CamelCase и UpperCase как таковой:

public static void main(String[] args) { 
    ResourceBundle readerBundle = PropertyResourceBundle.getBundle("ReaderMessageBundle", Locale.getDefault()); 
    System.out.println(readerBundle.getString("READER.KEY")); 

    ResourceBundle upperReaderBundle = PropertyResourceBundle.getBundle("READERMESSAGEBUNDLE", Locale.getDefault()); 
    System.out.println(upperReaderBundle.getString("READER.KEY")); 

    ResourceBundle depBundle = PropertyResourceBundle.getBundle("DependencyMessageBundle", Locale.getDefault()); 
    System.out.println(depBundle.getString("DEPENDENCY.KEY")); 

    ResourceBundle upperDepBundle = PropertyResourceBundle.getBundle("DEPENDENCYMESSAGEBUNDLE", Locale.getDefault()); 
    System.out.println(upperDepBundle.getString("DEPENDENCY.KEY")); 
} 

Поиск # 1:

Если оба проекта открыты в NetBeans и я бегу основной метод. Все работает нормально и печатается следующее:

Internal Value 
Internal Value 
Dependency Value 
Dependency Value 

Это мой желаемый результат.

Поиск # 2:

Когда я закрываю ResourceBundleDependency проект в NetBeans и запустить тот же метод (я построил зависимость), он находит файл при вызове в CamelCase манере, но не может найти его с помощью UpperCase образом:

Internal Value 
Internal Value 
Dependency Value 
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name DEPENDENCYMESSAGEBUNDLE, locale en_GB 
    at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1564) 
    at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1387) 
    at java.util.ResourceBundle.getBundle(ResourceBundle.java:845) 
    at com.mycompany.resourcebundlereader.BundleReader.main(BundleReader.java:19) 

Это не может быть Classpath проблемой, так как файл CamelCase свойство найден нормально.

Поиск # 3:

Преступник должен быть NetBeans. Вместо этого я построю .jar и запустим это вместо этого. Вызов java -jar ResourceBundleReader-1.0-SNAPSHOT.jar, я получаю следующий результат:

Internal Value 
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name READERMESSAGEBUNDLE, locale en_GB 
     at java.util.ResourceBundle.throwMissingResourceException(Unknown Source) 
     at java.util.ResourceBundle.getBundleImpl(Unknown Source) 
     at java.util.ResourceBundle.getBundle(Unknown Source) 
     at com.mycompany.resourcebundlereader.BundleReader.main(BundleReader.java:13) 

Что еще хуже? Он даже не может прочитать файл свойств из своего собственного .jar в верхнем регистре.

Поиск # 4:

Преступник должен быть Maven? Создавая .jar без использования maven и просто добавляя банку зависимости к пути к классам, проблема такая же, как и предыдущая.Работает отлично от NetBeans, не может даже читать свой ResourceBundle в UpperCase:

java -jar ResourceBundleReader2.jar 
Internal Value 
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name READERMESSAGEBUNDLE, locale en_GB 
     at java.util.ResourceBundle.throwMissingResourceException(Unknown Source) 
     at java.util.ResourceBundle.getBundleImpl(Unknown Source) 
     at java.util.ResourceBundle.getBundle(Unknown Source) 
     at resourcebundlereader2.BundleReader.main(BundleReader.java:13) 

ResourceBundle и PropertyResourceBundle JavaDoc действительно не говоря уже ничего от решения прописными. Но если это работает в одном случае, почему бы и нет другого? Если это не очень хорошо поддерживается, может ли пользовательский ClassLoader решить его?

ответ

0

Ваша проблема - чувствительность к регистру «файловой системы» (если я могу назвать файл jar файловой системой).

PropertyResourceBundle.getBundle() должен загрузить файл свойств с соответствующим именем. Это означает, что некоторый код должен искать файл свойств либо в файловой системе, либо в файле jar.

В окнах файловая система не чувствительна к регистру, поэтому поиск «READERMESSAGEBUNDLE.properties» найдет файл с именем «ReaderMessageBundle.properties».

Файловые системы linux и файлы jar чувствительны к регистру, поэтому поиск «READERMESSAGEBUNDLE.properties» ничего не обнаружит.


Будет ли заказчик classloader решить вашу проблему? Может быть, если метод ClassLoader.getResource(String) не просто возвращает URL-адрес для READERMESSAGEBUNDLE.properties (если он существует), но перечисляет все ресурсы, содержащиеся в его пути к классам, и проверяет, соответствует ли какое-либо из них имени без учета регистра.