Tomcat5 MBeans/JMX context creation

2004-03-01 Thread Randy Watler
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



Re: Tomcat5 MBeans/JMX context creation

2004-03-01 Thread Remy Maucherat
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 

Re: Tomcat5 MBeans/JMX context creation

2004-03-01 Thread Randy Watler

Remy Maucherat wrote:

 Randy Watler wrote:

 I am currently experimenting with the Java 1.5 remote JMX/MBeans for 
 use in our build process.
 ...
 Can anyone clarify how the createStandardContext should be invoked?


 You can look at the JBoss integration code for examples.
 ...
 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.

Remy,

Note that I am using the JMX remote Out-of-the-box Java 1.5 Monitoring 
and Management, so some of the JBoss setup may not apply, (like the 
ClassLoader configuration that passes object instances). Here is what I 
am trying:

// create context
mbeanServer.createMBean( org.apache.commons.modeler.BaseModelMBean, 
context,
 new Object [] { 
org.apache.catalina.core.StandardContext },
 new String [] { java.lang.String } ) ;
mbeanServer.setAttribute( context, new Attribute( docBase, 
/tmp/testsite ) ) ;
mbeanServer.setAttribute( context, new Attribute( path, /testsite ) ) ;

// start context
mbeanServer.invoke( context, start, null, null ) ;

Unfortunately, the createMBean call above throws the following exception:

javax.management.ReflectionException: The MBean class could not be 
loaded by the default loader repository
at 
com.sun.jmx.mbeanserver.MBeanInstantiatorImpl.findClassWithDefaultLoaderRepo
sitory(MBeanInstantiatorImpl.java:61)
at 
com.sun.jmx.mbeanserver.MBeanInstantiatorImpl.instantiate(MBeanInstantiatorI
mpl.java:378)
at 
com.sun.jmx.mbeanserver.JmxMBeanServer.instantiate(JmxMBeanServer.java:1011)
at 
com.sun.jmx.remote.security.MBeanServerAccessController.createMBean(MBeanSer
verAccessController.java:167)
at 
javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.
java:1418)
at 
javax.management.remote.rmi.RMIConnectionImpl.access+100(RMIConnectionImpl.j
ava:81)
at 
javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMICon
nectionImpl.java:1301)
at java.security.AccessController.doPrivileged(Native Method)
at 
javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConne
ctionImpl.java:1395)
at 
javax.management.remote.rmi.RMIConnectionImpl.createMBean(RMIConnectionImpl.
java:337)
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:494)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport+1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at 
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:7
01)
at java.lang.Thread.run(Thread.java:566)
at 
sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteC
all.java:247)
at 
sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
at com.sun.jmx.remote.internal.PRef.invoke(Unknown Source)
at 
javax.management.remote.rmi.RMIConnectionImpl_Stub.createMBean(Unknown 
Source)
at 
javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.createM
Bean(RMIConnector.java:662)
at InstallTask.execute(InstallTask.java:84)
... 1 more
Caused by: java.lang.ClassNotFoundException: 
org.apache.commons.modeler.BaseModelMBean
at 
com.sun.jmx.mbeanserver.ClassLoaderRepositorySupport.loadClass(ClassLoaderRe
positorySupport.java:208)
at 
com.sun.jmx.mbeanserver.ClassLoaderRepositorySupport.loadClass(ClassLoaderRe
positorySupport.java:128)
at 
com.sun.jmx.mbeanserver.MBeanInstantiatorImpl.findClassWithDefaultLoaderRepo
sitory(MBeanInstantiatorImpl.java:58)
at 
com.sun.jmx.mbeanserver.MBeanInstantiatorImpl.instantiate(MBeanInstantiatorI
mpl.java:378)
at 
com.sun.jmx.mbeanserver.JmxMBeanServer.instantiate(JmxMBeanServer.java:1011)
at 
com.sun.jmx.remote.security.MBeanServerAccessController.createMBean(MBeanSer
verAccessController.java:167)
at 
javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.
java:1418)
at 
javax.management.remote.rmi.RMIConnectionImpl.access+100(RMIConnectionImpl.j
ava:81)
at 
javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMICon
nectionImpl.java:1301)
at java.security.AccessController.doPrivileged(Native Method)
at 
javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConne
ctionImpl.java:1395)
at