文章
问答
冒泡
spring boot 集成 flink-sql-connector-oracle-cdc 启动报错解决

场景
在spring boot 工程中集成 flink-sql-connector-oracle-cdc ,由于在resource目录下配置了logack-spring.xml文件,启动报错如下

Logging system failed to initialize using configuration from 'null'
java.lang.IllegalStateException: Could not initialize Logback logging from classpath:logback-spring.xml
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:168)
    at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:80)
    at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:132)
    at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:329)
    at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85)
    at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114)
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:343)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:301)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
    at ms.alioth.ServeApplication.main(ServeApplication.java:19)
Caused by: ch.qos.logback.core.joran.spi.JoranException: Parser configuration error occurred
    at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:89)
    at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:57)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:151)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:110)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:53)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.configureByResourceUrl(LogbackLoggingSystem.java:188)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:165)
    ... 22 more
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:82)
    ... 28 more

如果没有自己配置logback-spring.xml 是不会报错的
网上的通常说法是基于oracle-jdbc的,但是在flink-sql-connector-oracle-cdc 中 ,oracle.xml 下的包是直接打在 代码中的,无法通过maven的exclusion 来排除。


根据报错信息,定位到代码处

private SAXParser buildSaxParser() throws JoranException {
    try {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setValidating(false);
        //spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        spf.setNamespaceAware(true);
        return spf.newSAXParser();
    } catch (Exception pce) {
        String errMsg = "Parser configuration error occurred";
        addError(errMsg, pce);
        throw new JoranException(errMsg, pce);
    }
}
public static SAXParserFactory newInstance() {
    return FactoryFinder.find(
            /* The default property name according to the JAXP spec */
            SAXParserFactory.class,
            /* The fallback implementation class name */
            "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
}
static <T> T find(Class<T> type, String fallbackClassName)
    throws FactoryConfigurationError
{
    final String factoryId = type.getName();
    dPrint(()->"find factoryId =" + factoryId);

    // Use the system property first
    try {
        String systemProp = SecuritySupport.getSystemProperty(factoryId);
        if (systemProp != null) {
            dPrint(()->"found system property, value=" + systemProp);
            return newInstance(type, systemProp, null, true);
        }
    }
    catch (SecurityException se) {
        if (debug) se.printStackTrace();
    }

    // try to read from $java.home/conf/jaxp.properties
    try {
        if (firstTime) {
            synchronized (cacheProps) {
                if (firstTime) {
                    String configFile = SecuritySupport.getSystemProperty("java.home") + File.separator +
                        "conf" + File.separator + "jaxp.properties";
                    File f = new File(configFile);
                    firstTime = false;
                    if (SecuritySupport.doesFileExist(f)) {
                        dPrint(()->"Read properties file "+f);
                        cacheProps.load(SecuritySupport.getFileInputStream(f));
                    }
                }
            }
        }
        final String factoryClassName = cacheProps.getProperty(factoryId);

        if (factoryClassName != null) {
            dPrint(()->"found in ${java.home}/conf/jaxp.properties, value=" + factoryClassName);
            return newInstance(type, factoryClassName, null, true);
        }
    }
    catch (Exception ex) {
        if (debug) ex.printStackTrace();
    }

    // Try Jar Service Provider Mechanism
    T provider = findServiceProvider(type);
    if (provider != null) {
        return provider;
    }
    if (fallbackClassName == null) {
        throw new FactoryConfigurationError(
            "Provider for " + factoryId + " cannot be found");
    }

    dPrint(()->"loaded from fallback value: " + fallbackClassName);
    return newInstance(type, fallbackClassName, null, true);
}


从代码可以看到,如果设置了系统属性,则根据系统属性去找,否则根据spi去查询,再没有就根据传参过来的fallbackClassName去拿。
由于无法移除依赖,这里我们之间通过静态代码块,指定实现类。

static {
    System.setProperty("javax.xml.parsers.SAXParserFactory","com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
}

这样就可以解决报错问题

flink
java

关于作者

落雁沙
非典型码农
获得点赞
文章被阅读