这是我的项目的 Maven 结构
app > common-module > webapp-module > batch-module pom.xml
The common-module
exposes a Version
class. This class is used by both webapp and batch modules.
The Version
class has one unique static method called get
. It returns the global version of the project.
The global version is stored in a properties file. When get
is called from batch module (a standalone java application), the properties file is successfully loaded.
In the webapp, things are different. I have created a managed bean VersionBean
that would permit any JSF page to call the get
method. Whenever I use one of the following
FacesContext.getCurrentInstance().getExternalContext()
FacesContext.getCurrentInstance().getExternalContext().getContext()
Thread.currentThread().getClassLoader()
我永远找不到properties.file。
如何从托管 bean 加载位于 jar 文件中的属性文件 (getResourceAsStream)?
编辑
这是我根据 @BalusC 和 @eljunior 的建议提出的解决方案
VersionBean.java
@ManagedBean(eager=true)
@ApplicationScoped
public class VersionBean {
private String version;
@PostConstruct
public void init(){
version = Version.get();
}
}
版本.java
public class Version {
public static String get() {
InputStream is = Version.class.getResourceAsStream("/version.properties");
// Read InputStream and return version string ...
}
}
最佳答案
我不确定 Maven 如何构建 WAR 以及您的属性文件实际位于何处,但我至少可以告诉 ExternalContext#getResourceAsStream()
, Thread#getContextClassLoader()
和 Class#getClassLoader()
的工作方式不同。
ExternalContext#getResourceAsStream()
ExternalContext#getResourceAsStream()
扫描 Web 内容文件夹中的 Web 应用程序资源(WAR 的/WEB-INF
和/META-INF
文件夹位于此处)也驻留在)以及部署在 Web 应用程序的/WEB-INF/lib
中的任何 JAR 文件的/META-INF/resources
文件夹中。提供的路径始终相对于这些根文件夹,并且应以/
开头。InputStream input = externalContext .getResourceAsStream("/WEB-INF/version.properties");
Thread#getContextClassLoader()
Thread#getContextClassLoader()
在类路径的“根”上运行。这涵盖了 webapp、appserver 和 JVM 的类路径所覆盖的所有文件夹。提供的路径始终相对于类路径根目录,并且不能以/
开头。请注意,当属性文件包含在包中时,您应该将包结构视为文件系统路径,并以/
作为分隔符。下面的示例假设它位于包com.example.version
中。InputStream input = Thread.currentThread().getContextClassLoader() .getResourceAsStream("com/example/version/version.properties");
Class#getClassLoader()
Class#getClassLoader() 相对于类本身的位置进行操作。提供的路径可以是相对路径或绝对路径。如果是相对的,那么它是相对于类本身的位置的。如果是绝对的,那么它对于类路径根来说是绝对的。请注意,这不一定可以访问类路径覆盖的所有其他文件夹。下面的示例假设属性文件与VersionBean
类位于同一包中:InputStream input = VersionBean.class .getResourceAsStream("version.properties");
或者当它在另一个包中时,例如
com.example.other
(注意开头的/
):InputStream input = VersionBean.class .getResourceAsStream("/com/example/other/version.properties");
关于java - 使用 JSF 从 JAR 文件中加载属性文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10873885/