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>