我有一个maven项目设置,例如
parent
...pom.xml
...servlet-app
......pom.xml ( specifies simple-lib as a dependency )
...simple-lib
......src/main/resources/config.properties
......src/main/java/package1/Config.java
......src/main/java/package1/HelloQuartzJob.java
基本上servlet应用程序servlet-app将simple-lib指定为依赖项。配置文件config.properties打包在simple-lib.jar的顶层/级别。当我解压缩servelet-app.war时,我可以看到WEB_INF / lib / simple-lib.jar。所以,一切都很好。
Config.java看起来像这样:
public class Config{
static final String PROPERTILES_FILE = "config.properties";
static Properties props;
static{
log.info("Loading Config properties from {}", PROPERTILES_FILE);
props = new Properties();
try {
InputStream is = ClassLoader.getSystemResourceAsStream(PROPERTILES_FILE);
if (is == null) {
log.info("Loading through ClassLoader as root");
is = ClassLoader.getSystemResourceAsStream("/"+PROPERTILES_FILE);
}
if (is == null) {
log.info("Loading through Config.class. root");
is = Config.class.getResourceAsStream("/"+PROPERTILES_FILE);
}
if (is == null) {
log.info("Loading through Config.class. relative");
is = Config.class.getResourceAsStream(PROPERTILES_FILE);
}
if( is == null ) {
log.info("Thread class loader root");
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("/"+PROPERTILES_FILE);
}
props.load(is);
} catch (Throwable e) {
log.error("Config properties loading error ", e);
throw new RuntimeException(e);
}
}
}
但是,当我在tomcat7中部署它时,我得到一个NoClassDefFound /无法初始化package1.Config错误。我相信这是因为classLoaders。
同样令人感兴趣的是,这个package1.Config由HelloQuartzJob.java使用,它是一个石英作业,由在这个servlet应用程序中运行的调度程序实例运行。
任何指针?
答案 0 :(得分:0)
你应该替换这一行:
InputStream is = ClassLoader.getSystemResourceAsStream(PROPERTILES_FILE);
使用:
InputStream is = Config.class.getClassLoader().getResourceAsStream(PROPERTILES_FILE);
为了使用当前的webapp类加载器及其根源于战争根源。
答案 1 :(得分:0)
我看到两个问题:
is = ClassLoader.getSystemResourceAsStream("/"+PROPERTILES_FILE);
和
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("/"+PROPERTILES_FILE);
直接从类加载器加载资源时,不要使用前导'/'字符。
从Class.getResourceAsStream()
使用前导'/'(因为资源是相对于类的包加载的),但对于ClassLoader.getResourceAsStream()
和getSystemResourceAsStream()
,不是使用前导'/'。
答案 2 :(得分:0)
您需要从类加载器实例中请求资源。
来自静态背景:
String url = Config.class.getClassLoader().getResource("config.properties");
InputStream is = Config.class.getClassLoader().getResourceAsStream("config.properties");
来自一个实例:
String url = getClass().getClassLoader().getResource("config.properties");
InputStream is = getClass().getClassLoader().getResourceAsStream("config.properties");
您应该只使用相对路径而不是绝对路径(以" /"开头)来访问webapp上下文中的jar资源。
昨天我遇到了同样的麻烦,这样很容易解决: - )
这只是一个simle classLoader问题,但它非常重要。如果使用绝对路径,则加载程序只会查看WEB-INF / classes文件夹。