为什么在初始化Spring时会出现NullPointerException异常

4

我在服务器上运行批处理作业时遇到了问题,但是在我的开发工作站上从Eclipse运行正常。

我使用Roo设置了Spring环境,创建了一个实体,并创建了一个批处理程序来执行一些操作,在我的开发机器上进行了充分测试。我初始化了我的上下文并执行操作,但是当我在服务器上运行批处理时,上下文没有正确地初始化。以下是代码:

public class TestBatch {

    private static ApplicationContext context;


    @SuppressWarnings("unchecked")
    public static void main(final String[] args) {

            context = new ClassPathXmlApplicationContext("/META-INF/spring/applicationContext.xml");
            try {
                @SuppressWarnings("unused")
                TestBatch app = new TestBatch();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    }

    public void TestBatch() { /** Do Something using the context **/ }

}

以下是日志和异常信息:

2010-02-16 11:54:16,072 [main] INFO  org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6037fb1e: startup date [Tue Feb 16 11:54:16 CET 2010]; root of context hierarchy
Exception in thread "main" java.lang.ExceptionInInitializerError
    at org.springframework.context.support.AbstractRefreshableApplicationContext.createBeanFactory(AbstractRefreshableApplicationContext.java:194)
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:127)
    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:458)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:388)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at tld.mydomain.myproject.batch.TestBatch.main(TestBatch.java:51)
Caused by: java.lang.NullPointerException
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.<clinit>(DefaultListableBeanFactory.java:103)
    ... 7 more

有什么想法或提示吗?我的类路径设置为$ PROJECTHOME / target / classes,所有依赖项都在$ PROJECTHOME / target / lib中,并使用“export CLASSPATH = $ PROJECTHOME / target / classes; java -Djava.endorsed.dirs = $ PROJECTHOME / target / lib tld.mydomain.myproject.batch.TestBatch”执行。
我的设置有什么问题吗?当我从Eclipse运行时,没有问题,但是当我将其部署到我想要运行它的服务器上并按上述方式运行它时,我遇到了这个问题。因为它可以从Eclipse运行,所以我相信我的配置文件都没问题,但是我怎样才能调试出问题的原因呢?也许我有一些配置错误或者开发工作站和服务器之间存在不匹配?或者这是一种非常奇怪的说法,表示找不到文件,如果是这样,我该如何确保它找到正确的文件?
我真的很期待听到您对解决这个问题的建议。
干杯
Nik

我建议查看DefaultListableBeanFactory.java文件,第103行。或者更好的方法是在那里设置一个断点。 - Eli Acherkan
请ç،®ن؟‌applicationContext.xmlه·²ç»ڈو”¾ç½®هœ¨وœچهٹ،ه™¨ن¸ٹم€‚ - Bozho
应用程序上下文位于 $CLASSPATH/META-INF/spring/applicationContext.xml。关于设置断点,当我在服务器上运行时,我该如何做?在我的工作站上通过IDE运行时没有错误。 - niklassaers
$CLASSPATH被实现成什么了?我猜是webapp/WEB-INF/classes/吧? - Bozho
4个回答

7
问题的原因是-Djava.endorsed.dirs=$PROJECTHOME/target/liborg.springframework.beans.factory.support.DefaultListableBeanFactory包含以下代码:
static {
    ClassLoader cl = DefaultListableBeanFactory.class.getClassLoader();
    try {
        javaxInjectProviderClass = cl.loadClass("javax.inject.Provider"); //Line 103
    }
    catch (ClassNotFoundException ex) {
        // JSR-330 API not available - Provider interface simply not supported then.
    }
}

它会引发NullPointerException错误,因为在通过-Djava.endorsed.dirs加载类时getClassLoader()返回null。来自javadoc的说明如下:
一些实现可能使用null表示引导类加载器。
因此,请改用-classpath(带有所有jar的明确指定)而不是-Djava.endorsed.dirs。

非常感谢,那解决了我的问题。但是现在我又回到了一个巨大的类路径!有没有办法保持我的类路径干净整洁,同时确保我的程序能够正确执行? - niklassaers
1
不用担心类路径的样子。它只是传递给程序的一个参数。通常情况下,您甚至不需要手动设置它,大多数应用程序都通过脚本或其他方法来构建它。 - matt b
1
这也可能是Rational Application Developer/Eclipse中的一个问题,您已将JAR添加到标记为系统库的用户库中。真是太令人宽慰了,我还以为Spring肯定不会发布像spring-test框架这样在RAD中无法正常工作的东西……结果是我的问题。 - Ryan Ransford
刚刚遇到了这个问题。Ryan的建议不要将Spring作为系统用户库解决了我的问题,所以感谢他! - user1541338
你好,您的回答中指定的步骤我不太明白,请问能否说明一下如何操作? - swapyonubuntu

2

在添加用户库时会出现java.lang.ExceptionInInitializerError异常。我在HibernateSpring中也遇到了同样的问题。所以我删除了名为"Spring"的用户库,然后手动添加JAR包,这样就完美解决了。


1
在Eclipse中:
如果您正在使用Spring Jars作为用户库(例如SpringLib),请检查Spring的用户库是否被添加(或已选中)为系统库(添加到引导类路径)。如果是,请取消勾选。

0
只需将JAR文件添加到引用库中,而不是用户库中。这对我有用!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接