Oracle9i Application Server Migrating from Oracle Application Server Release 1.0.2 Part Number A83709-05 |
Library | Service | Contents | Index

# 2
Migrating JWeb Applications to Apache JServ

This chapter discusses migration of JWeb applications from Oracle Application Server to Apache JServ in the Oracle9i Application Server. It includes a discusssion of functional differences between JWeb and Apache JServ, and provides code examples for migrating. The topics include:

- What is Apache JServ?

- JWeb and Apache JServ 1.1 Differences

- Code Modifications for JWeb Applications

## What is Apache JServ?

Oracle9i Application Server uses the Oracle HTTP Server to service HTTP requests from clients. Apache JServ 1.1, a Servlet 2.0 compliant servlet engine, is bundled with Oracle9i Application Server. If you have JWeb applications deployed on Oracle Application Server 4.x and wish to migrate to Oracle9i Application Server, you need to migrate your JWeb applications to the Servlet 2.0 specification.

### Migrating Oracle Application Server JServlets to Apache JServ Servlets

Apache JServ 1.1 is compatible with Apache 1.3.x, JDK 1.1 or later, and JSDK 2.0. Oracle Application Server 4.0.8 JServlets are compliant with the Servlet 2.1 specification. If you are migrating JServlets to Apache, we recommend that you plan the migration to Oracle8i JVM servlets because of the differences between 2.0 and 2.1 compliant servlets.

See Also: `http://java.apache.org` for more information on Apache JServ `http://java.sun.com` for more information on the Servlet specifications

## JWeb and Apache JServ 1.1 Differences

This section describes the differences between JWeb and Apache JServ 1.1 applications.

### Architecture

JWeb applications execute within the Oracle Application Server cartridge infrastructure, while Apache JServ 1.1 servlets run with the Oracle HTTP Server and in JVM(s).

#### JWeb Architecture

In Oracle Application Server, the HTTP listener receives a request for a JWeb cartridge. The listener passes the request to the dispatcher, which communicates with the Web Request Broker (WRB). The WRB uses URL mapping to identify the cartridge instance to which the request should be sent. If no cartridge instances exist for the requested cartridge, the cartridge server factory creates a cartridge server process to instantiate the cartridge. In JWeb, the cartridge server process loads a JVM, which runs a JWeb application (of the Oracle Application Server application paradigm). Figure 2-1 depicts these components graphically.

#### Figure 2-1 Oracle Application Server Cartridge Infrastructure

Text description of the illustration oas_arch.gif

#### Apache JServ Architecture

Apache JServ consists of two functional components: mod_jserv and a servlet engine. mod_jserv is an Apache Server module and directs incoming requests for Java Servlets to a servlet engine. The Apache JServ Protocol (AJP) facilitates communication between the two components.

Figure 2-2 illustrates a one-to-many configuration. In a one-to-many configuration, there is one Apache listener and multiple servers. Each server can run one or more servlet engines. In this figure, a single Apache instance is communicating to two servers. Server 1 is running two servlet engines and server 2 is running one servlet engine. Three AJP connections are open between the servlet engines and a single mod_jserv in the Apache instance.

#### Figure 2-2 Apache JServ Architecture (one-to-many example)

Text description of the illustration apa_arch.gif

mod_jserv, which is implemented in C, is an Apache module that runs in the same process as the Apache web server. It functions like a dispatcher in that it receives a request from the Apache HTTP listener and routes it to a servlet engine. It does not execute any servlet business logic.

A servlet engine provides the runtime environment to execute servlets implementing the Servlet 2.0 API. It runs in a JVM process, in the same or different node as the Apache web server. Each JVM has one servlet engine, and the number of servlet engines is not proportional to the number of web servers (mod_jserv modules). One mod_jserv can work with more than one servlet engine and vice versa. Or, multiple mod_jserv modules can work with multiple servlet engines.

#### Apache JServ Protocol

Because Apache JServ servlet engines do not run in-process with mod_jserv (or possibly not even on the same physical machine as the module), a protocol is required for the two components to communicate. A proprietary protocol called Apache JServ Protocol (AJP) 1.1, is used. AJP 1.1 communicates using sockets, and implements an authentication algorithm using MD5 hashing without strong cryptography.

See Also: `` `http://java.apache.org/jserv/protocol/AJPv11.html`

#### Single Node Configuration

When a servlet engine is located on the same machine as the web server, the mod_jserv module can be set up to start or stop the servlet engine and JVM when the web server starts or stops, respectively. The module performs all the necessary tasks to gracefully shut down the JVM. In this scenario, mod_jserv can also perform failover by checking JVM status regularly and starting another JVM if the first crashes.

#### Multi-Node Configuration

Automatic lifecycle control is not available when mod_jserv and a servlet engine exist on different machines. The engine and JVM must be started manually with a customizable script (each servlet engine requires its own script to start). This means that each engine can be started with a custom environment. There is a limit of 25 servlet engines that can be addressed by a single mod_jserv.

mod_jserv and servlet engine instances can have one-to-one, one-to-many, many-to-one, and many-to-many relationships. Multiple servlet engines can also reside on one node (in which case the JVMs must be assigned different port numbers so that mod_jserv can differentiate them).

#### Servlet Zones

Apache JServ implements a servlet virtualization paradigm called servlet zones. Servlet zones can be equated with virtual hosts of web servers. Each zone provides a logical demarcation from the physical relationships (locations) of servlet classes. Hence, each servlet zone can be assigned a common context, including a common URI, regardless of where its member servlets are located (for example, on different hosts). However, the current implementation of Apache JServ does not provide sandbox security for each zone.

### Life cycle

JWeb classes and Apache JServ servlets have different life cycles.

#### JWeb Life Cycle

JWeb classes use the standard `main()` entry point to start their execution logic. Their life cycle resembles that of a standard Java class in loading, linking, initializing, and invoking `main()`.

See Also: `` `http://java.sun.com/docs/books/vmspec/index.html`

a

#### Apache JServ Life Cycle

In Apache JServ, Servlet life cycle is compliant with Servlet 2.0 specifications. The life cycle is defined by the `javax.servlet.Servlet` interface, which is implemented directly or indirectly by all servlets. This interface has methods which are called at specific times by the servlet engine in a particular order during a servlet's lifecycle. The `init()` and `destroy()` methods are invoked once per servlet lifetime, while the `service()` method is called multiple times to execute the Servlet's logic.

Figure 2-3 depicts the servlet life cycle.

#### Figure 2-3 JServlet life cycle

Text description of the illustration lifecyc.gif

### Threading

The JWeb cartridge and Apache JServ servlet engine support single or multiple threads of execution, but the threading implementations are different.

#### JWeb Threading

Threading for the JWeb cartridge is defined in the Oracle Application Server cartridge configuration by toggling the Stateless parameter (true or false). If true, a cartridge instance is shared by more than one client. If false, it is not shared, and only one client can access it at any one time. Also, if Oracle Application Server is in min/max mode, the min/max cartridge servers and min/max threads values can be varied to change the way multi-threading is implemented for the cartridge.

#### Apache JServ Threading

The Apache JServ servlet engine is multi-threaded by default. The servlet container in the engine manages the threads that service client requests. Each instance of a servlet class can be given multiple threads of execution. In this case, a servlet instance is shared between more than one client. Alternatively, you can specify a class to execute only one thread at a time by having that class implement the `javax.servlet.SingleThread` interface. In this case, a pool of instances of this Servlet class is maintained and each instance is assigned to one client only at any one time (instances are not shared).

### Sessions

In the JWeb cartridge, you can enable client sessions using the OAS Manager. In Apache JServ, in accordance with Servlet 2.0 specifications, only programmable sessions are available. Consequently, if you are migrating a JWeb application that was session-enabled by a means other than code, you need to implement the session mechanism programmatically using the servlet session API. See "Session Control".

### Dynamic Content Generation in HTML Pages

A JWeb Toolkit feature is available for generating dynamic content in HTML pages. The JWeb Toolkit embeds special placeholders in an HTML page. When this file is imported into a JWeb class as an `oracle.html.HtmlFile` object, the `setItemAt()` method places the data generated from the code at the placeholder locations.

Since this is a JWeb specific feature, it is not available in Apache JServ. If you would like to embed dynamic information in HTML pages (scripting), consider using JavaServer Pages with OracleJSP in Oracle9i Application Server.

## Code Modifications for JWeb Applications

To migrate JWeb applications to Apache JServ, you will have to modify code in these areas:

- Session Control

- Application Threads

- Logging

### Session Control

You can session-enable a JWeb application with the cartridge's Client Session parameter in the Node Manager Web Parameters form. This allows the static parameters of an invoked class to contain per client data across calls. In the Servlet 1.0 API, session state is not kept in static variables of servlet classes. Instead, a session object is explicitly obtained to store session state using named attributes.

In Apache JServ, there is no configurable sessions support, so you have to enable sessions in code using the `getSession()` method in `javax.servlet.http.HttpServletRequest`, as shown below:

    HttpSession session = request.getSession(true);

State information for a session can then be stored and retrieved by the `putValue()` and `getValue()` methods, respectively, of javax.servlet.http.HttpSession.

    session.putValue("List", new Vector());
    Vector list = (Vector) session.getValue("List");

Note: Do not use static data members to maintain session state in Apache JServ (although this is common practice in JWeb). Instead, use the servlet session API. The latter allows the servlet engine to use memory more efficiently.

#### JServ Session Time-out

You can specify the time-out value for a session in the `session.timeout` parameter in the `jserv.properties` file. You can also expire a session by invoking `invalidate()` in the servlet session API.

The JWeb session time-out callback is not available in Apache JServ.

### Application Threads

In JWeb, an application can manage threads using the `oracle.owas.wrb.WRBRunnable` class. This class allows application threads to access request and response information. For Apache JServ, only standard Java thread management is needed to manage application threads (the `java.lang.Runnable` interface is used). For both JWeb and Apache JServ, using application threads is not recommended because multi-threaded applications limit the effectiveness of the load balancer.

### Logging

JWeb applications log messages using the Oracle Application Server logger service provided by the WRB. This service allows applications to write messages to a central repository, such as a file system or database. The `oracle.owas.wrb.services.logger.OutputLogStream` class interfaces with the logger service.

In Apache JServ, messages are written to two log files. Messages generated by mod_jserv are recorded in the file specified by the `ApJServLogFile` directive in the Oracle HTTP Server `http.conf` configuration file. The default value for this directive is `<ORACLE_HOME>/Apache/Jserv/logs/mod_jserv.log`. Messages generated by the servlet engine are recorded in the file specified by the `log.file` parameter in `jserv.properties` file. The default value for this directive is `<ORACLE_HOME>/Apache/Jserv/logs/jserv.log`).

The messages generated by servlet applications, like exception stack traces, are recorded into `jserv.log`. In code, you can write to this log file using the `javax.servlet.ServletContext.log()` or `javax.servlet.GenericServlet.log()` methods.

The `jserv.properties` file allows you to select specific functional parts of the servlet engine to log. In `jserv.log`, these parts are referred to as channels.

##### Table 2-1 Channels in jserv.log

Channel | Type of Message
--- | ---
log.channel.authentication | Authentication messages from the AJP protocol.
log.channel.exceptionTracing | Exception stack traces caught by the servlet engine.
log.channel.init | Initialization messages from servlet engine.
log.channel.requestData | Data obtained from HTTP requests. For example, parameters from GET or POST HTTP methods.
log.channel.responseHeaders | Header information from HTTP responses.
log.channel.serviceRequest | Request processing messages.
log.channel.servletLog | Messages from the `javax.servlet.ServletContext.log` and `javax.servlet.GenericServlet.log` methods.
log.channel.servletManager | Messages from the servlet manager. These include messages for loading/unloading servlet zones and automatic class reloading.
log.channel.signal | System signal messages.
log.channel.terminate | Messages generated when servlet engine terminates.

#### JWeb Toolkit Packages (JWeb API)

The JWeb cartridge in Oracle Application Server includes a JWeb toolkit of Oracle proprietary Java packages. If you used any of those packages in JWeb applications that will migrate to Oracle9i Application Server, you must modify the code to use Servlet 2.0 equivalent classes and methods. If no equivalent functionality is available, you must rewrite the code to implement the functionality provided by the JWeb packages.

Because some of the JWeb toolkit packages were designed specifically to interact with Oracle Application Server components such as the WRB, the functionality in these packages is not reproducible in the standard servlet API. Consequently, the migration process may also include some redesign of applications.

The following tables list JWeb methods and their functional equivalents for the following servlet API classes:

- Table 2-2, "JWeb Equivalents for javax.servlet.http.HttpServletRequest Class Methods"

- Table 2-3, "JWeb Equivalents for javax.servlet.ServletRequest Class Methods"

- Table 2-4, "JWeb Equivalents for javax.servlet.ServletResponse Class Methods"

- Table 2-5, "JWeb Equivalents for javax.servlet.ServletContext Class Methods"

- Table 2-6, "JWeb Equivalents for javax.servlet.http.HttpUtils Class Methods"

  ##### Table 2-2 JWeb Equivalents for javax.servlet.http.HttpServletRequest Class Methods

  JWeb Method | Servlet Method
  --- | ---
  oracle.owas.wrb.services.http.HTTP.getHeader(String) | getHeader(name)
  oracle.owas.wrb.services.http.getCGIEnvironment("AUTH_TYPE") | getAuthType()
  oracle.owas.wrb.services.http.HTTP.getHeaders()Foot 1 | getHeaderNames()Foot 2
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("PATH_INFO") | getPathInfo()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("PATH_TRANSLATED") | getPathTranslated()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("QUERY_STRING") | getQueryString()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("REQUEST_METHOD") | getMethod()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("REMOTE_USER") | getRemoteUser()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("SCRIPT_NAME") | getServletPath()

  1 A hashtable of header names and values is returned. 2 An enumeration of header names is returned.

  ##### Table 2-3 JWeb Equivalents for javax.servlet.ServletRequest Class Methods

  JWeb Method | Servlet Method
  --- | ---
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("CONTENT_TYPE") | getContentType()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("CONTENT_LENGTH") | getContentLength()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("SERVER_PROTOCOL") | getProtocol()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("REMOTE_ADDR") | getRemoteAddr()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("REMOTE_HOST") | getRemoteHost()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("SERVER_NAME") | getServerName()
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment("SERVER_PORT") | getServerPort()
  oracle.owas.wrb.services.http.HTTP.getPreferredAcceptCharset() | getCharacterEncoding()
  oracle.owas.wrb.services.http.HTTP.getURLParameter(name) | getParameter(name)
  oracle.owas.wrb.services.http.HTTP.getURLParameters(name) | getParameterValues(name)Foot 1

  1 where there are multiple values for "name"

  ##### Table 2-4 JWeb Equivalents for javax.servlet.ServletResponse Class Methods

  JWeb Method | Servlet Method
  --- | ---
  oracle.owas.wrb.WRBWriter | getWriter()

  ##### Table 2-5 JWeb Equivalents for javax.servlet.ServletContext Class Methods

  JWeb Method | Servlet Method
  --- | ---
  oracle.owas.wrb.services.http.HTTP.getCGIEnvironment | getServerInfo()
  Use oracle.OAS.Services.Logger | log(Exception, String) log(String)

  ##### Table 2-6 JWeb Equivalents for javax.servlet.http.HttpUtils Class Methods

  JWeb Method | Servlet Method
  --- | ---
  oracle.owas.wrb.services.http.HTTP.getURLParameters(Hashtable) | parsePostData(int, ServletInputStream)
  oracle.owas.wrb.services.http.HTTP.getURLParameters(Hashtable) | parseQueryString(String)
  oracle.html.HtmlStream.print | javax.servlet.ServletOutputStream.print
  oracle.html.HtmlStream.println | avax.servlet.ServletOutputStream.println
  oracle.owas.wrb.services.http.MultipartElement | javax.servlet.ServletInputStream.readLine

| Copyright © 2001 Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index