How to disable accessExternalDTD and entityExpansionLimit warnings with logback
Asked Answered
R

5

31

I'm using logback with groovy and get lots of warnings showing up when parsing xml. I am aware of the bug in JDK1.7_u45 that is causing this.

Warning:  org.apache.xerces.parsers.SAXParser: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.
Warning:  org.apache.xerces.parsers.SAXParser: Property 'http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit' is not recognized.

Is there any way to turn off this log warnings from showing up in DEBUG? I tried writing a filter using Filter, but didn't help.

Rist answered 22/8, 2014 at 18:2 Comment(3)
If you are processing large amounts of XML, your logs get filled with thousands of those messages. I would really like to get rid of this, too. I already tried Java 8 without success, a newer version of Xerces than 2.11 is not in sight. Any suggestions?Sakai
Could you guys please provide a runnable example?Shawndashawnee
i also getting same exceptionSpontoon
P
28

This is a known bug in the JRE that reports this as an warning. See bug reports here and here

The issue happens only when you have xerces jar in your classpath, the xerces implementation does not recognize the property and throws an exception on org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.setProperty() which results in a warning log (to System.err) from the com.sun.org.apache.xalan.internal.xsltc.compiler.Parser.parse()

The easy (if possible) solution is remove xerces jar from your classpath.

Your log filter does not work since the error is never sent to slf4j. Which kind of suggests a convoluted way of fixing the issue - redirect System.err to slf4j and then use a logging filter on it.

Sample code to reproduce the issue (based on the issue report):

import java.io.IOException;
import java.net.URL;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;

public class XercesTest {
    public static void main(String[] args) throws IOException, TransformerConfigurationException {
        TransformerFactory tf = TransformerFactory.newInstance();
        URL xsl = MainClass.class.getResource("build.xsl");
        StreamSource stylesheetSource = new StreamSource(
            xsl.openStream(), xsl.toExternalForm());
        tf.newTransformer(stylesheetSource);
    }
}

build.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <!-- TODO: Auto-generated template -->
    </xsl:template>
</xsl:stylesheet>

And maven dependency:

<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
</dependency>
Pedology answered 6/7, 2015 at 20:31 Comment(4)
Thanks, that worked. It was tricky because the error was in a plugin. So I followed this procedure to exclude the dependency from the plugin: #6029034Vidovic
Do we have any other solution for this? Because this not worked for me.Darceydarci
On my side, I could not remove xerces from the classpath, but strangely, I could resolve the problem by adding xalan to the classpath.Paltry
@JörgEisfeld how did adding Xalan resolve the issue? I am facing the same problem during a Java 17 migration when adding an external Xerces as Maven dependencyHighcolored
T
2

I also had this error in a project. As I understand it, newer versions of the JRE have the Xerces implementation built into it. More importantly, the JRE version properly supports the accessExternalDTD and entityExpansionLimit properties.

Because I had a downstream dependency that was including xercesImpl.jar in my war file, my solution was to just yank it using the code below in my build.gradle and let the JRE implementation of xerces take over in the class path.

warApplication {
    from '/WEB-INF/lib'
        exclude 'xercesImpl*.jar'
}
Toddtoddie answered 25/10, 2017 at 1:3 Comment(0)
S
2

If it is not possible to remove xerces from the classpath, you can be more explicit about which factory you want to use, thus avoiding pulling in xerces. Here are two ways of resolving specific factories:

public static SchemaFactory getSchemaFactory() {
  return schemaFactory =
    SchemaFactory.newInstance(
        "http://www.w3.org/2001/XMLSchema",
        "com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory",
        null);
}

public static TransformerFactory getTransformerFactory() {
  try {
    final Class<?> transformerFactoryImplClass =
      TransformerFactory.class
          .getClassLoader().loadClass("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
    final Method factoryGetter =
      transformerFactoryImplClass.getDeclaredMethod("newTransformerFactoryNoServiceLoader");
    return (TransformerFactory) factoryGetter.invoke(null);
  } catch (ClassNotFoundException
    | NoSuchMethodException
    | IllegalAccessException
    | InvocationTargetException e) {
    // fallback in case com.sun.* is not available
    return TransformerFactory.newInstance();
  }
}
Schizogenesis answered 5/6, 2019 at 11:32 Comment(0)
D
1

Old question I know, just wanted to post a shortcut. As mentioned in the answer by Dana Britzman newer versions of the JRE have the Xerces and Xalan implementation built into it. More importantly, the JRE version properly supports the accessExternalDTD and entityExpansionLimit properties.

I needed a xalan implementation, and did as below

TransformerFactory tf = com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newInstance("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl", null);
Donahue answered 20/9, 2020 at 17:7 Comment(3)
I tried to give a different implementation as you suggested but it shows the same error as the above property not recognizedWorn
I'm using it in my code, and it's working just fine. Which version of, which JRE did you use? Be specific before down votingDonahue
Which Xerces version is used by the JRE?Highcolored
S
0

To get around this with a recent JDK8 version, I used this code:

  DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", this.getClass().getClassLoader());

The internal packaged classes are part of the JDK. This will guarantee that it use the JDK classes and won't try to use any other versions that are hanging around (which happens with Weblogic server for instance)

Solly answered 22/3, 2021 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.