代码之家  ›  专栏  ›  技术社区  ›  mmaceachran

slf4j-Spring MVC测试中的logback NullPointer

  •  1
  • mmaceachran  · 技术社区  · 10 年前

    我正在运行一些单元测试,我要使用SLF4J和logback。

    这是相关的pom.xml

         <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.2.6-RELEASE</version>
        <exclusions>
          <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
          </exclusion>
        </exclusions>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.7</version>
    </dependency>   
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.7.21</version>
    </dependency>
    

    下面是日志和堆栈跟踪:

    20:29:16,293 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:/code/web/target/test-classes/logback-test.xml]
    20:29:16,387 |-ERROR in ch.qos.logback.core.joran.event.SaxEventRecorder@7a1ebcd8 - Unexpected exception while parsing XML document. java.lang.NullPointerException
    at java.lang.NullPointerException
    at  at org.xml.sax.helpers.LocatorImpl.<init>(LocatorImpl.java:103)
    at  at ch.qos.logback.core.joran.event.SaxEvent.<init>(SaxEvent.java:31)
    at  at ch.qos.logback.core.joran.event.StartEvent.<init>(StartEvent.java:27)
    at  at ch.qos.logback.core.joran.event.SaxEventRecorder.startElement(SaxEventRecorder.java:106)
    at  at org.allcolor.xml.parser.CShaniSaxParser.parseStartTag(CShaniSaxParser.java:1393)
    at  at org.allcolor.xml.parser.CXmlParser.parseSTARTTag(CXmlParser.java:1405)
    at  at org.allcolor.xml.parser.CXmlParser.parse(CXmlParser.java:682)
    at  at org.allcolor.xml.parser.CShaniSaxParser.parse(CShaniSaxParser.java:767)
    at  at javax.xml.parsers.SAXParser.parse(SAXParser.java:392)
    at  at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:59)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:141)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:103)
    at  at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:53)
    at  at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:75)
    at  at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:150)
    at  at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84)
    at  at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
    at  at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
    at  at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
    at  at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
    at  at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
    at  at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
    at  at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
    at  at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685)
    at  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<clinit>(SpringJUnit4ClassRunner.java:91)
    at  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at  at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at  at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    

    以及logback-test.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <Pattern>.%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %n
                </Pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>TRACE</level>
            </filter>
        </appender>
        <root>
            <level value="INFO" />
            <appender-ref ref="consoleAppender" />
        </root> 
        <logger name="com.me.ControllerTester" level="debug" additivity="false">
            <appender-ref ref="consoleAppender" />
        </logger>
    </configuration>
    

    现在我已经检查了依赖关系树,没有任何冲突。我尝试过搞乱SAX解析器的版本。

    XML在我看来很好。我一定有点矛盾。。。

    有什么想法吗?

    1 回复  |  直到 10 年前
        1
  •  2
  •   tony19 thanksd    10 年前

    logback 使用 SAXParserFactory.newInstance() ,它有一个查找过程,用于确定要使用的实现。看来 org.allcolor.xml.parser.CShaniSaxParser 正在基于此查找在您的环境中选择:

    public static SAXParserFactory newInstance()

    获取的新实例 SAXParserFactory 。此静态方法创建一个新的工厂实例。此方法使用以下有序查找过程来确定 SAXParserFactory公司 要加载的实现类:

    • 使用 javax.xml.parsers.SAXParserFactory 系统属性。
    • 使用JRE目录中的属性文件“lib/jaxp.properties”。此配置文件是标准配置文件 java.util.Properties 格式并包含实现类的完全限定名,键是上面定义的系统属性。jaxp。JAXP实现只读取一次属性文件,然后缓存其值以供将来使用。如果第一次尝试读取文件时该文件不存在,则不会进一步尝试检查其是否存在。无法更改jaxp中任何属性的值。属性。
    • 如果可用,请使用ServicesAPI(如JAR规范中所述)来确定类名。服务API将在文件中查找类名 META-INF/services/javax.xml.parsers.SAXParserFactory 在运行库可用的jar中。
    • 平台默认值 SAXParserFactory公司 例子

    一旦应用程序获得对 SAXParserFactory公司 它可以使用工厂来配置和获取解析器实例。

    故障排除提示

    设置 jaxp.debug system属性将导致此方法向system打印大量调试消息。对它在做什么和在看什么有错误。

    如果加载时遇到问题 DocumentBuilders ,尝试:

    java -Djaxp.debug=1 YourProgram ....

    尝试切换到标准SAX解析器(例如 Apache Xerces )通过设置 javax.xml.parsers.SAXParserFactory 单元测试的系统属性:

    -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl