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?
Randy Watler
Finali Corporation