Duke – Java Web Server

I assembled a core Java Web Engine named as Duke. Duke is a light weight Java Servlet Container. I use it to refresh my Java skills/Design Pattern and to understood how Tomcat works.

Basically the code here was extracted from Tomcat Server.

Detailed info
====
* A Simple Servlet Container in Java: http://luohuahuang.com/2013/08/15/a-simple-servlet-container-in-java/
* façade pattern: http://luohuahuang.com/2013/08/15/facade-pattern/
* Singleton pattern: http://luohuahuang.com/2013/08/16/singleton-pattern/
* Java Thread: http://luohuahuang.com/2013/08/17/java-thread/
* Tomcat Connector: http://luohuahuang.com/2013/08/18/tomcat-connector/
* Tomcat Servlet Container: http://luohuahuang.com/2013/08/18/tomcat-servlet-container/

 

Tomcat Servlet Container

Today I pored into Tomcat’s Servlet Container mechanism.

What is a Servlet,

Servlet is an interface defined in javax.servlet package. It declars some essential methods for the life cycle of a servlet and they are implemented by every servlet and are invoked via a HTTP Request by the server. The following is Servlet’s essential methods,

public void init(ServletConfig config) throws ServletException
public void service(ServletRequest request, ServletResponse response)
throws ServletException, java.io.IOException
public void destroy()

1. The init() method is invoked during initialization stage of the servlet life cycle. It is passed an object implementing the javax.servlet.ServletConfig interface, which allows the servlet to access initialization parameters from the web application.

2. The service() method is invoked upon each request after its initialization. Each request is serviced in its own separate thread. The web container calls the service() method of the servlet for every request. The service() method determines the kind of request being made and dispatches it to an appropriate method to handle the request.

3. The destroy() method is invoked when the servlet object should be destroyed. It releases the resources being held.

Servlet container is designed for handling Servlet resources. Tomcat Servlet container is an implementation of org.apache.catalina.Container.

Basically a Tomcat Servlet container should do,

1. it should implement invoke() method specified by interface org.apache.catalina.Container. In this way, Tomcat’s default connector will invoke this method.

2.invoke() should create a ClassLoader and load the requested Servlet class.

    /**
     * Process the specified Request, and generate the corresponding Response,
     * according to the design of this particular Container.
     *
     * @param request Request to be processed
     * @param response Response to be produced
     *
     * @exception IOException if an input/output error occurred while
     *  processing
     * @exception ServletException if a ServletException was thrown
     *  while processing this request
     */
    public void invoke(Request request, Response response)
        throws IOException, ServletException;

Let’s how Craig R. McClanahan implements his Catalina Servlet Container. Catalina defines its interfaces in org.apache.catalina

The following is the Class Diagram I generated from Tomcat 6.x source code for org.apache.catalina

Container

1. It has a root container interface: org.apache.catalina.container. In Tomcat, it has four categories containers: Engine, Host, Context, and Wrapper.

Tomcat Architecture, http://tomcat.apache.org/tomcat-5.5-doc/architecture/overview.html

Engine

An Engine represents request processing pipeline for a specific Service. As a Service may have multiple Connectors, the Engine received and processes all requests from these connectors, handing the response back to the appropriate connector for transmission to the client. The Engine interface may be implemented to supply custom Engines, though this is uncommon.

Note that the Engine may be used for Tomcat server clustering via the jvmRoute parameter. Read the Clustering documentation for more information.

Host

Host is an association of a network name, e.g. http://www.yourcompany.com, to the Tomcat server. An Engine may contain multiple hosts, and the Host element also supports network aliases such as yourcompany.com and abc.yourcompany.com. Users rarely create custom Hosts because the StandardHost implementation provides significant additional functionality.

Context

Context represents a web application. A Host may contain multiple contexts, each with a unique path. The Context interface may be implemented to create custom Contexts, but this is rarely the case because theStandardContext provides significant additional functionality.

Besides that, it also has a wrapper interface.

Wrapper

A Wrapper represents an independent Servlet.

All of the Engine, Host, Context and Wrapper extend from root interface Container and add additional dedicated methods. Take Engine interface as example,

Method Summary
 java.lang.String getDefaultHost()
Return the default hostname for this Engine.
 java.lang.String getJvmRoute()
Retrieve the JvmRouteId for this engine.
 Service getService()
Return the Service with which we are associated (if any).
 void setDefaultHost(java.lang.String defaultHost)
Set the default hostname for this Engine.
 void setJvmRoute(java.lang.String jvmRouteId)
Set the JvmRouteId for this engine.
 void setService(Service service)
Set the Service with which we are associated (if any).

Their implemenations are StandardEngine, StandHost, StandardContext, and StandardWrapper repectively.

Princpiles in Container:

1. Every container can have more than one sub containers. Basically, one Context container will have more than one Wrapper instances; one Host container can have more than one Context instances. As one wrapper means one Servlet instance, hence a wrapper container could not have its child container.

    /**
     * Add a new child Container to those associated with this Container,
     * if supported.  Prior to adding this Container to the set of children,
     * the child's <code>setParent()</code> method must be called, with this
     * Container as an argument.  This method may thrown an
     * <code>IllegalArgumentException</code> if this Container chooses not
     * to be attached to the specified Container, in which case it is not added
     *
     * @param child New child Container to be added
     *
     * @exception IllegalArgumentException if this exception is thrown by
     *  the <code>setParent()</code> method of the child Container
     * @exception IllegalArgumentException if the new child does not have
     *  a name unique from that of existing children of this Container
     * @exception IllegalStateException if this Container does not support
     *  child Containers
     */
    public void addChild(Container child);
    /**
     * Return the child Container, associated with this Container, with
     * the specified name (if any); otherwise, return <code>null</code>
     *
     * @param name Name of the child Container to be retrieved
     */
    public Container findChild(String name);

    /**
     * Return the set of children Containers associated with this Container.
     * If this Container has no children, a zero-length array is returned.
     */
    public Container[] findChildren();
    /**
     * Remove an existing child Container from association with this parent
     * Container.
     *
     * @param child Existing child Container to be removed
     */
    public void removeChild(Container child);

So for any new containers, ASA they implements org.apache.catalina.Container interface, Catalina Servlet Engine can easily incorporate them by using above methods.

For other utility components, like Loader, Logger, Manager, Resources, etc. Catalina also provides getter/setter methods to help plugin them.


    /**
     * Return the Loader with which this Container is associated.  If there is
     * no associated Loader, return the Loader associated with our parent
     * Container (if any); otherwise, return <code>null</code>.
     */
    public Loader getLoader();

    /**
     * Set the Loader with which this Container is associated.
     *
     * @param loader The newly associated loader
     */
    public void setLoader(Loader loader);

    /**
     * Return the Logger with which this Container is associated.  If there is
     * no associated Logger, return the Logger associated with our parent
     * Container (if any); otherwise return <code>null</code>.
     */
    public Log getLogger();

    /**
     * Return the Manager with which this Container is associated.  If there is
     * no associated Manager, return the Manager associated with our parent
     * Container (if any); otherwise return <code>null</code>.
     */
    public Manager getManager();

    /**
     * Set the Manager with which this Container is associated.
     *
     * @param manager The newly associated Manager
     */
    public void setManager(Manager manager);

The design philosophy from Catalina is superb and elegant. We can learn how to design our plugin-supported system by following its design.
😉

Tomcat Connector

Today I started to extract a slim and simplified connector from the source code of Tomcat 4.x. Before I describe it, I will introduce Tomcat Connector 4.x in brief.

When you use Tomcat out of the box to run web applications, it is able to serve HTML pages without any additional configuration. The reason this works is because it comes configures with an HTTP connector that can handle requests from a user’s web browser. Because of this connector, Tomcat can function as a standalone web server, and serve static HTTML page in addition to handling servlets and JSP pages.

Tomcat Server Class Connector Impl/Name Description                          
Tomcat 3.x org.apache.catalina.connector.http10.HttpConnector HTTP/1.0 Connector Came standard and configured with Tomcat 3.x.
Tomcat 4.0 and 4.1 org.apache.catalina.connector.http.HttpConnector HTTP/1.1 Connector Came standard with 4.0 and 4.1. In Tomcat 4.0, this was the default connector.
Tomcat 4.1 org.apache.coyote.tomcat4.CoyoteConnector Coyote HTTP Connector This is the default connector for Tomcat 4.1. This connector will soon obsolete both connectors defined above: HTTP/1.0 and HTTP/1.1. It will also be backwards compatible with both Tomcat 4.x and Tomcat 3.x.

Check out for more connectors: http://tomcat.apache.org/tomcat-4.1-doc/config/connectors.html

Here are the weak points of using Tomcat as a Web server for static contents. http://www.idevelopment.info/data/Programming/web/connecting_apache_tomcat/Web_Server_Connectors.shtml

Here we can see there are two protocols HTTP/1.1 and HTTP/1.0. You can refer to http://stackoverflow.com/questions/246859/http-1-0-vs-1-1 to see the three new features brought by HTTP 1.1 (Persistent connections/100 Continue status, etc.)

HttpConnector was the default connector for Tomcat 4.x however it has been replaced by CoyoteConnector since the late of 4.x which is faster and has better performance. Tomcat requires its connectors should satisfy below conditions:

1. Implement interface org.apache.catalina.Connector

2. Create an instance of org.apache.catalina.Request

3. Create an instance of org.apache.catalina.Response

Connector should wait for HTTP requests, and create Request & Response objects, and then pass request object and response object to Servlet container.

The following diagram is the UML class diagram I generated from the source code of Tomcat 6.0.37. You can see it is using CoyoteConnector.

ConnectorUCD

Basically you don’t need to bother about those utility classes. Nothing much. They are just wrappers from basic Java javax.servlet.http.* packages. For example,

public class Request implements HttpServletRequest {

public class Response implements HttpServletResponse {

public class CoyoteInputStream extends ServletInputStream {

Let’s come back to the slim connector I extracted for Duke Web Server. Below is its UML class diagram.

Connector (1)

Let’s explore its logic:

1. Boostrap will use HttpConnector to start the Socket.

2. HttpConnector invokes HttpProcessor to handle the request.

3. HttpProcessor implements interfaces Runnable so that it can be run in asynchronous. For each establishment, HttpProcessor instantiates one HttpRequest and one HttpResponse. HttpRequest and HttpResponse implements HttpServletRequest & HttpServletResponse respectively. Both of the classes have their facade class (façade pattern).

4. HttpRequest provides methods to handle its input stream (HttpRequestStream, extends from ServletInputStream.). Similar HttpResponse provides methods to handle its output stream (HttpResponseStream, extends from ServletOutputStream.)

5. If the request URI contains string ‘servlet’ – it means it’s a Servlet request, then HttpProcessor will invoke methods provides by HttpRequest and HttpResponse to process the header/request information, and then invoke ServletProcessor to return a HttpResponseFacade object to Servlet container.

If the request URI implies its a static page, like html, then it will invoke ‘StaticResourceProcessor’ to write the HTML content to response.

You can also refer to book ‘How Tomcat Works‘ (Chapter 3 & 4) for more details – It is a very awesome book. I strongly recommend you should buy one if you want to know how Tomcat works!

If you are interested in how to implement a simple pure Perl Web server, you can refer to Camel – A pure Perl web server.

 

Java Thread

Today, I started to add concurrent (multi-thread) capabilities to my Duke Web Server. In this post, I will refresh my knowledge in Java Thread mechanism.

Processes and Threads

In concurrent programming, there are two basic units of execution: processes and threads. In the world of Java, mostly time we are talking about Threads.

A process has a self-contained execution environment. Typically when we are talking process, we are talking a program or application. However, sometimes we also regards a set of cooperating processes as one program. For an example of process in Perl language, you can refer to my earlier post HTTP:Daemon in Perl

A thread sometimes is called lightweight process. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process.

How to define and start a Thread in Java

1. Implements Runnable interface. The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. The class must define a method of no arguments called run.

Modifier and Type Method and Description
void run()

When an object implementing interface Runnable is used to create a thread, starting the thread causes the object’s run method to be called in that separately executing thread.

Here a sample class which supports Thread.

public class HelloRunnable implements Runnable {

    public void run() {
        System.out.println("Hello from a thread!");
    }

    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }

}

2. Extend Thread class. The Thread class itself implements Runnable interface, though its run method does nothing – in other word, you have to overwrite its run in your class as above. As in Java, a class can implement many interfaces but extend only one class. Hence, developers usually choose the method 1 to implement their concurrent requirements.

public class HelloThread extends Thread {

    public void run() {
        System.out.println("Hello from a thread!");
    }

    public static void main(String args[]) {
        (new HelloThread()).start();
    }

}

Please note, you should invoke Thread.start in order to start the new thread. – Do NOT invoke the run method – it is just a common invoke like other methods – in other word, it does NOT support thread with run method!

For more details about Java Thread, you might refer to http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html

Let’s see how I incorporate Java Thread into Duke Web Server.

For a synchronous implementation, you might refer to A Simple Servlet Container in Java

Basically, its steps should be,

1. Start a socket

2. Listening

3. Accept a request

4. Handle request

5. Start again from Step 3

Below are the steps support concurrent,

1. Start a socket

2. Listening

3. Accept a request – start a thread to handle the request – the thread will go to step 4

4. In the same time with Step 3, main process will come bck to Step 2 to wait for next request.

Below is the snippet,

package com.duke.moyan.connector;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class HttpAgent implements Runnable{

	private Socket socket = null;

	private void setSocket(Socket socket) {
		this.socket = socket;
	}

	public HttpAgent(Socket socket) {
		this.setSocket(socket);
	}

	@Override
	public void run() {
		try {
			BufferedReader input = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));
			OutputStream output = socket.getOutputStream();

			HttpRequest request = new HttpRequest(input);
			request.parse();

			HttpResponse response = new HttpResponse(output);
			response.setRequest(request);

			if (request.getUri().startsWith("/" + Constants.SERVLET_DIR +  "/")) {
				ServletProcessor processor = new ServletProcessor();
				processor.process(request, response);
			} else {
				StaticResourceProcessor processor = new StaticResourceProcessor();
				processor.process(request, response);
			}

			output.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Close failed");
		}
	}

}

Start it,

		Socket socket = null;

		while (true) {
			try {
				socket = serverSocket.accept();
				System.out.println("Yes, accepted");
				//Thread.sleep(10000);
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("Accept failed: " + Constants.PORT);
				System.exit(-1);
			}

			Runnable httpthread;
			httpthread = new HttpAgent(socket);
			Thread thread = new Thread(httpthread);
			thread.start();
		}

You may fee interested in its package name ‘moyan’. Check it out http://en.wikipedia.org/wiki/Mo_Yan. I am just reading his novels. To salute to Mr. Moyan, I just named it with his name. 🙂

Singleton pattern

Today I started to remove the hardcoded strings from my Duke Web Server. My requirement is, there should be only one object instance exists and it should provide the service of retrieving values from LocalStrings.properties. Hence I looked for help from Singleton pattern.

Singleton pattern,

“In software engineering, the singleton pattern is a design pattern that restricts the Instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. The concept is sometimes generalized to systems that operate more efficiently when only one object exists, or that restrict the instantiation to a certain number of objects. The term comes from the mathematical concept of a singleton.” — from wiki.

Let’s its UML diagram,

Its implementation must satisfy below principles:

1. its constructor is private. In other word, it can not be created outside but just from getInstance() to get its single instance.

2. it should have a private static instance.

Below is an sample from wiki,

public class SingletonDemo {
        private static SingletonDemo instance = null;

        private SingletonDemo() {       }

        public static synchronized SingletonDemo getInstance() {
                if (instance == null) {
                        instance = new SingletonDemo ();
                }
                return instance;
        }
}

Let’s explain it:

1. If anyone wants to use SingletonDemo, he can just invoke SingletonDemo.getInstance() to retrieve its static private SingletonDemo. In this way, it can be ensured that it has only one instance exists anytime.

2. To avoid conflict, use keyword synchronized to obtain its class lock to control its access to static private SingletonDemo.

In Tomcat, it adopts the same pattern to design its StringManager. If you are interested, you can refert to the source code of org.apache.catalina.util.StringManager.

Typically, in each Tomcat package,

it will has its local LocalStrings.properties files

singleton1

In Constants.java, it contains all of the necessary static parameters. It has one parameter as below

public static final String Package = “org.apache.catalina.connector”;

everytime StringManager runs, it will retrieve the LocalStrings and try to retrieve an StringManager instance,

private static Hashtable managers = new Hashtable();

 * Get the StringManager for a particular package. If a manager for
 * a package already exists, it will be reused, else a new
 * StringManager will be created and returned.
 *
 * @param packageName The package name
public synchronized static StringManager getManager(String packageName) {
 StringManager mgr = (StringManager)managers.get(packageName);
if (mgr == null) {
 mgr = new StringManager(packageName);
 managers.put(packageName, mgr);
 }
 return mgr;
 }

Here you can see it uses a hashtable to store those StringManager instances. Actually it is not a strict Singleton. It is ‘Singleton’ for every package only. I think that is easy to understand. As Tomcat has lots of strings and it is very terrible if tomcat has only one StringManager instance. Hence here Tomcat will maintain one StringManager instance for every package.

In my Duke Server, I just copied and simplified it as below,

package com.duke.moyan.util;

import java.util.Hashtable;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;

public class StringManager {
 private ResourceBundle bundle;

private StringManager(String packageName) {
 String bundleName = packageName + ".LocalStrings";
 try {
 bundle = ResourceBundle.getBundle(bundleName);
 return;
 } catch (MissingResourceException e) {
 System.out.println("Failed to load " + bundleName);
 }
 }

public String getString(String key) {
 String str = null;
 if (bundle == null){
 return key;
 }
 try {
 str = bundle.getString(key);
 } catch (MissingResourceException mre) {
 System.out.println("Cannot find message associated with key '" + key + "'");
 }

return str;
 }

@SuppressWarnings("rawtypes")
 private static Hashtable managers = new Hashtable();

@SuppressWarnings("unchecked")
 public synchronized static StringManager getManager(String packageName) {
 StringManager mgr = (StringManager) managers.get(packageName);

if (mgr == null) {
 mgr = new StringManager(packageName);
 managers.put(packageName, mgr);
 }
 return mgr;
 }
 }

// below is the sample how to use it:

protected static StringManager sm = StringManager.getManager(constants.Package);

sm.getString("HttpResonpse.ERROR_404");

//in LocalString.properties, it has line: HttpResponse.ERROR_404=Oops, File Not Found

façade pattern

Before we deep into Facade Pattern, let’s see an example (it is descirbed in http://luohuahuang.com/2013/08/15/a-simple-servlet-container-in-java/) in the following,

facade

Here, the UML logic is very frank. Class HttpRequest implements interface javax.servlet.ServletRequest. Besides that, it also has two additional methods parse() and parseUri(String). ServletProcessor will use HttpRequest to handle Servlet affairs.

For a better understanding, let’s see below snippet,

// here request is a Class HttpRequest. It is converted into a Servlet class upwards.

Servlet servlet = null;

try {
 servlet = (Servlet) myClass.newInstance();
 servlet.service((ServletRequest) request, (ServletResponse) response);
 }

It smells bad because of below two points,

1. Both of parse() and parseUri methods should be unavailable from Servlet engine as they are internal use only. However in above code, both of the methods are accessible by Servlet.service through servlet.service((ServletRequest) request. That is vulnerable.

2. HttpRequest is a customized Class with new method, although it implements from javax.servlet.ServletRequest. Hence developers who have to develop Servlet services have to understand the details of HttpRequest. This effort is unnecessary as to develop Servlet services, all they need to know should be only strictly those methods from ServletRequest.

So, we need to find another way to hide the implementation of HttpRequest from Servlet.

Let’s Facade Pattern, http://en.wikipedia.org/wiki/Facade_pattern

Facade
The facade class abstracts Packages 1, 2, and 3 from the rest of the application.
Clients
The objects are using the Facade Pattern to access resources from the Packages.

 Similarly, the solution for HttpRequest is,

Create a Facade class which should implement the same as HttpRequest from javax.servlet.ServletRequest but without parse() or parseUri(String) method.

In the main method, change

from –


Servlet servlet = null;

try {
 servlet = (Servlet) myClass.newInstance();
 servlet.service((ServletRequest) request, (ServletResponse) response);
 }

to –

Servlet servlet = null;
 RequestFacade requestFacade = new RequestFacade(request);
 ResponseFacade responseFacade = new ResponseFacade(response);
 try {
 servlet = (Servlet) myClass.newInstance();
 servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
 }

In this way, we can hide parse() and parseUri(String), and make the interface of HttpRequest more clear and tidy.

You can see more from source code of org.apache.catalina.connector

A Simple Servlet Container in Java

Yesterday I started to refresh my Java skills. Basically I will follow the same way I refreshed my Perl skills. In the past 1 month I refreshed my Perl skills by designing a tiny pure perl web container. You might check it out from http://luohuahuang.com/2013/08/12/camel-a-pure-perl-web-server/

In the following section I will introduce HTTP again but from prospect of Java language.

Internet is running upon a ‘stateless’ protocol ‘HTTP’. http://tools.ietf.org/pdf/rfc2616.pdf defines Hypertext Transfer Protocol — HTTP/1.1. Basically for a HTTP connection, it has,

HTTP Request

POST /firstapp/test.pl HTTP/1.1
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-us,en;q=0.5
Host: localhost:8080
Referer: http://localhost:8080/firstapp/test.pl
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Content-Length: 792

It contains three parts:

URI: Uniform Resource Identifier.

Request Header

Message Body.

HTTP Response

HTTP/1.1 200 OK

Server: …

Let’s see how to get started.

Firstly, we need to new a java.net.ServerSocket. You can request it to listen in localhost:8080

try {
serverSocket = new ServerSocket(PORT, 1, InetAddress.getByName(IP_ADDR));
catch (IOException e) {
e.printStackTrace();
System.out.println("Could not listen on port: " + PORT);
System.exit(-1);
}

Secondly, ASA the connection is established, it will retrieve a socket handler for you and you can use that socket handler to retrieve InputStream and also prepare your OutputStream.

try {
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
output = socket.getOutputStream();

Thirdly, create two classes by implementing interfaces javax.servlet.ServletRequest and javax.servlet.ServletResponse respectively. Here you need to extract the URI from HTTP Request so that you can know what it wants. Basically you can category requests into two types: Static Request (.html) and Servlet. The difference between these two types is: for static request, you can just simply open that requested .html file and write it back to the outputstream; for Servlet request, you need to load the Servlet Class into the classloader, run its service() method and then retrieve back the result.

if (request.getUri().startsWith("/servlet/")) {
ServletProcessor processor = new ServletProcessor();
processor.process(request, response);
} else {
StaticResourceProcessor processor = new StaticResourceProcessor();
processor.process(request, response);
}
// …
// load the servlet into classloader. run it and retrieve the result.
public void process(HttpRequest request, HttpResponse response) {
String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf("/") + 1);
URLClassLoader loader = null;
try {
// create a URLClassLoader
URL[] urls = new URL[1];
URLStreamHandler streamHandler = null;
File classPath = new File(WEB_ROOT);
// the forming of repository is taken from the createClassLoader
// method in
// org.apache.catalina.startup.ClassLoaderFactory
String repository = (new URL("file", null,classPath.getCanonicalPath() + File.separator)).toString() + "servlet" + File.separator;
// the code for forming the URL is taken from the addRepository
// method in
// org.apache.catalina.loader.StandardClassLoader class.
urls[0] = new URL(null, repository, streamHandler);
loader = new URLClassLoader(urls);
} catch (IOException e) {
System.out.println(e.toString());
}
@SuppressWarnings("rawtypes")
Class myClass = null;
try {
myClass = loader.loadClass(servletName);
} catch (ClassNotFoundException e) {
System.out.println(e.toString());
}

Servlet servlet = null;
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) request,(ServletResponse) response);
} catch (Exception e) {
System.out.println(e.toString());
} catch (Throwable e) {
System.out.println(e.toString());
}

About a Servlet Lifecycle,

Below is a sample servlet,

import java.io.*;
import javax.servlet.*;
import java.io.PrintWriter;

//javac -cp /home/luhuang/workspace/Duke/lib/servlet-api-2.2.jar HelloWorld.java
public class HelloWorld implements Servlet {
	public void init(ServletConfig config) throws ServletException {
	}

	public void service(ServletRequest request, ServletResponse response)
			throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<body>");
		out.println("<h1>Hello Servlet - Greeting from Duke</h1>");
		out.println("</body>");
		out.println("</html>");
	}

	public void destroy() {
	}

	public String getServletInfo() {
		return null;
	}

	public ServletConfig getServletConfig() {
		return null;
	}

}
You just need to implement its service() method and no need to bother about other methods.
Here is the snap. 🙂
servlet1