wiki:waue/2009/0813
鑲嵌 jetty 5.1.x code

簡介

  • Jetty 官網上面的code為 6.x 版本,因此在jetty 5.1 無法編譯過,因此在這邊把sample code紀錄起來
  • 將以下的程式碼鑲嵌入java檔內,編譯時classpath要匯入jetty等相關函式庫
  • 編譯完成後,執行以下指令即可
    • (當然除了注意code正確完整,也須確保環境變數設定無誤)
      java your_class_main your_xml
      

Jetty code 最精簡版

此範例皆置於 Jetty-Demo 的 simple_start 資料夾

  • 執行方法
    ./jetty.sh
    

jetty.sh

#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-6-sun
export JETTY_HOME=/opt/jetty_demo
export THISPATH=/opt/jetty_demo/simple_start
export CLASSPATH=$CLASSPATH:$THISPATH:\
/opt/jetty_demo/lib/javax.servlet.jar:\
/opt/jetty_demo/lib/org.mortbay.jetty.jar:\
/opt/jetty_demo/lib/org.mortbay.jmx.jar:\
/opt/jetty_demo/ext/ant.jar:\
/opt/jetty_demo/ext/jasper-compiler.jar:\
/opt/jetty_demo/ext/mx4j-remote.jar:\
/opt/jetty_demo/ext/xml-apis.jar:\
/opt/jetty_demo/ext/commons-el.jar:\
/opt/jetty_demo/ext/jasper-runtime.jar:\
/opt/jetty_demo/ext/mx4j-tools.jar:\
/opt/jetty_demo/ext/xmlParserAPIs.jar:\
/opt/jetty_demo/ext/commons-logging.jar:\
/opt/jetty_demo/ext/mx4j.jar:\
/opt/jetty_demo/ext/xercesImpl.jar

cd $THISPATH

# compiler
javac -cp $CLASSPATH SimpleJetty.java

# run
java -cp $CLASSPATH -Djetty.home=$JETTY_HOME SimpleJetty my.xml

SimpleJetty?.java

import org.mortbay.http.SocketListener;
import org.mortbay.jetty.Server;

public class SimpleJetty {

        static final String web_root = "/opt/jetty_demo/webapps/root/";
        static final int port_num = 8180;

        public static void main(String[] args) {
                Server server = new Server();
                SocketListener listener = new SocketListener();
                listener.setPort(port_num);
                server.addListener(listener);
                try {
                        server.addWebApplication("/", web_root);
                        server.start();

                } catch (Exception e1) {
                        e1.printStackTrace();
                }

        }

}

my.xml

<Configure class="org.mortbay.jetty.Server">
  <Call name="addListener">
    <Arg>
      <New class="org.mortbay.http.SocketListener">
          <Set name="Port">
            <SystemProperty name="jetty.port" default="8180"/>
          </Set>
      </New>
    </Arg>
  </Call>

  <Call name="addWebApplication">
    <Arg>/opt/jetty_demo/webapps/root
    </Arg>
  </Call>
 </Configure>

Debug

  • 遇到classNotFound: LogFactory? 的錯誤 : 沒有把 common-log.jar 加入classpath
  • 遇到classNotFound: main 的錯誤 : 沒有把本地目錄匯入classpath
  • 提示 Address already in use ,但程式還是在跑 : 上次關掉jetty是用control-c 而非 java -jar stop.jar
    • (起始時用 java -jar start.jar etc/jetty.xml 才會遇到)

jetty 5.1 程式教學

Using the ServletHandler?

If you do not wish to use web applications but you want to deploy servlets, then you need to register at least one context and at least the ServletHandler? with the server.

HttpServer?

You are able to statically configure individual servlets at a specific URL pattern, or use dynamic mapping to extract servlet names from the request URL.

HttpServer server = new HttpServer();
server.addListener(":8080");
HttpContext context = server.getContext("/");
ServletHandler handler= new ServletHandler();
handler.addServlet("Dump","/dump/*",
                   "org.mortbay.servlet.Dump");
context.addHandler(handler);

org.mortbay.jetty.Server

Alternately, the org.mortbay.jetty.Server can be used instead of a HttpServer?, so that it's conveniance methods may be used:

Server server = new Server();
server.addListener(":8080");
ServletHttpContext context = (ServletHttpContext)
    server.getContext("/");
context.addServlet("Dump","/dump/*",
                   "org.mortbay.servlet.Dump");

Static Servlet

  • Using Static Servlet Mappings

The examples above used defined servlet mappings to map a request URL to a servlet.

Prefix (eg "/dump/*"), suffix (eg. "*.jsp"), exact (eg "/path") or default ("/") mappings may be used and they are all within the scope of the context path:

  • Code Example: Static servlet mappings
Server server = new Server();
server.addListener(":8080");
ServletHttpContext context = (ServletHttpContext)
    server.getContext("/context");
context.addServlet("Dump","/dump/*",
                   "org.mortbay.servlet.Dump");
context.addServlet("Dump","/dump/session",
                   "org.mortbay.servlet.SessionDump");
context.addServlet("JSP","*.jsp",
                   "org.apache.jasper.servlet.JspServlet");
context.addServlet("Default","/",
                   "org.mortbay.jetty.servlet.Default");

Examples of URLs that will be mapped to these servlets are:

/context/dump Dump Servlet by prefix
/context/dump/info Dump Servlet by prefix
/context/dump/session SessionDump? Servlet by exact
/context/welcome.jsp JSP Servlet by suffix
/context/dump/other.jsp Dump Servlet by prefix
/context/anythingelse Default Servlet
/anythingelse Not this context

Using Dynamic Servlets

Servlets can be discovered dynamically by using the org.mortbay.jetty.servlet.Invoker servlet. This servlet uses the request URI to determine a servlet class or the name of a previously registered servlet:

  • Code Example: Dynamic servlet mappings
Server server = new Server();
server.addListener(":8080");
ServletHttpContext context = (ServletHttpContext)
    server.getContext("/context");
context.addServlet("Dump","/dump/*",
                   "org.mortbay.servlet.Dump");
context.addServlet("Invoker","/servlet/*",
                   "org.mortbay.jetty.servlet.Invoker");

Examples of URLs that will be mapped to these servlets are:

/servlet/Dump Dump Servlet by name
/servlet/com.acme.MyServlet?/info Servlet by dynamic class
/servlet/com.mortbay.servlet.Dump Dump Servlet by class or ERROR

By default, the Invoker will only load servlets from the context classloader, so the last URL above will result in an error. The Invoker can be configured to allow any servlet to be run, but this can be a secuirty issue.

Deploying Web Applications

The Servlet Specification details a standard layout for web applications. If your content is packaged according to these specifications, then simply call the addWebApplication(...)methods on the org.mortbay.jetty.Server instance, specifying at minimum a context path, the directory or war file of your application. Jetty is then able to discover and configure all the required handlers including security, static content and servlets.

The addWebApplication(...)methods transparently create and return an instance of WebApplicationContext? which contains a WebApplicationHandler?.

The WebApplicationHandler? extends ServletHandler? and as well as servlets, it provides standard security and filters. Normally it is configured by the webdefault.xml file to contain Invoker, JSP and Default servlets. Filters, Servlets and other mechanisms are configured from the WEB-INF/web.xml file within the web application.

This example configures a web application located in the directory ./webapps/myapp/ at the context path / for a virtual host myhost:

  • Code Example: Configuring a web application
server.addWebApplication("myhost","/","./webapps/myapp/");

The arguments to the addWebApplication method are:

  • An (optional) virtual host name for the context
  • A context path
  • The location of the web application, which may be a directory structure or a war file, given as a URL, war filename or a directory name.

The addWebApplication method is overloaded to accommodate the parameters marked as (optional).

Note: If you run Jetty within JBoss, then you should NOT use the addWebApplication API (or XML), as this bypasses the JBoss classloaders. Use the JBoss deployment mechanisms instead and only use the Jetty configuration for listeners and logs.

Multiple Web Applications

To make things even easier, if you have multiple web apps to deploy, you can accomplish this with a single method call:

  • Code Example: Configuring multiple web apps
server.addWebApplications ("myhost","./webapps/");

Given the code above, Jetty would look in the directory "./webapps/" for all war files and subdirectories, and configure itself with each web application specified therein. For example, assuming the directory webapps contained the war files webapps/root.war, webapps/customer.war and webapps/admin.war, then Jetty would create the contexts "/", "/customer/*" and "/admin/*" mapped to the respective war files. NOTE the special mapping of war files (or directories) named root to the context "/".

In order to actually deploy the web application, it is also necessary to configure a port listener. The full code example to deploy the web application in the code snippet is:

  • Code Example: Deploying a web application
Server server = new Server();
SocketListener listener = new SocketListener();
listener.setPort(8080);
server.addListener(listener );
server.addWebApplication("myhost","./webapps/myapp/");
server.start();

Using XML

The same web application can be deployed instead via an XML configuration file instead of calls to the API. The name of the file is passed to Jetty as an argument on the command line (see the section on Jetty demonstrations for instructions). The following excerpt deploys the same web application as given in the code example above:

                             
<Configure class="org.mortbay.jetty.Server">
  <Call name="addListener">
    <Arg>
      <New class="org.mortbay.http.SocketListener">
          <Set name="Port">
            <SystemProperty name="jetty.port" 
             default="8080"/>
          </Set>
      </New>
    </Arg>
  </Call>

  <Call name="addWebApplication">
    <Arg>/</Arg>
    <Arg><SystemProperty name="jetty.home" 
          default="."/>/webapps/myapp
    </Arg>
  </Call>
 </Configure>

Last modified 15 years ago Last modified on Aug 13, 2009, 6:20:54 PM