Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
war应用程序中的Java类加载器(jar/classloader hell)quartz_Java_Tomcat_Classloader_Quartz Scheduler - Fatal编程技术网

war应用程序中的Java类加载器(jar/classloader hell)quartz

war应用程序中的Java类加载器(jar/classloader hell)quartz,java,tomcat,classloader,quartz-scheduler,Java,Tomcat,Classloader,Quartz Scheduler,我有一个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.ja

我有一个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应用程序将简单库指定为依赖项。配置文件config.properties打包在simple-lib.jar的顶层。当我解包servelet-app.war时,我可以看到WEB\u-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错误。我相信这是因为类加载器

另外值得注意的是,HelloQuartzJob.java使用了这个package1.Config,这是一个quartz作业,由在这个servlet应用程序中运行的调度器实例运行


有指针吗?

您应该替换此行:

InputStream is = ClassLoader.getSystemResourceAsStream(PROPERTILES_FILE);
与:

为了使用当前的webapp类加载器,其根位于war的根..

我发现了两个问题:

is = ClassLoader.getSystemResourceAsStream("/"+PROPERTILES_FILE);


直接从类加载器加载资源时,不要使用前导“/”字符


Class.getResourceAsStream()
使用前导“/”(因为资源是相对于类的包加载的),但是对于
ClassLoader.getResourceAsStream()
getSystemResourceAsStream()
不使用前导“/”。

您需要从ClassLoader实例请求资源

从静态上下文:

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资源时,应该只使用相对路径,而不使用绝对路径(以“/”开头)

昨天我也遇到了同样的问题,这样就很容易解决了:-)


这只是一个简单的类加载器问题,但它非常重要。如果使用绝对路径,加载程序将只查看WEB-INF/classes文件夹。

这可能会对您有所帮助:该问题是相关的,但并不确切。在这种情况下,我的类根本没有被初始化,因为它无法通过类加载器找到资源。它的静态作用域。没有“this”。@smartnut007想法仍然是一样的,从this或Config.class获取类的类加载器,重新考虑你的否决票。我认为你没有充分阅读我的问题。我已经尝试过上面相同的方法,至少等效的Config.class.getResourceAsStream(Properties_文件)是不同的。您必须使用Config.class.getClassLoader(),您也可以阅读此主题
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");