I have a complicated set of XSDs, so the end XSD has many <xsd:import> entries, so it requires a resource resolver to locate the referenced XSDs. The resource resolver then needs to be injected into the SchemaFactory. Simplified example:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ndg</groupId>
<artifactId>dummy</artifactId>
<name>NDG test project</name>
<description>NDG test project</description>
<version>0.0.1-SNAPSHOT</version>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
</dependencies>
</project>
Resolver.java
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
public class Resolver implements LSResourceResolver
{
@Override
public LSInput resolveResource (String type, String namespaceURI, String publicId, String systemId, String baseURI)
{
return null;
}
}
Main.java
import javax.xml.validation.SchemaFactory;
public class Main
{
public static final void main (final String [] args)
{
Resolver resolver = new Resolver ();
SchemaFactory schemaFactory = SchemaFactory.newInstance ("http://www.w3.org/2001/XMLSchema");
schemaFactory.setResourceResolver (resolver);
System.out.println ("All ok");
}
}
This runs fine, both under JDK 11 and JDK 17. But if I try to wire the application with Spring, like so:
spring-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >
<bean id="resolver" class="Resolver" />
<bean id="schemaFactory" class="javax.xml.validation.SchemaFactory" factory-method="newInstance">
<constructor-arg value="http://www.w3.org/2001/XMLSchema" />
<property name="resourceResolver" ref="resolver" />
</bean>
</beans>
Spring.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Spring
{
public static final void main (final String [] args)
{
new ClassPathXmlApplicationContext ("/spring-beans.xml");
System.out.println ("All ok");
}
}
Then on JDK 11 it outputs a warning:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.beans.BeanWrapperImpl$BeanPropertyHandler (file:/W:/maven/repository/org/springframework/spring-beans/5.3.22/spring-beans-5.3.22.jar) to method com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.setResourceResolver(org.w3c.dom.ls.LSResourceResolver)
and on JDK 17 such usage of internal types is now illegal and so it fails completely. Note SchemaFactory is an abstract class - the concrete class at runtime is com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory as per the message, so the warning/error is technically correct in that the code is indeed trying to call setResourceResolver on an internal com.sun class.
What I don't understand is:
- Why does it work directly in my Main class but not from Spring? Surely they're both just calling the same setResourceResolver method.
- If it is a problem with Spring, then do they not have JDK 17 support yet? I read Spring 5.3+ should be fine with JDK 17.
- Is there any solution other than waiting for Spring 6? (will that even solve it?)