You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by st...@cygnite.com on 2004/01/22 15:52:18 UTC

Class loader issues with Struts on ATG Dynamo 5.6.1

Hello to all.

I've been using Struts for a while now, with great success! Thanks to the 
developers! However, I've found a bit of a problem using Struts 1.1 with 
Dynamo 5.6.1 Apologies in advance if this is more appropriate to the user 
mailing list - I wasn't sure!

Dynamo implements J2EE 1.2, which includes the Servlet 2.2 specs, which I 
gather can sometimes be a bit vague on the subject of web application 
context class loaders. I've been trying to get the tag libraries working 
correctly. When using say a <bean:define> tag, an exception is thrown when 
trying to instantiate the page by dynamo:

[ERROR] MessageResourcesFactory - -MessageResourcesFactory.createFactory 
<java.lang.ClassNotFoundException: 
org.apache.struts.util.PropertyMessageResourcesFactory>java.lang.ClassNotFoundException: 
org.apache.struts.util.PropertyMessageResourcesFactory
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
        at 
org.apache.struts.util.RequestUtils.applicationClass(RequestUtils.java:182)
        at 
org.apache.struts.util.MessageResourcesFactory.createFactory(MessageResourcesFactory.java:192)
        at 
org.apache.struts.util.MessageResources.getMessageResources(MessageResources.java:576)
        at 
org.apache.struts.util.RequestUtils.<clinit>(RequestUtils.java:138)
        at 
org.apache.struts.util.MessageResourcesFactory.createFactory(MessageResourcesFactory.java:192)
        at 
org.apache.struts.util.MessageResources.getMessageResources(MessageResources.java:576)
        at 
org.apache.struts.taglib.bean.DefineTag.<clinit>(DefineTag.java:88)
        at java.lang.Class.newInstance0(Native Method)
        at java.lang.Class.newInstance(Class.java:237)
        at 
atg.servlet.pagecompile.taglib.TagPool.checkOut(TagPool.java:111)
        at 
atg.servlet.pagecompile.taglib.TagManager.checkOutTag(TagManager.java:210)
(Extra lines cropped, and are all ATG classes)

Looking through the code for RequestUtils.applicationClass() the code 
seems to try and get the current context loader:

        // Look up the class loader to be used
        ClassLoader classLoader = 
Thread.currentThread().getContextClassLoader();
        if (classLoader == null) {
            classLoader = RequestUtils.class.getClassLoader();
        }

        // Attempt to load the specified class
        return (classLoader.loadClass(className));

However, looking at the trace, I'm guessing that the getContextClassLoader 
method returns the system-wide class loader (which has no knowledge of the 
WEB-INF/lib contents). One fix which seems to work (at least here) is just 
to comment that code and replace with

        return Class.forName(className);

The main question is whether this fix is appropriate - and whether there 
are any other workarounds or fixes available - presumably I would have to 
put this in all the other classes where the code using the 
getContextClassLoader was? I'm guessing that there was a good reason not 
to use Class.forName anyway (if so, I'd be interested to know why?)

thanks in advance,

Steve.

Re: Class loader issues with Struts on ATG Dynamo 5.6.1

Posted by Kris Schneider <kr...@dotech.com>.
How 'bout a custom RequestProcessor:

public void process(HttpServletRequest request,
                    HttpServletResponse response)
  throws IOException, ServletException {
  Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
  super.process(request, response);
}

Quoting steve.storey@cygnite.com:

> Hello to all.
> 
> I've been using Struts for a while now, with great success! Thanks to the 
> developers! However, I've found a bit of a problem using Struts 1.1 with 
> Dynamo 5.6.1 Apologies in advance if this is more appropriate to the user 
> mailing list - I wasn't sure!
> 
> Dynamo implements J2EE 1.2, which includes the Servlet 2.2 specs, which I 
> gather can sometimes be a bit vague on the subject of web application 
> context class loaders. I've been trying to get the tag libraries working 
> correctly. When using say a <bean:define> tag, an exception is thrown when 
> trying to instantiate the page by dynamo:
> 
> [ERROR] MessageResourcesFactory - -MessageResourcesFactory.createFactory 
> <java.lang.ClassNotFoundException: 
>
org.apache.struts.util.PropertyMessageResourcesFactory>java.lang.ClassNotFoundException:
> 
> org.apache.struts.util.PropertyMessageResourcesFactory
>         at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
>         at java.security.AccessController.doPrivileged(Native Method)
>         at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
>         at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
>         at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)
>         at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
>         at 
> org.apache.struts.util.RequestUtils.applicationClass(RequestUtils.java:182)
>         at 
>
org.apache.struts.util.MessageResourcesFactory.createFactory(MessageResourcesFactory.java:192)
>         at 
>
org.apache.struts.util.MessageResources.getMessageResources(MessageResources.java:576)
>         at 
> org.apache.struts.util.RequestUtils.<clinit>(RequestUtils.java:138)
>         at 
>
org.apache.struts.util.MessageResourcesFactory.createFactory(MessageResourcesFactory.java:192)
>         at 
>
org.apache.struts.util.MessageResources.getMessageResources(MessageResources.java:576)
>         at 
> org.apache.struts.taglib.bean.DefineTag.<clinit>(DefineTag.java:88)
>         at java.lang.Class.newInstance0(Native Method)
>         at java.lang.Class.newInstance(Class.java:237)
>         at 
> atg.servlet.pagecompile.taglib.TagPool.checkOut(TagPool.java:111)
>         at 
> atg.servlet.pagecompile.taglib.TagManager.checkOutTag(TagManager.java:210)
> (Extra lines cropped, and are all ATG classes)
> 
> Looking through the code for RequestUtils.applicationClass() the code 
> seems to try and get the current context loader:
> 
>         // Look up the class loader to be used
>         ClassLoader classLoader = 
> Thread.currentThread().getContextClassLoader();
>         if (classLoader == null) {
>             classLoader = RequestUtils.class.getClassLoader();
>         }
> 
>         // Attempt to load the specified class
>         return (classLoader.loadClass(className));
> 
> However, looking at the trace, I'm guessing that the getContextClassLoader 
> method returns the system-wide class loader (which has no knowledge of the 
> WEB-INF/lib contents). One fix which seems to work (at least here) is just 
> to comment that code and replace with
> 
>         return Class.forName(className);
> 
> The main question is whether this fix is appropriate - and whether there 
> are any other workarounds or fixes available - presumably I would have to 
> put this in all the other classes where the code using the 
> getContextClassLoader was? I'm guessing that there was a good reason not 
> to use Class.forName anyway (if so, I'd be interested to know why?)
> 
> thanks in advance,
> 
> Steve.

-- 
Kris Schneider <ma...@dotech.com>
D.O.Tech       <http://www.dotech.com/>

---------------------------------------------------------------------
To unsubscribe, e-mail: struts-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-dev-help@jakarta.apache.org