Skip to content

native-image output cannot find com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl #684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dsilvasc opened this issue Sep 23, 2018 · 7 comments
Assignees

Comments

@dsilvasc
Copy link

To reproduce this, first compile the coverage report tool from gradle-scoverage with graal native-image:

$ /Library/Java/JavaVirtualMachines/graalvm-ce-1.0.0-rc6/Contents/Home/bin/native-image -cp $HOME/.gradle/caches/modules-2/files-2.1/gradle.plugin.org.scoverage/gradle-scoverage/2.3.0/33683401ef9a69601a29e01eb885c64e070bd160/gradle-scoverage-2.3.0.jar:$HOME/.gradle/caches/modules-2/files-2.1/org.scoverage/scalac-scoverage-plugin_2.12/1.3.1/4faa316a42fb0cff1e6fa40915f332f43116aaea/scalac-scoverage-plugin_2.12-1.3.1.jar:$HOME/.gradle/caches/modules-2/files-2.1/org.scoverage/scalac-scoverage-runtime_2.12/1.3.1/b51a70c1da41e07de83506ea12dc25fb994740a5/scalac-scoverage-runtime_2.12-1.3.1.jar:$HOME/.gradle/caches/modules-2/files-2.1/org.scala-lang.modules/scala-xml_2.12/1.0.5/a2b2afbeea86818a911b05851bb11d7d4840bb75/scala-xml_2.12-1.0.5.jar:$HOME/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala-library/2.12.3/f2e496f21af2d80b48e0a61773f84c3a76a0d06f/scala-library-2.12.3.jar:$HOME/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala-compiler/2.12.3/b6b9ca202fc8405260d30e703b9790e91c75cd85/scala-compiler-2.12.3.jar:$HOME/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala-reflect/2.12.3/a017f8f606e5f433df4f8d5efc20ce39c2fe8330/scala-reflect-2.12.3.jar org.scoverage.SingleReportApp

Then try it out:

$ ./org.scoverage.singlereportapp ./some/project ./some/project/build/scoverage ./some/project/build/reports/scoverage true true true false
Exception in thread "main" javax.xml.parsers.FactoryConfigurationError: Provider com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl not found
	at java.lang.Throwable.<init>(Throwable.java:265)
	at java.lang.Error.<init>(Error.java:70)
	at javax.xml.parsers.FactoryConfigurationError.<init>(FactoryConfigurationError.java:92)
	at javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:200)
	at javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:152)
	at javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:277)
	at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:127)
	at scala.xml.factory.XMLLoader.parser(XMLLoader.scala:28)
	at scala.xml.factory.XMLLoader.parser$(XMLLoader.scala:27)
	at scala.xml.XML$.parser(XML.scala:60)
	at scala.xml.factory.XMLLoader.loadString(XMLLoader.scala:60)
	at scala.xml.factory.XMLLoader.loadString$(XMLLoader.scala:60)
	at scala.xml.XML$.loadString(XML.scala:60)
	at scoverage.Serializer$.deserialize(Serializer.scala:88)
	at scoverage.Serializer$.deserialize(Serializer.scala:131)
	at scoverage.Serializer.deserialize(Serializer.scala)
	at org.scoverage.SingleReportApp.main(SingleReportApp.java:36)
	at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:163)
Caused by: java.lang.ClassNotFoundException: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
	at java.lang.Throwable.<init>(Throwable.java:287)
	at java.lang.Exception.<init>(Exception.java:84)
	at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:75)
	at java.lang.ClassNotFoundException.<init>(ClassNotFoundException.java:82)
	at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:51)
	at com.oracle.svm.core.hub.DynamicHub.forName(DynamicHub.java:1010)
	at javax.xml.parsers.FactoryFinder.getProviderClass(FactoryFinder.java:124)
	at javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:188)
	... 14 more
@cstancu
Copy link
Member

cstancu commented Sep 25, 2018

@dsilvasc it looks like you are trying to allocate classes with Class.forName() at run time, e.g., com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl, without having registered them for reflection at image build time. Please see the reflection documentation for details.

@dsilvasc
Copy link
Author

In this case the call to the JDK's javax.xml.parsers.SAXParserFactory.newInstance() eventually does some reflection.

The Oracle JDK docs don't mention the classes it will try to load:
https://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/SAXParserFactory.html#newInstance()

In general how should users determine which internal classes Oracle's implementation of the JDK might try to load at runtime?

@skrat
Copy link

skrat commented Feb 26, 2019

I tried adding it to the reflection config JSON, but then it complains during build time that no such method (parse) is found. Gave up

@cstancu
Copy link
Member

cstancu commented Dec 23, 2019

To automatically discover reflectively used elements you can now use the native-image-agent. Please re-open if you still see the error after generating the config with the agent.

@cstancu cstancu closed this as completed Dec 23, 2019
@sbrannen
Copy link

sbrannen commented Mar 4, 2020

This still occurs with GraalVM CE 20.0 when using the native image agent (e.g., -agentlib:native-image-agent=experimental-class-loader-support,config-output-dir=...), resulting in the following.

com.sun.org.apache.xerces.internal.utils.ConfigurationError: Provider com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl not found
       com.sun.org.apache.xerces.internal.utils.ObjectFactory.newInstance(ObjectFactory.java:163)
       com.sun.org.apache.xerces.internal.utils.ObjectFactory.newInstance(ObjectFactory.java:143)
       com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory.getInstance(SchemaDVFactory.java:73)
       com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory.getInstance(SchemaDVFactory.java:57)
       com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.reset(XMLSchemaLoader.java:1024)

Note that the method in question (com.sun.org.apache.xerces.internal.utils.ObjectFactory.findProviderClass(String, ClassLoader, boolean)) looks like this in JDK 1.8 update 231.

    /**
     * Find a Class using the specified ClassLoader
     */
    public static Class findProviderClass(String className, ClassLoader cl,
                                      boolean doFallback)
        throws ClassNotFoundException, ConfigurationError
    {
        //throw security exception if the calling thread is not allowed to access the package
        //restrict the access to package as speicified in java.security policy
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            if (className.startsWith(JAXP_INTERNAL) ||
                    className.startsWith(STAX_INTERNAL)) {
                cl = null;
            } else {
                final int lastDot = className.lastIndexOf(".");
                String packageName = className;
                if (lastDot != -1) packageName = className.substring(0, lastDot);
                security.checkPackageAccess(packageName);
            }
        }
        Class providerClass;
        if (cl == null) {
            //use the bootstrap ClassLoader.
            providerClass = Class.forName(className, false, ObjectFactory.class.getClassLoader());
        } else {
            try {
                providerClass = cl.loadClass(className);
            } catch (ClassNotFoundException x) {
                if (doFallback) {
                    // Fall back to current classloader
                    ClassLoader current = ObjectFactory.class.getClassLoader();
                    if (current == null) {
                        providerClass = Class.forName(className);
                    } else if (cl != current) {
                        cl = current;
                        providerClass = cl.loadClass(className);
                    } else {
                        throw x;
                    }
                } else {
                    throw x;
                }
            }
        }

        return providerClass;
    }

Please reopen this issue.

@sbrannen
Copy link

sbrannen commented Mar 4, 2020

Perhaps effectively a duplicate of #1387.

@rlconst
Copy link

rlconst commented Mar 8, 2025

I will add for Google to to index. Whoever will try to use POI with graalvm and get org.apache.xerces.impl.dv.ObjectFactory$ConfigurationError: Provider org.apache.xerces.impl.dv.dtd.DTDDVFactoryImpl not found should do this.

  1. on Linux run java -jar -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image build/libs/yourlib-1.0-SNAPSHOT-all.jar src/test/resources/input.xlsx out.json
  2. add this to build gradle
graalvmNative {
    binaries {
        named("main") {
            useFatJar.set(true)
            buildArgs.add("-H:-CheckToolchain")
            // CP1252 is missing
            // https://github.com/apache/poi/blob/trunk/poi/src/main/java/org/apache/poi/poifs/filesystem/FileMagic.java#L133
            buildArgs.add("-H:+AddAllCharsets")
            configurationFileDirectories.from(file("src/main/resources/META-INF/native-image/"))
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants