You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Leon Rosenberg <ro...@googlemail.com> on 2006/09/05 16:40:16 UTC

Implementing own Loader

Hi,

I'm trying to implement an own Loader wraped around the WebappLoader.
My goal is to modify the classloader and to substitute all created
servlets by own proxies.

However, I started creating an own loader and proxying requests to the
WebappLoader but failed :-)

My context.xml contains:

<Context path="/moskitodemo" docBase="${catalina.home}/webapps/moskitodemo"
        debug="0" >
	<Loader className="net.java.dev.moskito.tomcat.MoskitoLoader"
delegate="false" reloadable="true"/>
</Context>

my loader:

public class MoskitoLoader implements Loader{
	
	private Loader tomcatLoader;

	public MoskitoLoader(ClassLoader classLoader){
		System.out.println("MINIT: "+classLoader);
		tomcatLoader = new WebappLoader(classLoader);
	}

I'm proxying the calls to the WebappLoader like this:

	public ClassLoader getClassLoader() {
		ClassLoader ret = tomcatLoader.getClassLoader();
		return ret;
	}

However, loading of the application doesn't work. The getClassLoader
method returns null and I have multiple errors in the logfile starting
with:
SEVERE: Error deploying configuration descriptor moskitodemo.xml
java.lang.NullPointerException
        at java.util.Hashtable.put(Hashtable.java:401)
        at org.apache.naming.ContextBindings.bindClassLoader(ContextBindings.java:265)
        at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:232)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4118)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
        at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:608)
        at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:535)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:470)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1112)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1021)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
        at org.apache.catalina.core.StandardService.start(StandardService.java:450)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:551)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:275)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)

I suppose I have to do some more than just instantiate a WebappLoader,
but where can I find what? Any points to docs?

Or do I have to implement all the Lifecycle and proxy it to the WebappLoader?

regards
Leon

P.S. I was trying to do this from the docs without looking into the
sourcecode, if this is a wrong approach please tell :;-)

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Implementing own Loader

Posted by Leon Rosenberg <ro...@googlemail.com>.
Hello Mark,

> Each servlet is invoked via the StandardWrapperValve (accessible via
> JMX) that includes basic performance stats. Is this sufficient?

could you explain your statement a little bit? As far as I see the
Servlet is invoked by the StandardWrapper by Class.newInstance()?
(line 1055).

Maybe I got something wrong?

The basic performance stats aren't sufficent (for me) since they do
not support time-intervals. And I'm usually interested in what my
servlet is doing now. I mean, if my webapp is running for 3 weeks and
the servlet suddenly needs double execution time, i will never see it
in the basic performance stats, since the 3 weeks of running will
level everything (statistically).

Leon

On 9/6/06, Mark Thomas <ma...@apache.org> wrote:
> Leon Rosenberg wrote:
> > However, what I am trying to achieve is to create a wrapper
> > (reflection.Proxy) around each servlet to be able to monitor and
> > measure its performance. The problem is that tomcat provides very nice
> > plugability concepts for the ClassLoader (many thanx for that, guys)
> > but no concept for servlet creation itself.
>
>
> Mark
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Implementing own Loader

Posted by Mark Thomas <ma...@apache.org>.
Leon Rosenberg wrote:
> However, what I am trying to achieve is to create a wrapper
> (reflection.Proxy) around each servlet to be able to monitor and
> measure its performance. The problem is that tomcat provides very nice
> plugability concepts for the ClassLoader (many thanx for that, guys)
> but no concept for servlet creation itself.

Each servlet is invoked via the StandardWrapperValve (accessible via
JMX) that includes basic performance stats. Is this sufficient?

Mark

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Implementing own Loader

Posted by Leon Rosenberg <ro...@googlemail.com>.
Hello Mark,

thank you for the reply.
Meanwhile I found out that replacing the webappClassLoader in the
default webapploader via  loader configuration in context.xml is
sufficent to what I need.

However, what I am trying to achieve is to create a wrapper
(reflection.Proxy) around each servlet to be able to monitor and
measure its performance. The problem is that tomcat provides very nice
plugability concepts for the ClassLoader (many thanx for that, guys)
but no concept for servlet creation itself.

Wouldn't it make sense to refactor the following line from
StandardWrapper (line 1055 in 5.5 branch)

            try {
                servlet = (Servlet) classClass.newInstance();
            } catch (ClassCastException e) {

in a separate class called ServletFactory or something?

interface ServletFactory{
  public Servlet createServlet(Class servletClass) throws. ...;
}

class StandardServletFactory implements ServletFactory{
   public Servlet createServlet(Class servletClass){
     return servletClass.newInstance();
   }
}

I mean that wouldn't be a significant change in the existing codebase,
it wouldn't affect performance, and it would make the servlet
instantiation customizable!

Leon

On 9/6/06, Mark Thomas <ma...@apache.org> wrote:
> Leon Rosenberg wrote:
> > ok, now i added Lifecycle to the implemented interfaces and am proxing
> > the method calls to webapp loader... success is still another thing:
>
> Looks like the associated container hasn't been set. In your shoes I
> would get a debugger out and step through the initialisation of the
> standard loader and the custom one and see where they differ.
>
> Mark
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Implementing own Loader

Posted by Mark Thomas <ma...@apache.org>.
Leon Rosenberg wrote:
> ok, now i added Lifecycle to the implemented interfaces and am proxing
> the method calls to webapp loader... success is still another thing:

Looks like the associated container hasn't been set. In your shoes I
would get a debugger out and step through the initialisation of the
standard loader and the custom one and see where they differ.

Mark


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Implementing own Loader

Posted by Leon Rosenberg <ro...@googlemail.com>.
ok, now i added Lifecycle to the implemented interfaces and am proxing
the method calls to webapp loader... success is still another thing:

SEVERE: Error deploying configuration descriptor moskitodemo.xml
java.lang.NullPointerException
        at org.apache.catalina.loader.WebappLoader.start(WebappLoader.java:614)
        at net.java.dev.moskito.tomcat.MoskitoLoader.start(MoskitoLoader.java:43)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4079)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
        at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:608)
        at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:535)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:470)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1122)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1021)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
        at org.apache.catalina.core.StandardService.start(StandardService.java:450)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:551)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:432)
Sep 5, 2006 7:51:58 PM org.apache.catalina.startup.HostConfig deployWAR

any ideas?
regards
Leon

On 9/5/06, Leon Rosenberg <ro...@googlemail.com> wrote:
> Hi,
>
> I'm trying to implement an own Loader wraped around the WebappLoader.
> My goal is to modify the classloader and to substitute all created
> servlets by own proxies.
>
> However, I started creating an own loader and proxying requests to the
> WebappLoader but failed :-)
>
> My context.xml contains:
>
> <Context path="/moskitodemo" docBase="${catalina.home}/webapps/moskitodemo"
>         debug="0" >
>         <Loader className="net.java.dev.moskito.tomcat.MoskitoLoader"
> delegate="false" reloadable="true"/>
> </Context>
>
> my loader:
>
> public class MoskitoLoader implements Loader{
>
>         private Loader tomcatLoader;
>
>         public MoskitoLoader(ClassLoader classLoader){
>                 System.out.println("MINIT: "+classLoader);
>                 tomcatLoader = new WebappLoader(classLoader);
>         }
>
> I'm proxying the calls to the WebappLoader like this:
>
>         public ClassLoader getClassLoader() {
>                 ClassLoader ret = tomcatLoader.getClassLoader();
>                 return ret;
>         }
>
> However, loading of the application doesn't work. The getClassLoader
> method returns null and I have multiple errors in the logfile starting
> with:
> SEVERE: Error deploying configuration descriptor moskitodemo.xml
> java.lang.NullPointerException
>         at java.util.Hashtable.put(Hashtable.java:401)
>         at org.apache.naming.ContextBindings.bindClassLoader(ContextBindings.java:265)
>         at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:232)
>         at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
>         at org.apache.catalina.core.StandardContext.start(StandardContext.java:4118)
>         at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
>         at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
>         at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
>         at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:608)
>         at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:535)
>         at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:470)
>         at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1112)
>         at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310)
>         at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
>         at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1021)
>         at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
>         at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
>         at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
>         at org.apache.catalina.core.StandardService.start(StandardService.java:450)
>         at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)
>         at org.apache.catalina.startup.Catalina.start(Catalina.java:551)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:585)
>         at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:275)
>         at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
>
> I suppose I have to do some more than just instantiate a WebappLoader,
> but where can I find what? Any points to docs?
>
> Or do I have to implement all the Lifecycle and proxy it to the WebappLoader?
>
> regards
> Leon
>
> P.S. I was trying to do this from the docs without looking into the
> sourcecode, if this is a wrong approach please tell :;-)
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org