2012-06-03 3 views
2

Вот структура Maven моего проектаЗагрузка файла свойств внутри JAR-файла с JSF

 
app 
    > common-module 
    > webapp-module 
    > batch-module 
pom.xml 

common-module выставляет Version класс. Этот класс используется как webapp, так и пакетными модулями.

Класс Version имеет один уникальный статический метод, называемый get. Он возвращает глобальную версию проекта.

Глобальная версия хранится в файле свойств. Когда get вызывается из пакетного модуля (автономного приложения Java), файл свойств успешно загружается.

В webapp все по-другому. Я создал управляемый компонент VersionBean, который позволил бы любой странице JSF вызвать метод get. Всякий раз, когда я пользуюсь одним из следующих

FacesContext.getCurrentInstance().getExternalContext() 

FacesContext.getCurrentInstance().getExternalContext().getContext() 

Thread.currentThread().getClassLoader() 

Я никогда не могу найти файл properties.file.

Как загрузить файл свойств (getResourceAsStream), расположенный в файле jar из управляемого компонента?

EDIT
Вот решение, которое я придумал на основе рекомендаций от @BalusC и @eljunior

VersionBean.java

@ManagedBean(eager=true) 
@ApplicationScoped 
public class VersionBean { 
    private String version; 
    @PostConstruct 
    public void init(){ 
     version = Version.get(); 
    } 
} 

Version.java

public class Version { 
    public static String get() { 
     InputStream is = Version.class.getResourceAsStream("/version.properties"); 

     // Read InputStream and return version string ... 
    } 
} 

ответ

0

Я бы делегировал загрузку файла свойств тому же загрузчику классов класса Version: в методе get используйте Version.class.getResourceAsStream("yourFile.properties");.

Это должно работать в любом месте класс версии могут быть загружены, так что это будет работать в веб-приложение тоже (конечно, при условии, что файл свойств фактически IS внутри общего модуля банку файл :).

Тогда ваш VersionBean может быть приложение области действия боба только загруженного свойство на инициализацию приложения, что-то вроде этого:

@ManagedBean(eager=true) 
@ApplicationScoped 
public class VersionBean { 
    private String version; 
    @PostConstruct 
    public void init(){ 
     version = Version.get(); 
    } 
} 

Обратите внимание, что если вы используете версию JSF до 2,0, вы будете иметь для настройки управляемых компонентов в faces-config.xml вместо использования аннотаций @ManagedBean и @ApplicationScoped.

11

Я не знаю, как Maven строит WAR и где ваш файл свойств является фактически находится, но я могу по крайней мере сказать, как ExternalContext#getResourceAsStream(), Thread#getContextClassLoader() и Class#getClassLoader() все работы по-разному.

  1. ExternalContext # getResourceAsStream()
    В ExternalContext#getResourceAsStream() сканирует WebAPP ресурсов в папке веб-контента (там, где /WEB-INF и /META-INF папки войны также проживают) и в /META-INF/resources папке любых JAR-файлов, размещенных в /WEB-INF/lib из webapp. Поставляемый путь всегда относится к этим корневым папкам и должен начинаться с /.

    InputStream input = externalContext 
        .getResourceAsStream("/WEB-INF/version.properties"); 
    
  2. Thread # getContextClassLoader()
    Thread#getContextClassLoader() действует на "корень" в пути к классам. Это охватывает все папки, охватываемые classpath для webapp, сервера приложений и JVM. Поставляемый путь всегда относится к корню класса маршрута и может не начать с /. Обратите внимание, что когда файл свойств заключен в пакет, вы должны рассматривать структуру пакета как путь к файловой системе с разделителем /. В приведенном ниже примере предполагается, что он находится в пакете com.example.version.

    InputStream input = Thread.currentThread().getContextClassLoader() 
        .getResourceAsStream("com/example/version/version.properties"); 
    
  3. Класс # getClassLoader()
    Class#getClassLoader() работает по отношению к местоположению самого класса. Поставляемый путь может быть как относительным, так и абсолютным. Если относительный, то это касается местоположения самого класса. Если абсолютный, то он является абсолютным для корня classpath. Обратите внимание, что это необязательно имеет доступ ко всем другим папкам, охватываемым classpath. Ниже примере предполагается, что файл свойств в том же пакете, как VersionBean класса:

    InputStream input = VersionBean.class 
        .getResourceAsStream("version.properties"); 
    

    Или когда он находится в другом пакете, например, com.example.other (обратите внимание, ведущий /):

    InputStream input = VersionBean.class 
        .getResourceAsStream("/com/example/other/version.properties"); 
    
+0

Спасибо за ваши объяснения. Я не знал, что методы будут работать так по-разному. Абсолютное расположение файла свойств выглядит следующим образом: '/WEB-INF/lib/batch-module.jar!/Version.properties' – Stephan

+0

' Thread.currentThread(). GetContextClassLoader(). GetResourceAsStream ("version.properties") 'должен тогда делать. – BalusC

+0

Я в замешательстве. Это * * решение # 2. Ответ Eljunior (в основном решение №3, как и в моем ответе) предполагает, что он находится в том же пакете, что и класс, который, похоже, не имеет значения, учитывая ваше абсолютное местоположение в JAR (учитывая, что классы без упаковки являются плохой практикой) , Отказ от ответственности: Maven находится вне меня, поэтому я не могу сказать из головы, как именно он строит JAR и WAR. – BalusC

Смежные вопросы