XML validation against XSDs when schema files locate in a WAR

I am trying to validate XML against multiply XSD schemas.

The following code works like a charm if I execute my app as a simple Spring-Boot application:

// init
String[] xsdFileNames = ...
Source[] sources = new Source[xsdFileNames.length];

for (int i = 0; i < xsdFileNames.length; i++) {
    InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsdFileNames[i]);
    String realPath = getClass().getClassLoader().getResource(xsdFileNames[i]).getFile();

    StreamSource streamSource = new StreamSource(inputStream);
    streamSource.setSystemId(realPath );

    sources[i] = streamSource;
}

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(sources);
validator = schema.newValidator();

// validate
String xmlString = ...
StringReader xmlStringReader = new StringReader(xmlString))
Source source = new StreamSource(xmlStringReader);
validator.validate(source);

The systemId of the StreamSource needs to be set otherwise the SAXParser can not see the XSD types come from the 2nd XSD. More info here.

But unfortunately, my WAR needs to run in the Oracle WebLogic Server, and because WebLogic makes a trick with files from WAR the solution above does not work.

WebLogic packs resource files into a _wl_cls_gen.jar, and javax.xml.transform.Source does not able to resolve the path with this magic jar: .../_wl_cls_gen.jar!/schema/main.xsd.

Inside javax.xml.transform.Source there is a java.io.File and it not following this strange path.

This is the value of the realPath variable in case of Spring-Boot:

/home/xxx/dev/workspace/java/xxx/target/classes/schema/main.xsd

And in case of WebLogic:

/u01/oracle/user_projects/domains/DEV_DOMAIN/servers/ADMIN_SERVER/tmp/_WL_user/demo-0.1.0/g369dl/war/WEB-INF/lib/_wl_cls_gen.jar!/schema/main.xsd

Any idea how to handle this?

Answer

try using show-archived-real-path-enabled in weblogic.xml

show-archived-real-path-enabled The show-archived-real-path-enabled element specifies the behavior of getRealPath() for archived Web applications.

When set to true, getRealPath() returns the canonical path of the resource files.

If the show-archived-real-path-enabled element is set to false, the servlet container will return the real path of files in archived Web applications as null.

The default value is false.

https://docs.oracle.com/cd/E24329_01/web.1211/e21049/weblogic_xml.htm#WBAPP611