Randy Watler wrote:
I am currently experimenting with the Java 1.5 remote JMX/MBeans for use in our build process. In particular, I am attempting to install a new context in a running Tomcat5.18 server using an external Ant task/application, (without using the manager webapp). I found code in the admin webapp to do this, but it does not seem to configure the WebappClassLoader instances associated with the context correctly. By examining the Tomcat5 source, I was able to find a workaround that seems to function correctly, but I would like to verify it with someone who knows how the MBean API is intended to be used.

Here is what the admin webapp is doing to install a new context:

ObjectName host = ... ;
String contextPath = "/testsite" ;
String webappDocBase = "/tmp/testsite" ;
String newContext = (String)
mbeanServer.invoke( factory, "createStandardContext", new Object [] { host.toString(), "/testsite",
"/tmp/testsite" },
new String [] { "java.lang.String", "java.lang.String",
"java.lang.String" } ) ;
mbeanServer.invoke( factory, "createWebappLoader",
new Object [] { newContext },
new String [] { "java.lang.String" } ) ;
mbeanServer.invoke( factory, "createStandardManager",
new Object [] { newContext },
new String [] { "java.lang.String" } ) ;


Accessing a JSP page or servlet in this new context results in trying to use an unstarted ClassLoader that results in a ThreadDeath exception. The following MBeans are created, (note the odd Catalina:type=Loader instance):

Catalina:type=Loader,path=/testsite,host=localhost
Catalina:type=NamingResources,resourcetype=Context,path=/testsite,host=local
host
Standalone:j2eeType=Servlet,name=CookiesDump,WebModule=//localhost/testsite,
J2EEApplication=none,J2EEServer=none
Standalone:j2eeType=Servlet,name=default,WebModule=//localhost/testsite,J2EE
Application=none,J2EEServer=none
Standalone:j2eeType=Servlet,name=jsp,WebModule=//localhost/testsite,J2EEAppl
ication=none,J2EEServer=none
Standalone:j2eeType=WebModule,name=//localhost/testsite,J2EEApplication=none
,J2EEServer=none
Standalone:type=Cache,host=localhost,path=/testsite
Standalone:type=Loader,path=/testsite,host=localhost
Standalone:type=Manager,path=/testsite,host=localhost

If the code above is modified to remove the call to "createWebappLoader", the webapp is loaded correctly and the exported MBeans match what is available when the same webapp is loaded if deployed directly in the Tomcat5 webapps directory at startup:

Catalina:type=NamingResources,resourcetype=Context,path=/testsite,host=local
host
Standalone:j2eeType=Servlet,name=CookiesDump,WebModule=//localhost/testsite,
J2EEApplication=none,J2EEServer=none
Standalone:j2eeType=Servlet,name=default,WebModule=//localhost/testsite,J2EE
Application=none,J2EEServer=none
Standalone:j2eeType=Servlet,name=jsp,WebModule=//localhost/testsite,J2EEAppl
ication=none,J2EEServer=none
Standalone:j2eeType=WebModule,name=//localhost/testsite,J2EEApplication=none
,J2EEServer=none
Standalone:type=Cache,host=localhost,path=/testsite
Standalone:type=Loader,path=/testsite,host=localhost
Standalone:type=Manager,path=/testsite,host=localhost

It seems that the invocation of the "createWebappLoader" operation ends up creating an extra Loader instance somehow that confuses the ClassLoader configuration for the webapp context. I verified that the "createStandardContext" operation does indeed construct a Loader when start() is invoked on the context container. Apparently, either the "createStandardContext" is not supposed to create the Loader or the "createWebappLoader" operation should not be used in the admin webapp... then again, I might be missing something!

Can anyone clarify how the "createStandardContext" should be invoked?

You can look at the JBoss integration code for examples.


Part of the code:

      String objectNameS = config.getCatalinaDomain()
          + ":j2eeType=WebModule,name=//" +
         ((hostName == null) ? "localhost" : hostName)
          + ctxPath + ",J2EEApplication=none,J2EEServer=none";

ObjectName objectName = new ObjectName(objectNameS);

      server.createMBean("org.apache.commons.modeler.BaseModelMBean",
         objectName, new Object[]{config.getContextClassName()},
         new String[]{"java.lang.String"});

server.setAttribute(objectName, new Attribute("docBase", url.getFile()));

      server.setAttribute(objectName, new Attribute
         ("defaultWebXml", "web.xml"));

      if (config.isUseJBossWebLoader())
      {
         WebCtxLoader webLoader = new WebCtxLoader(loader);
         webLoader.setWarURL(url);
         server.setAttribute(objectName, new Attribute
            ("loader", webLoader));
      }
      else
      {
         server.setAttribute(objectName, new Attribute
            ("parentClassLoader", loader));
      }

      server.setAttribute(objectName, new Attribute
         ("delegate", new Boolean(getJava2ClassLoadingCompliance())));

      // Init the container; this will also start it
      server.invoke(objectName, "init", new Object[]{}, new String[]{});

There's additional code, but this is for creating a basic context, and configuring its classloader. The Tomcat code which allows doing this is a lot more recent than the harcoded admin webapp methods, and is more JavaBean like.

--
xxxxxxxxxxxxxxxxxxxxxxxxx
R�my Maucherat
Developer & Consultant
JBoss Group (Europe) S�RL
xxxxxxxxxxxxxxxxxxxxxxxxx

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to