You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Brett Smith <br...@bml.uk.com> on 2002/09/26 14:36:09 UTC
Embedded Tomcat and Class loader problems
Hi,
Im am trying to embed Tomcat into our application, but without having to
specify all the Tomcat libraries and in the classpath. I am using the code
below, and web pages are served up fine both from the ROOT context and the
'qddgwebclient' context, but when I try and use any servlet that the
'qddgwebclient' contains, Tomcat can't find any of the classes required. The
classes are all in jar's in the WEB-INF/lib directory. Can anyone see
anything wrong with this .....
/**
* Start Tomcat
*
* @throws Exception on any errors
*/
private void startTomcat() throws Exception
{
// File tomcatHome = new File(tomcatConfig.getTomcatHome());
File tomcatHome = new File("C:\\Java\\jakarta-tomcat-4.0.5");
if(!tomcatHome.exists())
throw new Exception("Tomcat could not be located at " +
tomcatHome.getAbsolutePath());
LOGCAT.info("Starting Tomcat from " + tomcatHome.getAbsolutePath());
// Configure catalina.base and home
System.setProperty("catalina.home", tomcatHome.getAbsolutePath());
System.setProperty("catalina.base", tomcatHome.getAbsolutePath());
// Construct the class loaders we will need
ClassLoader commonLoader = null;
ClassLoader catalinaLoader = null;
ClassLoader sharedLoader = null;
// Create the bootstrap class loader
LOGCAT.debug("Creating bootstrap class loader");
ClassLoader bootstrapLoader = new URLClassLoader(
new URL []
{
new File(new File(tomcatHome, "bin"), "bootstrap.jar").toURL()
}, getClass().getClassLoader());
// Get the class loader factory and set up debugging on it
Class classLoaderFactoryClass = Class.forName(
"org.apache.catalina.startup.ClassLoaderFactory",
true, bootstrapLoader);
Method createClassLoaderMethod = classLoaderFactoryClass.getMethod(
"createClassLoader",
new Class []
{
File [].class, File [].class, ClassLoader.class
});
Method setDebugMethod =
classLoaderFactoryClass.getMethod("setDebug",
new Class
[]
{
int.class
});
setDebugMethod.invoke(null, new Object [] { new Integer(9) });
// Create the class loaders
File [] unpacked = new File[1];
File [] packed = new File[1];
unpacked[0] = new File(tomcatHome,
"common" + File.separator + "classes");
packed[0] = new File(tomcatHome, "common" + File.separator + "lib");
LOGCAT.debug("Creating common class loader");
commonLoader = (ClassLoader) (createClassLoaderMethod.invoke(null,
new
Object []
{
unpacked, packed, bootstrapLoader
}));
LOGCAT.debug("Creating catalina class loader");
unpacked[0] = new File(tomcatHome,
"server" + File.separator + "classes");
packed[0] = new File(tomcatHome, "server" + File.separator + "lib");
catalinaLoader = (ClassLoader) (createClassLoaderMethod.invoke(null,
new
Object []
{
unpacked, packed, commonLoader
}));
LOGCAT.debug("Creating shared class loader");
unpacked[0] = new File(tomcatHome, "classes");
packed[0] = new File(tomcatHome, "lib");
sharedLoader = (ClassLoader) (createClassLoaderMethod.invoke(null,
new
Object []
{
unpacked, packed, commonLoader
}));
// Work out the workdir. If the image was created with precompiled
JSP
// pages in the webapp directory, then use that, otherwise use the
// local temporary workpspace and let tomcat compile when it needs
to
File workDir = server.getConfig().getTemporaryDirectory();
// Create the embedded tomcat (all using catalina class loader)
LOGCAT.debug("Locating catalina classes");
Class globalsClass = Class.forName("org.apache.catalina.Globals",
true,
catalinaLoader);
Class loggerClass = Class.forName("org.apache.catalina.Logger",
true,
catalinaLoader);
Class realmClass = Class.forName("org.apache.catalina.Realm", true,
catalinaLoader);
;
Class systemLoggerClass = Class.forName(
"org.apache.catalina.logger.SystemOutLogger",
true, catalinaLoader);
Class memoryRealmClass = Class.forName(
"org.apache.catalina.realm.MemoryRealm",
true, catalinaLoader);
contextClass = Class.forName("org.apache.catalina.Context", true,
catalinaLoader);
engineClass = Class.forName("org.apache.catalina.Engine", true,
catalinaLoader);
Class hostClass = Class.forName("org.apache.catalina.Host", true,
catalinaLoader);
Class deployerClass = Class.forName("org.apache.catalina.Deployer",
true, catalinaLoader);
embeddedClass =
Class.forName("org.apache.catalina.startup.Embedded",
true, catalinaLoader);
Class containerClass =
Class.forName("org.apache.catalina.Container",
true, catalinaLoader);
Class connectorClass =
Class.forName("org.apache.catalina.Connector",
true, catalinaLoader);
Class containerBaseClass = Class.forName(
"org.apache.catalina.core.ContainerBase",
true, catalinaLoader);
Class webappLoaderClass = Class.forName(
"org.apache.catalina.loader.WebappLoader",
true, catalinaLoader);
Class loaderClass = Class.forName("org.apache.catalina.Loader",
true,
catalinaLoader);
// Create an embededd server
LOGCAT.debug("Locating constructor for embedded");
Constructor [] cons = embeddedClass.getConstructors();
Constructor embeddedCon = embeddedClass.getConstructor(
new Class [] { loggerClass,
realmClass });
LOGCAT.debug("Creating embedded");
embedded = embeddedCon.newInstance(
new Object []
{
systemLoggerClass.newInstance(), memoryRealmClass.newInstance()
});
LOGCAT.info("Setting debug level");
Method m = embedded.getClass()
.getMethod("setDebug", new Class [] {
int.class });
m.invoke(embedded,
new Object [] { new
Integer(tomcatConfig.getTomcatDebugLevel()) });
// Create the engine (use the shared loader?)
LOGCAT.info("Creating Tomcat engine");
Method createEngineMethod = embeddedClass.getMethod("createEngine",
null);
engine = createEngineMethod.invoke(embedded, null);
Method setParentClassLoaderMethod = engineClass.getMethod(
"setParentClassLoader",
new Class []
{
ClassLoader.class
});
setParentClassLoaderMethod.invoke(engine,
new Object [] { sharedLoader });
// Create the host
LOGCAT.info("Creating host");
Method createHostMethod = embeddedClass.getMethod("createHost",
new Class []
{
String.class, String.class
});
host = createHostMethod.invoke(embedded,
new Object []
{
"localhost", new File(tomcatHome, "webapps").getAbsolutePath()
});
// Add host to engine
LOGCAT.info("Adding host to engine");
Method addHostToEngineMethod = engineClass.getMethod("addChild",
new Class []
{
containerClass
});
addHostToEngineMethod.invoke(engine, new Object [] { host });
// Create a context
String contextName = "";
String contextDir = tomcatHome.getAbsolutePath() + "/webapps/ROOT";
LOGCAT.debug("Creating context '" + contextName + "' at " +
contextDir);
Method createContextMethod =
embeddedClass.getMethod("createContext",
new Class []
{
String.class, String.class
});
context = createContextMethod.invoke(embedded,
new Object []
{
contextName, contextDir
});
// Set up the context
LOGCAT.debug("Setting up contexts");
Method addParameterMethod = contextClass.getMethod("addParameter",
new Class []
{
String.class, String.class
});
addParameterMethod.invoke(context,
new Object []
{
"javax.servlet.context.tempdir", workDir.getAbsolutePath()
});
Method getServletContextMethod = context.getClass()
.getMethod("getServletContext",
null);
servletContext = getServletContextMethod.invoke(context, null);
Method setAttributeMethod = servletContext.getClass()
.getMethod("setAttribute",
new Class []
{
String.class, Object.class
});
setAttributeMethod.invoke(servletContext,
new Object []
{
"javax.servlet.context.tempdir", workDir.getAbsolutePath()
});
Method setWorkDirMethod = context.getClass()
.getMethod("setWorkDir",
new Class [] {
String.class });
setWorkDirMethod.invoke(context,
new Object [] {
workDir.getAbsolutePath() });
// Add the context to the host
LOGCAT.debug("Adding context to host");
Method addChildMethod = host.getClass()
.getMethod("addChild",
new Class [] {
containerClass });
addChildMethod.invoke(host, new Object [] { context });
// Add engine to embdedd server
LOGCAT.debug("Adding engine to embedded server");
Method addEngineMethod = embedded.getClass()
.getMethod("addEngine",
new Class [] {
engineClass });
addEngineMethod.invoke(embedded, new Object [] { engine });
// Create a connector
LOGCAT.debug("Creating connector");
Method createConnectorMethod = embedded.getClass()
.getMethod("createConnector",
new Class []
{
InetAddress.class, int.class, boolean.class
});
connector = createConnectorMethod.invoke(embedded,
new Object []
{
null, new Integer(tomcatConfig.getTomcatPort()), new
Boolean(false)
});
// Add connector to server
LOGCAT.debug("Adding connector to server");
Method addConnectorMethod = embedded.getClass()
.getMethod("addConnector",
new Class []
{
connectorClass
});
addConnectorMethod.invoke(embedded, new Object [] { connector });
// Add the webclient war
URL qddgwebclientWebappURL = new
File("dist/webapps/qddgwebclient").toURL();
String contextPath = "/qddgwebclient";
Method findDeployedAppMethod = deployerClass.getMethod(
"findDeployedApp",
new Class [] {
String.class });
Object context = findDeployedAppMethod.invoke(host,
new Object [] {
contextPath });
if(context != null)
LOGCAT.warn("qddgwebclient webapp already exists.");
else
{
Method installMethod = deployerClass.getMethod("install",
new Class []
{
String.class, URL.class
});
installMethod.invoke(host,
new Object []
{
contextPath, qddgwebclientWebappURL
});
context = findDeployedAppMethod.invoke(host,
new Object [] {
contextPath });
}
// Start Tomcat
LOGCAT.info("Starting Tomcat");
Method startMethod = embedded.getClass().getMethod("start", null);
startMethod.invoke(embedded, null);
LOGCAT.info("Tomcat started");
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>