我的Ktor server项目要使用call logging功能,于是通过Gradle导入了最新版本(1.4.4)的logback:

implementation("ch.qos.logback:logback-classic:1.4.4")

然而在启动时报了这样的错误:

ch.qos.logback.core.joran.spi.JoranException: Error during SAX paser configuration. See https://logback.qos.ch/codes.html#saxParserConfiguration
	at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:96)
	at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:62)
	at ch.qos.logback.core.joran.GenericXMLConfigurator.populateSaxEventRecorder(GenericXMLConfigurator.java:178)
	at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:159)
	at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:122)
	at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:65)
	at ch.qos.logback.classic.util.DefaultJoranConfigurator.configureByResource(DefaultJoranConfigurator.java:53)
	at ch.qos.logback.classic.util.DefaultJoranConfigurator.configure(DefaultJoranConfigurator.java:34)
	at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:98)
	at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:77)
	at ch.qos.logback.classic.spi.LogbackServiceProvider.initializeLoggerContext(LogbackServiceProvider.java:50)
	at ch.qos.logback.classic.spi.LogbackServiceProvider.initialize(LogbackServiceProvider.java:41)
	at org.slf4j.LoggerFactory.bind(LoggerFactory.java:152)
	at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:139)
	at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:422)
	at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:408)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
	at io.ktor.server.engine.ApplicationEngineEnvironmentBuilder.<init>(ApplicationEngineEnvironmentJvm.kt:36)
	at io.ktor.server.engine.ApplicationEngineEnvironmentKt.applicationEngineEnvironment(ApplicationEngineEnvironment.kt:48)
	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer(EmbeddedServer.kt:90)
	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer(EmbeddedServer.kt:63)
	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer(EmbeddedServer.kt:38)
	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer$default(EmbeddedServer.kt:30)
	at xxx.ApplicationKt.main(Application.kt:8)
	at xxx.ApplicationKt.main(Application.kt)
Caused by: javax.xml.parsers.ParserConfigurationException: SAX feature 'http://xml.org/sax/features/external-general-entities' not supported.
	at oracle.xml.jaxp.JXSAXParserFactory.setFeature(JXSAXParserFactory.java:272)
	at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:89)
	... 24 more
15:42:54,414 |-INFO in ch.qos.logback.classic.LoggerContext[default] - This is logback-classic version 1.4.4
15:42:54,437 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
15:42:54,448 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/D:/Projects/IDEA/pacs-queuing-backend/build/resources/main/logback.xml]
15:42:54,520 |-ERROR in ch.qos.logback.core.joran.event.SaxEventRecorder@15ff3e9e - Error during SAX paser configuration. See https://logback.qos.ch/codes.html#saxParserConfiguration javax.xml.parsers.ParserConfigurationException: SAX feature 'http://xml.org/sax/features/external-general-entities' not supported.
	at javax.xml.parsers.ParserConfigurationException: SAX feature 'http://xml.org/sax/features/external-general-entities' not supported.
	at 	at oracle.xml.jaxp.JXSAXParserFactory.setFeature(JXSAXParserFactory.java:272)
	at 	at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:89)
	at 	at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:62)
	at 	at ch.qos.logback.core.joran.GenericXMLConfigurator.populateSaxEventRecorder(GenericXMLConfigurator.java:178)
	at 	at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:159)
	at 	at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:122)
	at 	at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:65)
	at 	at ch.qos.logback.classic.util.DefaultJoranConfigurator.configureByResource(DefaultJoranConfigurator.java:53)
	at 	at ch.qos.logback.classic.util.DefaultJoranConfigurator.configure(DefaultJoranConfigurator.java:34)
	at 	at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:98)
	at 	at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:77)
	at 	at ch.qos.logback.classic.spi.LogbackServiceProvider.initializeLoggerContext(LogbackServiceProvider.java:50)
	at 	at ch.qos.logback.classic.spi.LogbackServiceProvider.initialize(LogbackServiceProvider.java:41)
	at 	at org.slf4j.LoggerFactory.bind(LoggerFactory.java:152)
	at 	at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:139)
	at 	at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:422)
	at 	at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:408)
	at 	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
	at 	at io.ktor.server.engine.ApplicationEngineEnvironmentBuilder.<init>(ApplicationEngineEnvironmentJvm.kt:36)
	at 	at io.ktor.server.engine.ApplicationEngineEnvironmentKt.applicationEngineEnvironment(ApplicationEngineEnvironment.kt:48)
	at 	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer(EmbeddedServer.kt:90)
	at 	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer(EmbeddedServer.kt:63)
	at 	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer(EmbeddedServer.kt:38)
	at 	at io.ktor.server.engine.EmbeddedServerKt.embeddedServer$default(EmbeddedServer.kt:30)
	at 	at xxx.ApplicationKt.main(Application.kt:8)
	at 	at xxx.ApplicationKt.main(Application.kt)

本来以为是Ktor server和最新版本的logback不兼容,搜了半天也没见到有类似情况的bug report,只能一直降级logback,降到1.2.5才能正常运行。

但是在我另一个项目中,同样的Ktor和logback版本,却是没有问题的,这就很奇怪了……
于是再搜了一下,最后根据这个页面的回复,才知道原来是跟Oracle的JDBC驱动有关系……

解决方案就如页面中给出的,把xmlparserv2这个module从Oracle JDBC依赖中排除就好了:

implementation("com.oracle.database.jdbc:ojdbc8-production:21.7.0.0") {
    exclude(module = "xmlparserv2")
}
Gradle Kotlin DSL
implementation('com.oracle.database.jdbc:ojdbc8-production:21.7.0.0') {
    exclude(module: 'xmlparserv2')
}
Gradle Groovy DSL