Embedding Tomcat Into Java Applications
来源:互联网 发布:社区网站源码 编辑:程序博客网 时间:2024/06/06 12:32
Embedding Tomcat Into Java Applications
In this article, we'll extend our Tomcat discussions to the application level by creating a Java application that manages an embedded version of the Tomcat JSP/servlet container. Tomcat can be broken down into a set of containers, each with their own purpose. These containers are by default configured using the server.xml
file. When embedding, you will not be using this file; therefore, you will need to assemble instances of these containers programmatically. The following XML code snippet contains the hierarchy of the Tomcat containers:
<Server> <Service> <Connector /> <Engine> <Host> <Context /> </Host> </Engine> </Service></Server>
Note: Each of the previously listed elements contains attributes to set their appropriate behaviors, but for our purposes, only the element hierarchies and relationships are important.
This is the structure that we need to create with our embedded application. The <Server>
and <Service>
elements of this structure are going to be implicitly created, therefore we do not have to create these objects ourselves. The steps to create the remainder of the container structure are listed below.
These are the same steps that we must perform in order to create our own embedded version of the Tomcat container:
- Create an instance of an
org.apache.catalina.Engine
; this object represents the<Engine>
element above and acts as a container to the<Host>
element. - Create an
org.apache.catalina.Host
object, which represents a virtual host, and add this instance to theEngine
object. - Now you need to create n-number of
org.apache.catalina.Context
objects that will represent each Web application in thisHost
. - Once each of your
Context
s are created, you then need to add each of the createdContext
s to the previously createdHost
. For our example, we'll create a singleContext
that will represent ouronjava
application. - The final step is to create an
org.apache.catalina.Connector
object and associate it with the previously createdEngine
. TheConnector
object is the object that actually receives a request from the calling client.
To create this application, we'll leverage some existing Tomcat classes that have been developed to ease this type of integration. The main class we will use is the org.apache.catalina.startup.Embedded
class, which can be found in the <CATALINA_HOME>/src/catalina/src/share/org/apache/catalina/startup
directory. The following source listing contains our sample application that builds these containers using theorg.apache.catalina.startup.Embedded
class.
package onjava;import java.net.URL;import org.apache.catalina.Connector;import org.apache.catalina.Context;import org.apache.catalina.Deployer;import org.apache.catalina.Engine;import org.apache.catalina.Host;import org.apache.catalina.logger.SystemOutLogger;import org.apache.catalina.startup.Embedded;import org.apache.catalina.Container;public class EmbeddedTomcat { private String path = null; private Embedded embedded = null; private Host host = null; /** * Default Constructor * */ public EmbeddedTomcat() { } /** * Basic Accessor setting the value of the context path * * @param path - the path */ public void setPath(String path) { this.path = path; } /** * Basic Accessor returning the value of the context path * * @return - the context path */ public String getPath() { return path; } /** * This method Starts the Tomcat server. */ public void startTomcat() throws Exception { Engine engine = null; // Set the home directory System.setProperty("catalina.home", getPath()); // Create an embedded server embedded = new Embedded(); // print all log statments to standard error embedded.setDebug(0); embedded.setLogger(new SystemOutLogger()); // Create an engine engine = embedded.createEngine(); engine.setDefaultHost("localhost"); // Create a default virtual host host = embedded.createHost("localhost", getPath() + "/webapps"); engine.addChild(host); // Create the ROOT context Context context = embedded.createContext("", getPath() + "/webapps/ROOT"); host.addChild(context); // Install the assembled container hierarchy embedded.addEngine(engine); // Assemble and install a default HTTP connector Connector connector = embedded.createConnector(null, 8080, false); embedded.addConnector(connector); // Start the embedded server embedded.start(); } /** * This method Stops the Tomcat server. */ public void stopTomcat() throws Exception { // Stop the embedded server embedded.stop(); } /** * Registers a WAR with the container. * * @param contextPath - the context path under which the * application will be registered * @param warFile - the URL of the WAR to be * registered. */ public void registerWAR(String contextPath, URL warFile) throws Exception { if ( contextPath == null ) { throw new Exception("Invalid Path : " + contextPath); } if( contextPath.equals("/") ) { contextPath = ""; } if ( warFile == null ) { throw new Exception("Invalid WAR : " + warFile); } Deployer deployer = (Deployer)host; Context context = deployer.findDeployedApp(contextPath); if (context != null) { throw new Exception("Context " + contextPath + " Already Exists!"); } deployer.install(contextPath, warFile); } /** * Unregisters a WAR from the web server. * * @param contextPath - the context path to be removed */ public void unregisterWAR(String contextPath) throws Exception { Context context = host.map(contextPath); if ( context != null ) { embedded.removeContext(context); } else { throw new Exception("Context does not exist for named path : + contextPath); } } public static void main(String args[]) { try { EmbeddedTomcat tomcat = new EmbeddedTomcat(); tomcat.setPath("d:/jakarta-tomcat-4.0.1"); tomcat.startTomcat(); URL url = new URL("file:D:/jakarta-tomcat-4.0.1" + "/webapps/onjava"); tomcat.registerWAR("/onjava", url); Thread.sleep(1000000); tomcat.stopTomcat(); System.exit(0); } catch( Exception e ) { e.printStackTrace(); } }}
You should begin your examination of the EmbeddedTomcat
application source with the main()
method. This method first creates an instance of the EmbeddedTomcat
class. It then sets the path of the Tomcat installation that will be hosting our Tomcat instance. This path is equivalent to the <CATALINA_HOME>
environment variable. The next action performed by the main()
method is to invoke thestartTomcat()
method. This is the method that implements the container-construction steps described earlier. The steps performed by this method are listed below.
The
main()
method begins by setting the system property to the value of the path attribute:// Set the home directory System.setProperty("catalina.home", getPath());
Note:Make sure you use the value of
<CATALINA_HOME>
as the directory value passed to thesetPath()
method.The next step performed by this method is to create an instance of the
Embedded
object and set the debug level and current logger.// Create an embedded server embedded = new Embedded(); embedded.setDebug(5); // print all log statments to standard error embedded.setLogger(new SystemOutLogger());
Note:The debug level should be
0
, when deploying a production Web application. Setting the debug level to0
reduces the amount of logging performed by Tomcat, which will improve performance significantly.After the application has an instance of the
Embedded
object, it creates an instance of anorg.apache.catalina.Engine
and sets the name of the default host. TheEngine
object represents the entire Catalina servlet container.// Create an engine engine = embedded.createEngine(); engine.setDefaultHost("localhost");
After an
Engine
has been instantiated, we create anorg.apache.catalina.Host
object, namedlocalhost
, with a path pointing to the<CATALINA_HOME>/webapps/
directory, and add it theEngine
object. TheHost
object defines the virtual hosts that are contained in each instance of a Catalina Engine.// Create a default virtual host host = embedded.createHost("localhost", getPath() + "/webapps"); engine.addChild(host);
The next step performed by the
startTomcat()
method is to create anorg.apache.catalina.Context
object, which represents theROOT
Web application packaged with Tomcat, and add it the to the previously createdHost
. TheROOT
Web application is the only application that will be installed by default.// Create the ROOT context Context context = embedded.createContext("", getPath() + "/webapps/ROOT"); host.addChild(context);
The next step adds the
Engine
containing the createdHost
andContext
to theEmbedded
object.// Install the assembled container hierarchy embedded.addEngine(engine);
After the engine is added to the
Embedded
object, thestartTomcat()
method creates anorg.apache.catalina.Connector
object and associates it with the previously createdEngine
. The<Connector>
element defines the class that does the actual handling of requests and responses to and from a calling client application. In the following snippet, an HTTP connector that listens to port 8080 is created and added to theEmbedded
object.// Assemble and install a default HTTP connector Connector connector = embedded.createConnector(null, 8080, false); embedded.addConnector(connector);
The final step performed by the
startTomcat()
method starts the Tomcat container.embedded.start();
When startTomcat()
returns, the main method calls the registerWAR()
method, which installs the previously deployed onjava
application to the Embedded
object. The URL used in this example can point to any Webapp directory that follows the specification for Java Servlet 2.2 and later.
URL url = new URL("file:D:/jakarta-tomcat-4.0.1" + "/webapps/onjava"); tomcat.registerWAR("/onjava", url);
The main application is then put to sleep to allow the embedded server time to service requests. When the application awakes, the embedded server is stopped and the application exits.
To test this application, you must complete the following steps:
- Compile the
EmbeddedTomcat.java
class. - Make sure all other instances of Tomcat are shut down.
- Add the following jar files, all of which can be found in the Tomcat installation, to your application classpath.
- <CATALINA_HOME>/bin/bootstrap.jar
- <CATALINA_HOME>/server/lib/catalina.jar
- <CATALINA_HOME>/server/lib/servlet-cgi.jar
- <CATALINA_HOME>/server/lib/servlets-common.jar
- <CATALINA_HOME>/server/lib/servlets-default.jar
- <CATALINA_HOME>/server/lib/servlets-invoker.jar
- <CATALINA_HOME>/server/lib/servlets-manager.jar
- <CATALINA_HOME>/server/lib/servlets-snoop.jar
- <CATALINA_HOME>/server/lib/servlets-ssi.jar
- <CATALINA_HOME>/server/lib/servlets-webdav.jar
- <CATALINA_HOME>/server/lib/jakarta-regexp-1.2.jar
- <CATALINA_HOME>/lib/naming-factory.jar
- <CATALINA_HOME>/common/lib/crimson.jar
- <CATALINA_HOME>/common/lib/jasper-compiler.jar
- <CATALINA_HOME>/common/lib/jasper-runtime.jar
- <CATALINA_HOME>/common/lib/jaxp.jar
- <CATALINA_HOME>/common/lib/jndi.jar
- <CATALINA_HOME>/common/lib/naming-common.jar
- <CATALINA_HOME>/common/lib/naming-resources.jar
- <CATALINA_HOME>/common/lib/servlet.jar
- <CATALINA_HOME>/common/lib/tools.jar
- Make sure that your classpath includes the directory containing the compiled
EmbeddedTomcat
class. - Execute the following command:
java onjava.EmbeddedTomcat
If everything went according to plan, you should see some log statements in the console window:
HttpProcessor[8080][0] Starting background thread HttpProcessor[8080][0] Background thread has been started HttpProcessor[8080][1] Starting background thread HttpProcessor[8080][1] Background thread has been started HttpProcessor[8080][2] Starting background thread HttpProcessor[8080][2] Background thread has been started HttpProcessor[8080][3] Starting background thread HttpProcessor[8080][3] Background thread has been started HttpProcessor[8080][4] Starting background thread HttpProcessor[8080][4] Background thread has been started
Once you see the previous text, you will be able to access the ROOT
and /onjava
Web applications using the following URLs:
- http://localhost:8080/
- http://localhost:8080/onjava/
Note: The
onjava
application that we are using throughout this article is the Web application from my previous Tomcat articles.
- Embedding Tomcat Into Java Applications
- Embedding data into JPEG
- Embedding WordPress into OS Commerce
- 【wordpress】Embedding Maps into a Website
- Embedding Greek and scripts into text IDL
- Integrating JavaScript into Native Applications
- Integrating JavaScript into Native Applications
- Integrating JavaScript into Native Applications
- Embedding Python in C++ Applications with boost::python
- Embedding Python in Multi-Threaded C/C++ Applications
- embedding
- Some ideas to embedding lua into C/C++
- Embedding WebRTC Video Chat Right Into Your Website
- Incorporating Socket Programming into your Applications
- Free Apache Tomcat Hosting in the Cloud for Java Applications? It's Called OpenShift!
- Building Performance Metrics into ASP.NET MVC Applications
- Converting 32-bit Applications Into 64-bit Applications: Things to Consider
- Converting 32-bit Applications Into 64-bit Applications: Things to Consider
- ORACLE关于DELETE后空间不释放问题
- delphi7中删除掉 File->reopen中的选项
- Hibernate学习资料整理-1
- DXUT框架剖析(1)
- Cocos2d-x里面如何实现MVC(三)
- Embedding Tomcat Into Java Applications
- C# 中的委托和事件
- java中使用switch-case的用法及注意事项超全总结
- linux vi命令
- Cocos2d-x里面如何实现MVC(二)
- u盘自动挂载-udev(转载加修改),经过测试
- C# 国腾 二代身份证 扫描身份证信息
- ORACLE收缩表空间
- android更新adt后出现java.lang.NoClassDefFoundError: