Announcement Announcement Module
Collapse
No announcement yet.
Advanced question on custom classloaders Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Advanced question on custom classloaders

    Hi,


    I have a simple soap endpoint that works fine when the xml file containing the bean definitions are loaded in the regular way with the default classloader and a simple <import resource=... line.

    However, i need to load some spring beans (including the PayloadRootQNameEndpointMapping mapping definitions) using a custom classloader. This loading is considered an extension to the system we deliver, and we have some hooks within our war to allow for it. Here is the code to give you an idea on how the user defined beans are loaded (xxxx where details removed):

    --------------------------------------

    package xxxx;

    import java.io.File;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLClassLoader;

    import org.apache.log4j.Logger;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAwar e;
    import org.springframework.context.support.ClassPathXmlAp plicationContext;

    import xxxx.PlatformUtils;

    /**
    * This class injects a new classpath/classloader into the system. This is injected during spring bootstrap and
    * therefore falls one under the classloader hierarchy related to the classloader associated with loading spring
    * classes. Note that this class was needed to fix glassfish limitations/quirkyness related to class loading.
    *
    */
    public class AabExternalResource implements ApplicationContextAware {

    private static Logger log = Logger.getLogger(AabExternalResource.class);

    private String jarFileName = null;
    private String xmlResource = null;

    public AabExternalResource(String jarFileName, String xmlResource) {
    this.jarFileName = jarFileName;
    this.xmlResource = xmlResource;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(applicationContext) ;
    // allow the jar file name to be specified as a -D parameter
    String qualifiedJarFile = null;
    String myJarFile = System.getProperty("xxxx.external.jar");

    if(myJarFile != null) {
    qualifiedJarFile = myJarFile;
    } else {
    qualifiedJarFile = PlatformUtils.getRootDir() + "/lib/" + jarFileName;
    }

    File jarFile = new File(qualifiedJarFile);
    if (! jarFile.exists()) {
    log.warn("Jar File: " + qualifiedJarFile + " does not exist. Skipping...");
    return;
    }

    log.info("FRAMEWORK: Loading user defined beans from jar: " + qualifiedJarFile + " XML bean file: " + xmlResource);

    URLClassLoader classLoader = null;
    try {
    classLoader = new URLClassLoader(new URL[] { jarFile.toURI().toURL() }, getClass().getClassLoader());
    } catch (MalformedURLException e1) {
    log.error(e1.getMessage());
    return;
    }

    context.setClassLoader(classLoader);
    context.setConfigLocation(xmlResource);
    context.refresh();

    }


    }

    The above basically lets me create a child classloader under the default spring classloader and loads the beans in the given xmlResource file. Also, the parent applicationContext is specified so that parent beans are visible so everything works quite well. I am able to create new bean definitions with references to existing beans within the system. A great way to extend business logic within a server. However, i also want to extend the soap services. I have some hooks within the war to do this, but i need to be able to define new soap mappings.

    My problem is that none of the mappings defned within the xml are visible. For example:

    --------------

    <bean class="org.springframework.ws.server.endpoint.mapp ing.PayloadRootQNameEndpointMapping">
    <property name="mappings">
    <props>
    <prop
    key="{http://abc.com/abc/schemas}SearchRequest">
    AbcSearchEndpoint
    </prop>
    </props>
    </property>
    <property name="interceptors">
    <bean
    class="org.springframework.ws.server.endpoint.inte rceptor.PayloadLoggingInterceptor" />
    </property>
    </bean>

    -------------------

    The above mapping registers in the system when the xml file is loaded in the typical way, but is not visible when using the custom class loader. Instead i get the no mapping found error.

    I can see the mapping being loaded by the custom classloader, but it does not seem to be visible at runtime when a soap request is sent to the server. Note again that these mappings work fine if i import the beans directly with <import resource=...

    Is there some sort of workaround that will allow PayloadRootQNameEndpointMapping mapping definitions to be registered properly from custom class loaders?

    Tks,
    John
Working...
X