为什么我无法在 WildFly 中使用 WEB-INF/classes 中的 getResourceAsStream 读取属性文件?
Why I cannot read properties file using getResourceAsStream from WEB-INF/classes in WildFly?
我电脑的操作系统是 Windows7 64 位。
我在 Eclipse 中创建了一个非常简单的动态 Web 项目应用程序:
我在 WEB-INF/classes
目录中有一个 app.properties
文件,具有以下属性:
DefaultMaximumBatchSize=1000
DAOFactory=MSSQLSERVER
我有一个 class AppProperties
在启动时使用 getResourceAsStream:
将上述文件读入 Properties 对象
public class AppProperties {
private static final Properties APP_PROPERTIES;
static {
InputStream inputStream = null;
APP_PROPERTIES = new Properties();
try {
inputStream = AppProperties.class.getResourceAsStream("/WEB-INF/classes/app.properties");
System.out.println("AppProperties: inputStream=" + inputStream);
if (inputStream != null) {
APP_PROPERTIES.load(inputStream);
}
} catch (Exception e) {
System.out.println("AppProperties: Exception occured; e=" + e);
}
}
public static String getValue(String propertyName) {
if (propertyName == null || propertyName.equalsIgnoreCase(""))
return null;
else
return APP_PROPERTIES.getProperty(propertyName);
}
}
我有一个听众class AppContextListener
:
public class AppContextListener implements ServletContextListener {
public AppContextListener() {
}
public void contextInitialized(ServletContextEvent arg0) {
String defaultMaxBatchSize = AppProperties.getValue("DefaultMaximumBatchSize");
System.out.println("AppContextListener: contextInitialized(ServletContextEvent): defaultMaxBatchSize=" + defaultMaxBatchSize);
}
public void contextDestroyed(ServletContextEvent arg0) {
}
}
我将应用程序部署到 JBoss 4.2.3,运行 JBoss 4.2.3,我在 server.log:
中得到了这个输出
AppProperties: inputStream=java.io.FileInputStream@1adde645
AppContextListener: contextInitialized(ServletContextEvent): defaultMaxBatchSize=1000
完美。
然后我将相同的应用程序部署到 WildFly 8.2.1,运行 WildFly 8.2.1,我在 server.log:
中得到了这个输出
AppProperties: inputStream=null
AppContextListener: contextInitialized(ServletContextEvent): defaultMaxBatchSize=null
发生了什么事?从 WEB-INF/classes
目录读取 WildFly 中的属性文件的正确方法是什么?
JBoss 不应该工作。
Class.getResourceAsStream 从 class 路径 检索资源,而 webapp 根文件夹不在 class 路径中。
WEB-INF/classes
文件夹是。使用getResourceAsStream("/app.properties")
,记得关闭流:
private static final Properties APP_PROPERTIES = new Properties();
static {
try (InputStream inputStream = AppProperties.class.getResourceAsStream("/app.properties")) {
System.out.println("AppProperties: inputStream=" + inputStream);
if (inputStream != null)
APP_PROPERTIES.load(inputStream);
} catch (Exception e) {
System.out.println("AppProperties: Exception occured; e=" + e);
}
}
现在,如果 app.properties
总是在 AppProperties.class
旁边,而不是在根目录下,则使名称不合格(删除 /
)。即使您的 class 在包裹中(而且它在包裹中,对吗?),这也会起作用。
Class.getResourceAsStream()
在构成应用程序类路径的所有目录和 jar 中查找资源。
因此,如果您使用
启动 java 程序
java -cp foo;bar.jar com.baz.Main
而你使用SomeClass.class.getResourceAsStream("/blabla/app.properties")
,classloader会在foo/blabla
下寻找app.properties
文件,在bar.jar
的blabla
目录下寻找app.properties
文件。
现在,在webapp中,构成webapp类路径的是
- 目录WEB-INF/classes
- WEB-INF/lib下的所有jar文件
因此,如果您调用
AppProperties.class.getResourceAsStream("/WEB-INF/classes/app.properties")
类加载器将在
中查找app.properties
/WEB-INF/classes/WEB-INF/classes
<all the jar files of WEB-INF/lib>/WEB-INF/classes
结论是,要加载位于 WEB-INF/classes
的 app.properties
文件,您需要的是
AppProperties.class.getResourceAsStream("app.properties")
尝试
InputStream inputStream =
this.getClass().getClassLoader().getResourceAsStream("/my.properties");`
我电脑的操作系统是 Windows7 64 位。
我在 Eclipse 中创建了一个非常简单的动态 Web 项目应用程序:
我在 WEB-INF/classes
目录中有一个 app.properties
文件,具有以下属性:
DefaultMaximumBatchSize=1000
DAOFactory=MSSQLSERVER
我有一个 class AppProperties
在启动时使用 getResourceAsStream:
public class AppProperties {
private static final Properties APP_PROPERTIES;
static {
InputStream inputStream = null;
APP_PROPERTIES = new Properties();
try {
inputStream = AppProperties.class.getResourceAsStream("/WEB-INF/classes/app.properties");
System.out.println("AppProperties: inputStream=" + inputStream);
if (inputStream != null) {
APP_PROPERTIES.load(inputStream);
}
} catch (Exception e) {
System.out.println("AppProperties: Exception occured; e=" + e);
}
}
public static String getValue(String propertyName) {
if (propertyName == null || propertyName.equalsIgnoreCase(""))
return null;
else
return APP_PROPERTIES.getProperty(propertyName);
}
}
我有一个听众class AppContextListener
:
public class AppContextListener implements ServletContextListener {
public AppContextListener() {
}
public void contextInitialized(ServletContextEvent arg0) {
String defaultMaxBatchSize = AppProperties.getValue("DefaultMaximumBatchSize");
System.out.println("AppContextListener: contextInitialized(ServletContextEvent): defaultMaxBatchSize=" + defaultMaxBatchSize);
}
public void contextDestroyed(ServletContextEvent arg0) {
}
}
我将应用程序部署到 JBoss 4.2.3,运行 JBoss 4.2.3,我在 server.log:
中得到了这个输出AppProperties: inputStream=java.io.FileInputStream@1adde645
AppContextListener: contextInitialized(ServletContextEvent): defaultMaxBatchSize=1000
完美。
然后我将相同的应用程序部署到 WildFly 8.2.1,运行 WildFly 8.2.1,我在 server.log:
中得到了这个输出AppProperties: inputStream=null
AppContextListener: contextInitialized(ServletContextEvent): defaultMaxBatchSize=null
发生了什么事?从 WEB-INF/classes
目录读取 WildFly 中的属性文件的正确方法是什么?
JBoss 不应该工作。
Class.getResourceAsStream 从 class 路径 检索资源,而 webapp 根文件夹不在 class 路径中。
WEB-INF/classes
文件夹是。使用getResourceAsStream("/app.properties")
,记得关闭流:
private static final Properties APP_PROPERTIES = new Properties();
static {
try (InputStream inputStream = AppProperties.class.getResourceAsStream("/app.properties")) {
System.out.println("AppProperties: inputStream=" + inputStream);
if (inputStream != null)
APP_PROPERTIES.load(inputStream);
} catch (Exception e) {
System.out.println("AppProperties: Exception occured; e=" + e);
}
}
现在,如果 app.properties
总是在 AppProperties.class
旁边,而不是在根目录下,则使名称不合格(删除 /
)。即使您的 class 在包裹中(而且它在包裹中,对吗?),这也会起作用。
Class.getResourceAsStream()
在构成应用程序类路径的所有目录和 jar 中查找资源。
因此,如果您使用
启动 java 程序java -cp foo;bar.jar com.baz.Main
而你使用SomeClass.class.getResourceAsStream("/blabla/app.properties")
,classloader会在foo/blabla
下寻找app.properties
文件,在bar.jar
的blabla
目录下寻找app.properties
文件。
现在,在webapp中,构成webapp类路径的是
- 目录WEB-INF/classes
- WEB-INF/lib下的所有jar文件
因此,如果您调用
AppProperties.class.getResourceAsStream("/WEB-INF/classes/app.properties")
类加载器将在
中查找app.properties/WEB-INF/classes/WEB-INF/classes
<all the jar files of WEB-INF/lib>/WEB-INF/classes
结论是,要加载位于 WEB-INF/classes
的 app.properties
文件,您需要的是
AppProperties.class.getResourceAsStream("app.properties")
尝试
InputStream inputStream =
this.getClass().getClassLoader().getResourceAsStream("/my.properties");`