We are using Child first classloader to avoid jar conflicts and load the classes from a particular path. With the service loader and the xml-apis jar in the child classloader's classpath, we are facing issues.
xerces2 jars service loader creates an object of javax.xml.parsers.DocumentBuilderFactory with org.apache.xerces.jaxp.DocumentBuilderFactoryImpl if DocumentBuilderFactoryImpl not present in the classpath, It loads the fallback class present in the rt.jar. Under normal circumstances, the code works fine.
With using child first classloader on top of System classloader, we facing issues in the following lines.
DocumentBuilderFactory newInstance()
the above line is used for creating the object. The method details are,
public static DocumentBuilderFactory newInstance() {
return (DocumentBuilderFactory)FactoryFinder.find(DocumentBuilderFactory.class, "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
}
The first argument to the find method,
DocumentBuilderFactory.class
creates a class object for javax.xml.parsers.DocumentBuilderFactory class. but even we have set the classloader with child classloader, .class operator loads the class with System classloader and creates a class object, not with the current child classloader on top
.
Inside the service loader, creates an object for org.apache.xerces.jaxp.DocumentBuilderFactoryImpl with child classloader and the child first classloader loads the javax.xml.parsers.DocumentBuilderFactory class.
As the DocumentBuilderFactory.class loaded in the system classloader and the org.apache.xerces.jaxp.DocumentBuilderFactoryImpl class loaded in the top child classloaders are not assignable to each other as both javax.xml.parsers.DocumentBuilderFactory is created in separate classloaders.
My question is,
Is there any way to avoid the DocumentBuilder.class from loading to the system classloader?
For child first classloader we are using the following library https://github.com/kamranzafar/JCL/