Wednesday, April 27, 2005

Getting Spring to Work Inside Sonic XIS XML Server

I encountered an exception trying to use Spring inside the Sonic XIS XML server:
java.lang.ExceptionInInitializerError:
java.lang.NullPointerException
   at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:144)
   at org.springframework.core.io.ClassPathResource.getFile(ClassPathResource.java:154)
   ...
This issue happened because XIS has no context class load for the current thread. In order to workaround this problem, I updated the ClassPathResource class in the spring-core.jar file. I created the following method:
   private ClassLoader getClassLoader() {
       ClassLoader rv = this.classLoader;
       if (rv == null) {
           // no class loader specified -> use thread context class loader
           rv = Thread.currentThread().getContextClassLoader();
       }
       if (rv == null) {
           rv = getClass().getClassLoader();
       }
       return rv;
   }
And updated the following two methods:
   public InputStream getInputStream() throws IOException {
       InputStream is = null;
       if (this.clazz != null) {
           is = this.clazz.getResourceAsStream(this.path);
       }
       else {
           is = getClassLoader().getResourceAsStream(this.path);
       }
       if (is == null) {
           throw new FileNotFoundException(
                   getDescription() + " cannot be opened because it does not exist");
       }
       return is;
   }

   public URL getURL() throws IOException {
       URL url = null;
       if (this.clazz != null) {
           url = this.clazz.getResource(this.path);
       }
       else {
           url = getClassLoader().getResource(this.path);
       }
       if (url == null) {
           throw new FileNotFoundException(
                   getDescription() + " cannot be resolved to URL because it does not exist");
       }
       return url;
   }
After these changes, it was a simple matter to create my custom spring-core-wwre.jar file.