i made some extension to the EmbeddedTomcat so it reads the
RequestInterceptors out of the server.xml
to make it run with jboss you have to add the following lines to server.xml:
<RequestInterceptor
className="org.apache.tomcat.request.Jdk12Interceptor" />
<RequestInterceptor
className="org.jboss.tomcat.security.JbossRealm"
debug="0" />
and any security inteceptor you like to have.
i am working with tomcat 3.2b8
markus
ps: hopes that you check it in to cvs.
the mail system doesnt let me send an attachment so i have to send it here
in the body:
EmbeddedTomcat.java
/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.tomcat;
//import java.io.IOException;
import java.io.File;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.InetAddress;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.beans.*;
import javax.management.*;
import javax.servlet.ServletContext;
import org.jboss.logging.Log;
import org.jboss.logging.Logger;
import org.jboss.util.ServiceMBeanSupport;
import org.jboss.ejb.DeploymentException;
import org.apache.tomcat.startup.EmbededTomcat;
import org.apache.tomcat.context.WebXmlReader;
import org.apache.tomcat.context.PolicyInterceptor;
import org.apache.tomcat.context.LoaderInterceptor;
import org.apache.tomcat.context.DefaultCMSetter;
import org.apache.tomcat.context.WorkDirInterceptor;
import org.apache.tomcat.context.LoadOnStartupInterceptor;
import org.apache.tomcat.request.SessionInterceptor;
import org.apache.tomcat.request.SimpleMapper1;
import org.apache.tomcat.request.InvokerInterceptor;
import org.apache.tomcat.request.StaticInterceptor;
import org.apache.tomcat.request.AccessInterceptor;
import org.apache.tomcat.request.Jdk12Interceptor;
import org.apache.tomcat.session.StandardSessionInterceptor;
import org.apache.tomcat.core.RequestInterceptor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
/**
* A service to launch tomcat from JMX.
*
* This uses the class org.apache.tomcat.startup.EmbededTomcat, which
means
* that we can add and remove tomcat "contexts" on the fly.
*
* If you use this service, Tomcat's server.xml file will NOT be
processed, so
* you have to add all contexts through JMX.
*
* @see <related>
* @author <a href="mailto:[EMAIL PROTECTED]">Sebastien
Alborini</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Kevin Lewis</a>
* @version $Revision: 1.8 $
*/
public class EmbeddedTomcatService extends ServiceMBeanSupport
implements EmbeddedTomcatServiceMBean, MBeanRegistration {
// Constants -----------------------------------------------------
public static final String NAME = "EmbeddedTomcat";
// Attributes ----------------------------------------------------
// the tomcat launcher
private EmbededTomcat embededTomcat;
// the path to tomcat. We need it to set the root context
String tomcatHome;
// the port tomcat must listen to
int port;
// the config file to be used
String configFile;
// repository for deployed URLs and the associated servletContexts
Hashtable deployedURLs = new Hashtable();
final Log log = Log.createLog(NAME);
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
public EmbeddedTomcatService()
{
this(null, 8080);
}
public EmbeddedTomcatService(String configFile, int port)
{
this.configFile = configFile;
this.port = port;
}
public void setPort(int port)
{
this.port = port;
}
public int getPort()
{
return port;
}
public void setConfigFile(String configFile)
{
this.configFile = configFile;
}
public String getConfigFile()
{
return configFile;
}
// Public --------------------------------------------------------
public ObjectName getObjectName(MBeanServer server, ObjectName name)
throws javax.management.MalformedObjectNameException {
return new ObjectName(OBJECT_NAME);
}
public String getName() {
return NAME;
}
public void startService() throws Exception {
Log.setLog(log);
Logger.log("Testing if Tomcat is present....");
// tomcat (jdk12Interceptor) seems sets the
contextclassloader but doesn't restore the original one
ClassLoader oldCcl =
Thread.currentThread().getContextClassLoader();
try {
// We need the tomcat home to set tomcat's working
dir / ROOT context
Class tomcatClass;
try {
tomcatClass =
Class.forName("org.apache.tomcat.startup.EmbededTomcat");
} catch (Exception e) {
Logger.log("failed");
Logger.log("Tomcat not found. You need
tomcat 3.2b4+");
throw new Exception("start failed");
}
URL tomcatUrl =
tomcatClass.getProtectionDomain().getCodeSource().getLocation();
tomcatHome = new File(new
File(tomcatUrl.getFile()).getParent()).getParent();
// Locate server.xml
if (configFile == null)
{
configFile = new File(tomcatHome, "conf/server.xml").toString();
System.out.println("Config file set to:"+configFile);
}
try {
// Using EmbededTomcat instead of
org.apache.tomcat.startup.Tomcat
// allows us to add/remove contexts on the
fly
embededTomcat = new EmbededTomcat();
Logger.log("OK");
} catch (NoClassDefFoundError e) {
Logger.log("failed");
Logger.log("org.apache.tomcat.startup.EmbededTomcat wasn't found. Be sure to
have your CLASSPATH correctly set");
Logger.log("You need tomcat 3.2b4+ to use
this service");
throw e;
}
// Initialize the EmbededTomcat object.
// See javadoc in
org.apache.tomcat.startup.EmbededTomcat
// set debug (Warning: setting debug to anything
higher gave me lot of exceptions)
embededTomcat.setDebug(0);
embededTomcat.setWorkDir(tomcatHome);
addContextInterceptors(embededTomcat);
// set the interceptors.
// addInterceptors(embededTomcat);
// Create an instance of the DocumentBuilderFactory
System.out.println(Class.forName("javax.xml.parsers.DocumentBuilderFactory")
);
com.sun.xml.parser.DocumentBuilderFactoryImpl
docBuilderFactory = new com.sun.xml.parser.DocumentBuilderFactoryImpl();
//Get the DocumentBuilder from the factory that we just got
above.
com.sun.xml.parser.DocumentBuilderImpl docBuilder =
(com.sun.xml.parser.DocumentBuilderImpl)docBuilderFactory.newDocumentBuilder
();
// parse the config file
// ROB: it�s not bulletproof maybe should validate against a dtd
file
Document doc = docBuilder.parse(new File(configFile));
NodeList requestInterceptors =
doc.getElementsByTagName("RequestInterceptor");
String classTag="className";
Object[] args=new Object[1];
// add them
for(int i=0; i<requestInterceptors.getLength(); i++)
{
Element context = (Element)requestInterceptors.item(i);
RequestInterceptor interceptor = (RequestInterceptor)
Beans.instantiate(Thread.currentThread().getContextClassLoader(),context.get
Attribute(classTag));
// System.out.println("adding RequestInterceptor:
"+interceptor.getClass().toString());
PropertyDescriptor[]
props=Introspector.getBeanInfo(interceptor.getClass()).getPropertyDescriptor
s();
for(int j=0;j<props.length;j++)
{
if(props[j].getWriteMethod() != null)
{
String
value=context.getAttribute(props[j].getName()).trim();
if(value!=null && value.length()>0)
{
Class
argu[]=props[j].getWriteMethod().getParameterTypes();
if(argu[0].toString().equals("int"))
args[0]=new Integer(value);
else if(argu[0].toString().equals("boolean"))
args[0]=new Boolean(value);
else
args[0]=value;
props[j].getWriteMethod().invoke(interceptor,args);
}
}
}
embededTomcat.addRequestInterceptor(interceptor);
}
// add root context
deploy("/", "file:" + tomcatHome + "/webapps/ROOT");
// get list with contexts
NodeList contexts = doc.getElementsByTagName("Context");
// add them
for(int i=0; i<contexts.getLength(); i++) {
Element context = (Element)contexts.item(i);
String path = context.getAttribute("path");
String docBase = context.getAttribute("docBase");
File f = new File(docBase);
// check if docbase is of type /something in which case add
tomcat home
if(!f.exists()) {
deploy(path, "file:" + tomcatHome + "/" + docBase);
//System.out.println("file:" + tomcatHome + "/" + docBase);
}
// otherwise if it�s c:/something do nothing
else {
deploy(path, "file:" + docBase);
//System.out.println("file:" + docBase);
}
}
// add endpoint (web service)
embededTomcat.addEndpoint(port, null, null);
// start
embededTomcat.start();
} finally {
// restore the original value of the ccl.
Thread.currentThread().setContextClassLoader(oldCcl);
// unset log for the main thread.
// tomcat's child threads have a copy of it anyway.
Log.unsetLog();
}
}
public void stopService() {
// NYI in tomcat for now (3.2b6)
embededTomcat.stop();
}
// warURL could be given as a java.net.URL, but the JMX RI's html
adaptor can't
// show inputs for URLs in HTML forms.
public void deploy(String ctxPath, String warUrl) throws
DeploymentException {
Log.setLog(log);
try {
// add the context
ServletContext servletCtx =
embededTomcat.addContext(ctxPath, new URL(warUrl));
// init the context
embededTomcat.initContext(servletCtx);
// keep track of deployed contexts for undeployment
deployedURLs.put(warUrl, servletCtx);
} catch (Error e)
{
e.printStackTrace();
throw e;
} catch (Exception e) {
e.printStackTrace();
throw new DeploymentException(e.getMessage());
} finally {
Log.unsetLog();
}
}
public void undeploy(String warUrl) throws DeploymentException {
Log.setLog(log);
try {
// find the javax.servlet.ServletContext in the
repository
ServletContext servletCtx =
(ServletContext)deployedURLs.get(warUrl);
if (servletCtx == null)
throw new DeploymentException("URL " +
warUrl + " is not deployed");
// remove the context
embededTomcat.removeContext(servletCtx);
} catch (Exception e) {
throw new DeploymentException(e.getMessage());
} finally {
Log.unsetLog();
}
}
public boolean isDeployed(String warUrl) {
return deployedURLs.containsKey(warUrl);
}
// Protected -----------------------------------------------------
protected void addContextInterceptors(EmbededTomcat tomcat) {
// Since we add one non-default interceptor, we have to
specif them all
// the list comes from
org.apache.tomcat.startup.EmbededTomcat
WebXmlReader webXmlI=new WebXmlReader();
webXmlI.setValidate( false );
tomcat.addContextInterceptor( webXmlI );
PolicyInterceptor polI=new PolicyInterceptor();
tomcat.addContextInterceptor( polI );
polI.setDebug(0);
LoaderInterceptor loadI=new LoaderInterceptor();
tomcat.addContextInterceptor( loadI );
tomcat.addContextInterceptor( new
org.jboss.tomcat.naming.JbossWebXmlReader() );
ContextClassLoaderInterceptor ccli = new
ContextClassLoaderInterceptor();
tomcat.addContextInterceptor(ccli);
DefaultCMSetter defaultCMI=new DefaultCMSetter();
tomcat.addContextInterceptor( defaultCMI );
WorkDirInterceptor wdI=new WorkDirInterceptor();
tomcat.addContextInterceptor( wdI );
LoadOnStartupInterceptor loadOnSI=new
LoadOnStartupInterceptor();
tomcat.addContextInterceptor( loadOnSI );
}
protected void addSecurityRequestInterceptors(EmbededTomcat tomcat) {
}
/**
* depredicated. getting the interceptors out of the xml file
* JndiRequestInterceptor will be added through server.xml
*/
protected void addRequestInterceptors(EmbededTomcat tomcat) {
// Debug
// LogEvents logEventsI=new LogEvents();
// addRequestInterceptor( logEventsI );
// this one is custom
// set context class loader
// New interceptor.
tomcat.addRequestInterceptor( new
org.jboss.tomcat.naming.JndiRequestInterceptor() );
SessionInterceptor sessI=new SessionInterceptor();
tomcat.addRequestInterceptor( sessI );
SimpleMapper1 mapI=new SimpleMapper1();
tomcat.addRequestInterceptor( mapI );
mapI.setDebug(0);
InvokerInterceptor invI=new InvokerInterceptor();
tomcat.addRequestInterceptor( invI );
invI.setDebug(0);
StaticInterceptor staticI=new StaticInterceptor();
tomcat.addRequestInterceptor( staticI );
mapI.setDebug(0);
tomcat.addRequestInterceptor( new
StandardSessionInterceptor());
// access control ( find if a resource have constraints )
AccessInterceptor accessI=new AccessInterceptor();
tomcat.addRequestInterceptor( accessI );
accessI.setDebug(0);
Jdk12Interceptor jdk12I=new Jdk12Interceptor();
tomcat.addRequestInterceptor( jdk12I );
addSecurityRequestInterceptors(tomcat);
}
// Private -------------------------------------------------------
private void addInterceptors(EmbededTomcat tomcat) {
try {
addContextInterceptors(tomcat);
addRequestInterceptors(tomcat);
}
catch (Throwable e) {
System.out.println("Error initializing embedded Tomcat
service.");
e.printStackTrace(System.out);
}
}
}