Oracle® Application Server Containers for J2EE Servlet Developer's Guide
10g Release 2 (10.1.2) B14017-02 |
|
Previous |
Next |
This chapter, consisting of the following sections, provides basic information for developing servlets for OC4J and the Oracle Application Server. The first section highlights the use of the standalone version of OC4J for convenience during your development and testing phases.
This manual assumes you are using an OC4J standalone environment for at least your initial development phases. This term refers to the use of a single OC4J instance outside the Oracle Application Server environment and Oracle Enterprise Manager 10g. Using OC4J standalone is typically more convenient for early development.
The following sections provide some overview and key considerations:
To obtain OC4J standalone, download the oc4j_extended.zip
file from the Oracle Technology Network (OTN) at the following location:
http://www.oracle.com/technology/tech/java/oc4j/index.html
Notes:
|
You can start, manage, and control standalone OC4J instances through oc4j.jar
(the OC4J standalone executable) and the admin.jar
command-line utility, provided with the standalone product. Deploying an EAR file and binding its Web module through admin.jar
result in automatic updates to key configuration files.
Note: Key aspects of theadmin.jar utility are covered in Chapter 5, "Deployment and Configuration Overview", particularly in "Deploying an EAR File to OC4J Standalone". For further information, see the Oracle Application Server Containers for J2EE Stand Alone User's Guide.
|
During testing, it is also possible to manually install an EAR file or individual files according to the J2EE directory structure, and to complete the process by manually updating key configuration files, which triggers OC4J to unpack and deploy the application.
If you have an independent Web application, you can deploy it as a WAR file (or as a directory structure) within the OC4J default J2EE application, rather than using an EAR file.
In addition, for a convenient testing mode, you can deploy individual servlets or JSP pages to the OC4J default Web application.
An OC4J standalone environment, by default, includes the following key directories:
J2EE home: j2ee/home
, relative to where you install OC4J
Global configuration files directory: j2ee/home/config
Default Web application root directory: j2ee/home/default-web-app
Root target directory for deployed applications: j2ee/home/applications
Root target directory for deployment descriptors (such as orion-web.xml
and orion-application.xml
): j2ee/home/application-deployments
In the simplest case, deploying a test servlet to the OC4J default Web application consists of placing the class file under the /WEB-INF/classes
directory under the default Web application root directory.
Chapter 5 discusses more detailed deployment considerations, primarily targeting OC4J standalone users. See the following sections in particular:
Additionally, for information about invoking a servlet in OC4J standalone, see "Servlet Invocation in an OC4J Standalone Environment".
For detailed information about admin.jar
and about how to start, stop, configure, and manage your standalone process, download the Oracle Application Server Containers for J2EE Stand Alone User's Guide when you download OC4J_extended.zip
.
There are several OC4J flags to be aware of during your development stages, presumably while using OC4J standalone. Note that these flags work independently of each other.
OC4J check-for-updates
flag
In the OC4J server.xml
file, the top-level <application-server>
element includes a check-for-updates
attribute that determines whether the OC4J task manager automatically checks for updates to XML configuration files (including server.xml
itself), library JAR files, and JSP tag libraries. This is often referred to as OC4J polling. The default setting, for use during development, is "true
". You can disable polling as follows:
<application-server ... check-for-updates="false" ... > ... </application-server>
For example, during manual operations (considered "expert modes") during development, you can install your application by hand, then manually update the server.xml
file, global application.xml
file, and http-web-site.xml
file as appropriate to define and bind your Web application. With the default check-for-updates="true"
setting, OC4J automatically detects the changes and deploys your application (unpacking the EAR or WAR file in the process, if applicable).
See "OC4J Top-Level Server Configuration File: server.xml" for more information about this file.
Important: Thecheck-for-updates flag is used only in OC4J standalone. It is disregarded in an Oracle Application Server environment, in which the Oracle Process Management and Notification system (OPMN) and Distributed Configuration Management subsystem (DCM) manage the OC4J file update facilities.
|
admin.jar
-updateConfig
option
If you manually update OC4J XML configuration files while check-for-updates="false"
, you can run the admin.jar
utility with the -updateConfig
option to trigger a one-time check for updates:
% java -jar admin.jar -updateConfig
Important: If you want to re-enable checking after it had been disabled, you must use theadmin.jar -updateConfig option after setting check-for-updates="true" , so that OC4J notices this change. After that, automatic checking will be enabled again.
|
Servlet development
flag
For convenience during development and testing, use the development="true"
setting in the <orion-web-app>
element of the global-web-application.xml
file or orion-web.xml
file. With this setting, whenever you update the servlet code under a particular directory—typically a /WEB-INF/classes
directory, or according to the source-directory
attribute of <orion-web-app>
—the servlet is recompiled and redeployed automatically the next time it is invoked. See "Element Descriptions for global-web-application.xml and orion-web.xml" for more information about the development
and source-directory
attributes.
JSP main_mode
flag
This flag directs the mode of operation of the JSP container, particularly for automatic retranslation of JSP pages and reloading of JSP-generated Java classes that have changed. During development, use the recompile
(default) setting to check timestamps of JSP pages and to retranslate and reload them if they have been modified since they were last loaded. (Use the justrun
setting to not check any timestamps, such as for production mode.) See the Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide for more information about this flag and how to set it.
The OC4J 9.0.3 standalone implementation provided the tools.jar
file from the Sun Microsystems JDK 1.3.1. This file includes the java
front-end executable and javac
compiler executable, for example, among many other components.
The OC4J 10.1.2 standalone implementation no longer provides the tools.jar
file. Therefore, you must install a JDK that OC4J supports before installing OC4J itself. The JDK versions that OC4J supports for the OC4J 10.1.2 implementation are JDK 1.3.1 (for OC4J standalone only) and JDK 1.4. Oracle Application Server 10g Release 2 (10.1.2) includes JDK 1.4, so you should typically use this JDK version for OC4J standalone as well. However, there are migration issues to consider, particularly the JDK 1.4 requirement that all invoked classes must be in packages. See "JDK 1.4 Considerations: Cannot Invoke Classes Not in Packages".
Note: OC4J standalone usesjavac from the same directory in which java is accessed through the command "java -jar oc4j.jar ", ensuring use of the appropriate javac version.
|
Most HTTP servlets follow a standard form. They are written as public classes that extend the HttpServlet
class. A servlet overrides the init()
and destroy()
methods when code is required for initialization work at the time the servlet is loaded by the container, or for finalization work when the container shuts down the servlet. Most servlets override either the doGet()
method or the doPost()
method of HttpServlet
, to handle HTTP GET
or POST
requests appropriately. These two methods take request and response objects as parameters.
This chapter provides sample servlets that are more advanced than the HelloWorldServlet
in "A First Servlet Example".
The following sections cover features and issues to consider before developing your applications:
Here is a sample code template for servlet development:
public class myServlet extends HttpServlet { public void init(ServletConfig config) { } public void destroy() { } public void doGet(HttpServletRequest request, HttpServletResponse) throws ServletException, IOException { } public void doPost(HttpServletRequest request, HttpServletResponse) throws ServletException, IOException { } public String getServletInfo() { return "Some information about the servlet."; }
You can optionally override the init()
, destroy()
, and getServletInfo()
methods, but the simplest servlet just overrides either doGet()
or doPost()
.
The reason for overriding the init()
method would be to perform special actions that are required only once in the servlet lifetime, such as the following:
Establishing data source connections
Getting initialization parameters from the servlet configuration object and storing the values
Recovering persistent data that the servlet requires
Creating expensive session objects, such as hashtables
Logging the servlet version to the log()
method of the ServletContext
object
Servlets have a predictable and manageable lifecycle:
When the servlet is loaded, its configuration details are read from web.xml
. These details can include initialization parameters.
There is only one instance of a servlet, unless the single-threaded model is used. See "Servlet Thread Models and Related Considerations".
Client requests invoke the service()
method of the generic servlet, which then delegates the request to doGet()
or doPost()
(or another overridden request-handling method), depending on the information in the request headers.
Filters can be interposed between the container and the servlet to modify the servlet behavior, either during request or response. See "Servlet Filters" for more information.
A servlet can forward requests to other servlets or include output from other servlets. See "Servlet Includes and Forwards".
Responses come back to the client through response objects, which the container passes back to the client in HTTP response headers. Servlets can write to a response object by using a java.io.PrintWriter
or javax.servlet.ServletOutputStream
object.
The container calls the destroy()
method before the servlet is unloaded.
Typically, the servlet container instantiates and loads a servlet class when it is first requested. However, you can arrange the preloading of servlets through settings in the server.xml
file, the Web site XML file (such as default-web-site.xml
or http-web-site.xml
), and the web.xml
file. Preloaded servlets are loaded and initialized when the OC4J server starts up or when the Web application is deployed or redeployed.
Preloading requires the following steps:
Verify that the relevant <application>
element in the server.xml
file has the attribute setting auto-start="true"
. OC4J inserts this setting by default when you deploy an application.
Specify the attribute setting load-on-startup="true"
in the relevant <web-app>
subelement of the <web-site>
element of the Web site XML file. See "Configuration for Web Site XML Files" for information about the elements and attributes of Web site XML files.
For any servlet that you want to preload, there must be a <load-on-startup>
subelement under the <servlet>
element in the web.xml
file for the Web module.
Table 2-1 explains the behavior of the <load-on-startup>
element in web.xml
.
Table 2-1 File web.xml <load-on-startup> Behavior
Value Range | Behavior |
---|---|
Less than zero (<0) For example: <load-on-startup>-1</load-on-startup> |
Servlet is not preloaded. |
Greater than or equal to zero (>=0) For example: <load-on-startup>1</load-on-startup> |
Servlet is preloaded. The order of its loading, with respect to other preloaded servlets in the same Web application, is according to the load-on-startup value, lowest number first. (For example, 0 is loaded before 1, which is loaded before 2.) |
Empty element For example: <load-on-startup/> |
The behavior is as if the load-on-startup value is |
Note: OC4J supports the specification of startup classes and shutdown classes. Startup classes are designated through the<startup-classes> element of the server.xml file and are called immediately after OC4J initializes. Shutdown classes are designated through the <shutdown-classes> element of server.xml and are called immediately before OC4J terminates.
Be aware that startup classes are called before any preloaded servlets. See the Oracle Application Server Containers for J2EE User's Guide for information about startup classes and shutdown classes. |
The following sections describe OC4J features and some important considerations regarding servlet classloading and application loading:
OC4J Web Application Redeployment and Class Reloading Features
Sharing Cached Java Objects Across OC4J Servlets in Oracle Application Server
In OC4J, any of the following circumstances, depending on OC4J polling, results in redeployment of a Web application and, upon request, reloading of servlet classes and any dependency classes.
Notes:
|
If a servlet .class
file under /WEB-INF/classes
changes, such as by recompilation, then when the servlet is next requested, the associated Web application is redeployed and the servlet class and any dependency classes are reloaded. This action does not depend on OC4J polling. Note that nothing happens until the servlet is next requested. Also note that if only non-servlet .class
files under /WEB-INF/classes
change, nothing is reloaded.
Note: Changing a servlet class file in a directory location specified in a<classpath> element in global-web-application.xml or orion-web.xml has the same effect as changing a servlet class file in /WEB-INF/classes . However, changing a JAR file or dependency class file (such as for a JavaBean) in a <classpath> location has no effect.
|
If the web.xml
file changes, or a library JAR file in /WEB-INF/lib
changes, and OC4J polling is enabled, then the associated Web application is redeployed the next time the OC4J task manager runs, which by default is once each second. Any servlet class in the Web application and any dependency classes are reloaded upon the next request for the servlet. Alternatively, if polling is not enabled, you can trigger one-time polling and the resulting redeployment and reloading by using the admin.jar
-updateConfig
option.
Be aware of the following important considerations:
In the preceding scenarios, a servlet and its dependency classes are reloaded immediately, instead of upon next request, if the servlet is set to be preloaded. This is according to load-on-startup
settings. See "Servlet Preloading".
OC4J servlet reloading functionality does not extend to JSP page implementation classes. Changing a JSP page implementation .class
file does not result in any reloading. JSP recompilation and reloading behavior is determined by the JSP main_mode
flag, as described in the Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide.
Classes in Web modules of a parent application are not visible to child applications, although other classes of the parent application (such as EJBs, for example) are visible.
You can use <library>
elements in the global application.xml
file or server.xml
file to specify directories or JAR or ZIP files for shared code. Upon startup, OC4J loads all classes in any JAR or ZIP file specified in any <library>
element, and all classes in any JAR or ZIP file in any directory specified in any <library>
element.
To avoid unnecessary overhead, you should use <library>
elements somewhat sparingly, specify particular JAR or ZIP files instead of entire directories wherever possible, and, where directories are specified, minimize the number of JAR or ZIP files in those directories.
By default, application.xml
includes a <library>
element for the j2ee/home/applib
directory.
Note: Changing a JAR or ZIP file specified in a<library> element, or a JAR or ZIP file in a directory specified in a <library> element, does not by itself result in redeployment of any Web applications or reloading of classes. The OC4J task manager does not poll these shared library locations.
|
The servlet specification recommends, but does not require, loading local classes, which are classes in the WAR file, before system classes, which are any other classes in the environment. Note that "classes in the WAR file" may include classes from the WAR file manifest classpath. By default, the OC4J servlet container does not load local classes first, but you can configure this through the <web-app-class-loader>
element in global-web-application.xml
or orion-web.xml
. This element has two attributes:
search-local-classes-first
: Set this to "true
" to search and load WAR file classes before system classes. The default setting is "false
".
include-war-manifest-class-path
: Set this to "false
" to not include the classpath specified in the WAR file manifest Class-Path
attribute when searching and loading classes from the WAR file, regardless of the search-local-classes-first
setting. The default setting is "true
".
Notes:
|
Also see "Element Descriptions for global-web-application.xml and orion-web.xml".
To take advantage of the distributed functionality of the Oracle Application Server Java Object Cache, or to share a cached object between servlets, some minor modification to an application deployment is necessary. Any user-defined objects that will be shared between servlets or distributed between JVMs must be loaded by the system classloader; however, by default, objects loaded by a servlet are loaded by the context classloader. Objects loaded by the context classloader are visible only to the servlets within the servlet context corresponding to that classloader. The object definition will not be available to other servlets or to the cache in another JVM. If an object is loaded by the system classloader, however, the object definition will be available to other servlets and to the cache on other JVMs.
With OC4J, the system classpath is derived from the manifest of the oc4j.jar
file and any associated .jar
files, including cache.jar
. The classpath in the environment is ignored. To include a cached object in the classpath for OC4J, do one of the following with the .class
file, assuming an Oracle Application Server environment:
Copy it to the ORACLE_HOME
/javacache/cachedobjects/classes
directory.
Add it to the ORACLE_HOME
/javacache/cachedobjects/share.jar
file.
Both the classes
directory and the share.jar
file are included in the manifest for cache.jar
, and are therefore included in the system classpath.
For information about the Oracle Application Server Java Object Cache, see the Oracle Application Server Containers for J2EE Services Guide.
A servlet typically receives information from one or more sources, including the following:
Parameters from the request object
HTTP session object
Servlet context object
Sources of data outside the servlet (for example: databases, file systems, or external sensors)
The servlet adds information to the response object; the container sends the response back to the client.
Many servlets use other servlets in the course of their processing, either by "including" another servlet or "forwarding" to another servlet.
In servlet terminology, a servlet include is the process by which a servlet includes response from another servlet within its own response. Processing and response are initially handled by the originating servlet, then are turned over to the included servlet, then revert back to the originating servlet once the included servlet is finished.
With a servlet forward, processing is handled by the originating servlet up to the point of the forward call, at which point the response is reset and the target servlet takes over processing of the request. When a response is reset, any HTTP header settings and any information in the output stream are cleared from the response. After a forward, the originating servlet must not attempt to set headers or write to the response. Also note that if the response has already been committed, then a servlet cannot forward to or include another servlet.
To forward to or include another servlet, you must obtain a request dispatcher for that servlet, using either of the following servlet context methods:
RequestDispatcher getRequestDispatcher(String path)
RequestDispatcher getNamedDispatcher(String name)
For getRequestDispatcher()
, input the path of the target servlet. For getNamedDispatcher()
, input the name of the target servlet, according to the <servlet-name>
element for that servlet in the web.xml
file.
In either case, the returned object is an instance of a class that implements the javax.servlet.RequestDispatcher
interface. (Such a class is provided by the servlet container.) The request dispatcher is a wrapper for the target servlet. In general, the duty of a request dispatcher is to serve as an intermediary in routing requests to the resource that it wraps.
A request dispatcher has the following methods to effect any includes or forwards:
void include(ServletRequest request, ServletResponse response)
void forward(ServletRequest request, ServletResponse response)
As you can see, you pass in your request and response objects when you call these methods.
Notes:
|
For a servlet in a nondistributable environment, a servlet container uses only one servlet instance for each servlet declaration. In a distributable environment, a container uses one servlet instance for each servlet declaration in each JVM. Therefore, a servlet container, including the OC4J servlet container, generally processes concurrent requests to a servlet by using multiple threads for multiple concurrent executions of the servlet service()
method.
Servlet developers must keep this in mind, making provisions for simultaneous processing through multiple threads and designing their servlets so that access to shared resources is somehow synchronized or coordinated. Shared resources fall into two main areas:
In-memory data, such as instance or class variables
External objects, such as files, database connections, and network connections
One option is to synchronize the service()
method as a whole; however, this may adversely affect performance.
A better approach is to selectively protect instance or class fields, or access to external resources, through synchronization blocks.
As perhaps a last resort, the servlet specification supports a single-thread model. If a servlet implements the javax.servlet.SingleThreadModel
interface, the servlet container must guarantee that there is never more than one request thread at a time in the service()
method of any instance of the servlet. OC4J typically accomplishes this by creating a pool of servlet instances, with a separate instance handling each concurrent request. This process has significant performance impact on the servlet container, however, and should be avoided if at all possible. Furthermore, the SingleThreadModel
interface will be deprecated in version 2.4 of the servlet specification.
For general information about multithreading, see the Sun Microsystems Java Tutorial on Multithreaded Programming at the following Web site:
http://java.sun.com/docs/books/tutorial/essential/threads/multithreaded.html
The following sections list servlet performance considerations and introduce the Oracle Application Server Dynamic Monitoring Service (DMS):
For general OC4J performance information, including coverage of DMS and the dmstool
for performance metrics, refer to the Oracle Application Server Performance Guide.
This section summarizes issues, mostly documented elsewhere in this manual, that may impact performance:
Consider the optimal expiration setting for Web pages in your application. You can set the expiration for pages that match a given URL pattern, using the <expiration-setting>
subelement of <orion-web-app>
in global-web-application.xml
or orion-web.xml
. (See "Element Descriptions for global-web-application.xml and orion-web.xml".) A more appropriate setting decreases load on the application and improves performance.
Be aware of performance implications relating to how multiple concurrent requests are synchronized or coordinated, and also be aware of related considerations regarding thread models. See "Servlet Thread Models and Related Considerations".
There are performance implications related to how session state is replicated in a distributable environment. Replication is triggered each time there is a setAttribute()
call on the session object, so large numbers of such calls in a servlet may impact performance. In addition, be aware that for performance reasons, OC4J does not wait to confirm successful replication of session state. See "Session Replication in a Distributable Application".
Servlet configuration parameters can significantly affect performance. For information about the file-modification-check-interval
attribute of the <orion-web-app>
element, see "Element Descriptions for global-web-application.xml and orion-web.xml". For information about the use-keep-alives
attribute of the <web-site>
element, see "Element Descriptions for Web Site XML Files".
Additional JSP-related configuration parameters can significantly affect performance. See "Element Descriptions for global-web-application.xml and orion-web.xml" for information about the simple-jsp-mapping
and enable-jsp-dispatcher-shortcut
attributes of the <orion-web-app>
element.
OC4J standalone supports a mode of "shared" operation for a single application through multiple Web sites, where a site is defined as a particular host and port. This feature is particularly intended for secure applications in which some but not all communications require HTTPS. Running the noncritical communications through an HTTP port improves performance. See "Element Descriptions for Web Site XML Files" for information about the shared
attribute of the <web-app>
element.
If you ever use OC4J standalone as a production environment (although this is not typical), remember to disable the server.xml
check-for-updates
flag. See "Key OC4J Flags for Development".
In an Oracle Application Server environment, DMS adds performance-monitoring features to several components, including OC4J. The goal of DMS is to provide information about runtime behavior through built-in performance measurements so that users can diagnose, analyze, and debug any performance problems. DMS provides this information in a package that can be used at any time, including during live deployment. Data are published through HTTP and can be viewed with a browser.
Standard configuration for the DMS servlets, such as the spy servlet and monitoring agent, is in the global application.xml
file and the default-web-site.xml
file.
In the OC4J application.xml
file, the Web modules dms
and dms0
and the paths to their WAR files are specified. The default-web-site.xml
file specifies that these Web modules are deployed to the OC4J default application and binds them to their context paths. Do not directly alter any of these DMS configurations.
Use the Oracle Enterprise Manager 10g to access DMS, display DMS information, and, if appropriate, alter DMS configuration.
Among the migration considerations in moving to a Sun Microsystems JDK 1.4 environment, which is the environment shipped with Oracle Application Server 10g Release 2 (10.1.2), one is of particular importance to servlet and JSP developers.
To address security concerns and ambiguities with previous JDK versions, Sun Microsystems modified the Java compiler to reject import statements that import a type from the "unnamed namespace". So essentially, you cannot invoke a class (a method of a class) that is not within a package. Any attempt to do so will result in a fatal error at compilation time.
This issue especially affects JSP developers who invoke JavaBeans from their JSP pages, because such beans are often outside of any package (although version 2.0 of the JSP specification now requires beans to be within packages, to satisfy the new compiler requirements). Where JavaBeans outside of packages are invoked, JSP applications that were built and executed in an OC4J 9.0.3 / JDK 1.3.1 environment will no longer work in an OC4J 10.1.2 / JDK 1.4 environment.
Until you update your application so that all JavaBeans and other invoked classes are within packages, you can avoid this issue by reverting back to a JDK 1.3.1 environment for OC4J standalone. Note that JDK 1.3.x is not supported in a full Oracle Application Server 10.1.2 environment.
Notes:
|
For more information about the "classes not in packages" issue and other JDK 1.4 compatibility issues, refer to the following Web site:
http://java.sun.com/j2se/1.4/compatibility.html
In particular, click the link "Incompatibilities Between Java 2 Platform, Standard Edition, v1.4.0 and v1.3".
The followings sections describe additional features, mostly Oracle-specific, to consider in developing and running servlets in OC4J:
The following sections provide an overview of OC4J logging features:
Additional Oracle Application Server Log Files
Note: Logging features discussed here are for log messages from the OC4J server. It is also possible to use open source frameworks and utilities with OC4J, such as those from the Apache Jakarta Project. This includes log4j, a complementary technology that you can use to insert log statements in your own code. See "Configuration and Use of Jakarta log4j in OC4J". |
Several logs are available in OC4J. Because they are not specific to servlets, they are documented elsewhere, but this section provides a summary list and appropriate cross-references. For each log, you have the option of using text-based logging or ODL logging. (See the next section, "Oracle Diagnostic Logging Versus Text-Based Logging".) Note that for ODL, log file names always take the form log
N
.xml
, where N
is an integer. For text-based logging, you must specify the log file names.
For each log there is a configuration element in the appropriate OC4J configuration file to enable text-based logging, and a separate element to enable ODL logging. The presence of a logging configuration element enables the associated type of logging.
OC4J supports the following logs:
Application log
There is a log for each application deployed, as configured in orion-application.xml
. For text-based logging, a typical name is application.log
.
Global application log
There is a log for global logging for all applications, including the default application, as configured in the OC4J global application.xml
file. For text-based logging, a typical name is global-application.log
.
JMS log
There is a log for Java Message Service (JMS) functionality, as configured in jms.xml
. For text-based logging, a typical name is jms.log
.
RMI log
There is a log for remote method invocation functionality, as configured in rmi.xml
. For text-based logging, a typical name is rmi.log
.
Server log
There is a server-wide log, as configured in server.xml
. For text-based logging, a typical name is server.log
.
Web site access log
There is a Web site access log (one log file for each Web site to log all accesses of the site), as configured in the Web site XML file. For text-based logging, a typical name is http-access.log
.
Note: For Web site access logging, you can use only one type of logging, not both. |
Configuration of the Web access log is covered in this manual. Under "Element Descriptions for Web Site XML Files", see the information about the <access-log>
and <odl-access-log>
subelements of the <web-site>
element.
The Oracle Application Server Containers for J2EE User's Guide has information about how to enable logging to the other OC4J files.
For each of the logs listed in the preceding section, "OC4J Logs", you have the option of using Oracle Diagnostic Logging (ODL), which offers some advantages over text-based logging.
ODL provides standardized logging across all components of OC4J, creating the log files in an XML format that can be loaded to a repository for reporting and viewing. You can view ODL logs from Oracle Enterprise Manager 10g, for example.
With ODL, it is also easier to manage the size and number of your log files. In many situations, text-based logging results in the need to periodically shut down the OC4J server and manually clean up the files.
To enable and configure ODL logging for the Web site access log file, use the <odl-access-log>
subelement of the <web-site>
element in the Web site XML file. To enable and configure text-based logging, use the <access-log>
subelement of the <web-site>
element instead. (Note, however, that either element can be overridden for any particular Web application by a setting of access-log="false"
in the <web-app>
element of the Web application in the Web site XML file.)
For each of the other OC4J logs, use the <odl>
subelement of the <log>
element in the appropriate XML configuration file if you want to use ODL logging. To use text-based logging, use the <file>
subelement of the <log>
element instead.
Note: Web site access logs commonly use standard XLF or CLF format (extended log file format or common log file format). Users can split the files according to a specified time period, such as time of day or day of month. ODL Web site logs, however, do not support XLF or CLF format and you cannot split files by time period. When you reach the maximum size of an ODL log file, a new file is automatically created. (Log file names arelog1.xml , log2.xml , and so on.)
|
See the Oracle Application Server Containers for J2EE User's Guide for additional information about ODL.
In addition to the OC4J log files discussed previously, Oracle Application Server supports the following log files:
OPMN log file (one log file for each OC4J instance, for Oracle Process Management and Notification functionality)
ons.log
(OPMN notification system log, configured in opmn.xml
)
ipm.log
(OPMN process management log, configured in opmn.xml
)
OPMN manages Oracle HTTP Server and OC4J processes within an application server instance.
For information about Oracle Application Server log file management, refer to Oracle Application Server Administrator's Guide.
This discussion summarizes debugging features and considerations for servlet developers, with appropriate cross-references for additional information. It consists of the following sections:
OC4J supports several flags to enable debugging output for its subsystems.
Here are the HTTP debugging flags:
http.error.debug
for all HTTP errors; otherwise some are consumed without being reported
http.cluster.debug
for debugging statements regarding HTTP clustering and session persistence
http.session.debug
for HTTP session errors and lifecycle statements
http.request.debug
for information from HTTP request stream
http.redirect.debug
for information about HTTP redirects
debug.http.contentLength
to print explicit content-length calls as well as extra sendError
information
http.virtualdirectory.debug
to print the enforced virtual directory mappings upon startup
http.method.trace.allow
to enable the traceHTTP()
method
Here are the AJP debugging flags (for Oracle Application Server with Oracle HTTP Server only):
ajp.debug
to print the incoming AJP stream
ajp.io.debug
to print the AJP response from the server
The AJP flags do not produce user-friendly output, but are necessary for debugging some AJP issues.
Here are the JDBC debugging flags:
datasource.verbose
for information about the creation of data sources and database connections
jdbc.debug
for detailed information about JDBC calls
Here is the EJB debugging flag:
ejb.cluster.debug
for information about EJB clustering
Here are the RMI debugging flags:
rmi.debug
for information about remote method invocations
rmi.verbose
for detailed information about RMI calls
Here is the Web services debugging flag:
ws.debug
for information about Web services
The debugging flags are enabled through Java option settings such as the following:
-Dhttp.session.debug=true
If you are using OC4J standalone, specify option settings in the Java command line when you start OC4J. In an Oracle Application Server environment, use Oracle Enterprise Manager 10g. Specify option settings in the Java Options field under Command Line Options in the Application Server Control Console Server Properties Page for the OC4J instance. To get to this page, select Server Properties under Instance Properties in the Administration Page for the OC4J instance. See "Application Server Control Console OC4J Administration Page". See the Oracle Application Server Containers for J2EE User's Guide for further information.
Because of the way OPMN functions, there are timing issues to consider when debugging in an Oracle Application Server environment. Specifically, whenever debugging results in the halting of a process, OPMN terminates that process after the halt goes beyond the timeout period.
To remedy this situation, you must set an appropriate timeout value, using the <timeout>
element in the opmn.xml
file.
For information about opmn.xml
, particularly for starting and stopping Oracle Application Server, refer to the Oracle Application Server Administrator's Guide.
If you use Oracle JDeveloper as your development environment, you can take advantage of its debugging features.
For debugging, JDeveloper offers local and remote debugging of JSP pages, servlets, and other Java source files. You can start by setting breakpoints in the source files within JDeveloper and running a debugging session with the source selected. While debugging an application such as a servlet in JDeveloper, you have complete control over the execution flow and can view and modify variable values, as well as perform advanced application performance monitoring, such as viewing class instance counts and memory usage. JDeveloper will follow calls from your application into other source files or offer to generate stub classes for class sources that are not available. Remote debugging, after the code to be debugged is launched and the JDeveloper debugger is attached to it, is similar to local debugging.
See "Oracle JDeveloper Support for Servlet Development" for a general summary of JDeveloper features for servlet development.
Note: Other key IDE vendors offer plug-in modules that allow seamless integration with OC4J. This provides developers with the capability to build, deploy, and debug J2EE applications running on OC4J directly from within the IDE. You can refer to the following Web site for more information:
(To access the preceding Web site, you must have an Oracle Technology Network membership, but it is free of charge.) |
Visual Java programming tools now typically support servlet coding. In particular, Oracle JDeveloper supports servlet development and includes the following features:
Wizards to help generate servlet code
Integration of the OC4J servlet container to support the full application development cycle: editing, debugging, and running servlets
Debugging of deployed servlets
An extensive set of data-enabled and Web-enabled JavaBeans, known as JDeveloper Web beans
Support for incorporating custom JavaBeans
A deployment option for servlet applications that rely on Oracle Application Development Framework (Oracle ADF) Business Components
Also see "Debugging Through JDeveloper and Other IDEs".
For general information about JDeveloper, refer to the JDeveloper online help or to the following site on the Oracle Technology Network:
http://www.oracle.com/technology/products/jdev/content.html
OC4J supports some common open source utilities and frameworks. For Oracle Application Server 10g Release 2 (10.1.2), this document discusses support for two in particular:
Jakarta Struts
Jakarta log4j
The focus is on configuring and using these open source utilities in the OC4J standalone environment. See Appendix A, "Open Source Frameworks and Utilities".
A servlet is invoked by the container when a request for the servlet arrives from a client. The client request may come from a Web browser or a Java client application, or from another servlet in the application using the request forwarding mechanism, or from a remote object on a server. A servlet is requested through its URL mapping.
The following sections cover servlet invocation, including some special OC4J features for invoking a servlet by class name in a development or testing scenario:
Before discussing servlet invocation, it is useful to summarize the components of a URL. Here is the generic construct (though note that pathinfo
is usually empty):
protocol://host:port/contextpath/servletpath/pathinfo
You could also have additional information following any delimiters, such as request parameter settings following a question mark ("?
") delimiter:
protocol://host:port/contextpath/servletpath/pathinfo?param=value
Table 2-2 describes the components of the generic construct.
Table 2-2 URL Components
Component | Description |
---|---|
Protocol |
The network protocol to be used when invoking the Web application. Examples are |
Host |
The network name of the server that the Web application is running on. If the Web client is on the same system as the application server, you can use www.example.com |
Port |
The port that the Web server listens on. If a URL does not specify a port, most browsers assume port 80 for HTTP protocol or port 443 for HTTPS. For OC4J, the port number is specified in the |
Context path |
The designated root path for the servlet context. You specify the context path when you deploy an application. For OC4J, the specified context path is reflected in the setting of the Each servlet context is associated with a directory path in the server file system. The <web-app application="ojspdemos" name="ojspdemos-web" root="/ojspdemos" /> |
Servlet path |
The designated path, beyond the context path, for the particular servlet you want to invoke. You specify the servlet path through standard mappings in the application <web-app> ... <servlet> <servlet-name>logout</servlet-name> <servlet-class> oracle.security.jazn.samples.http.Logout </servlet-class> </servlet> ... <servlet-mapping> <servlet-name>logout</servlet-name> <url-pattern>/logout/*</url-pattern> </servlet-mapping> ... </web-app> |
Path information |
(This is typically empty.) Beyond the context path and servlet path, a URL can contain additional information that is supplied to the servlet through the HTTP request object. Such information is presumably understood by the servlet. This information is separate from any request parameter settings or other URL components that follow delimiters such as question marks. Such delimiters would follow any path information. |
Note: The name specified in a<servlet-name> element is the name you input to the servlet context getNamedDispatcher() method if you want a request dispatcher for that servlet.
|
For more information about the OC4J configuration elements and attributes discussed in Table 2-2, see "Element Descriptions for Web Site XML Files". For information about elements and attributes of the web.xml
file, refer to the servlet specification
Consider the following sample URL:
http://www.example.com:8888/foo/bar/mypath/MyServlet/info1/info2?user=Amy
In the process of invoking a servlet according to a URL supplied by a client browser, the servlet container takes the following steps:
It examines everything in the URL after the port number, then examines its own configuration settings (such as in a Web site XML file) for recognized context paths, then determines what part of the URL is the context path.
Assume for this example that /foo/bar
is the context path.
It examines everything in the URL after the context path, then examines the servlet mappings in the web.xml
file for recognized servlet paths, then determines what part of the URL is the servlet path.
At this point, the servlet can be invoked. The servlet container does not use any information beyond the servlet path.
Assume for this example that /mypath/MyServlet
is the servlet path.
If anything remains in the URL after the servlet path and preceding any URL delimiters (such as "?
" in this example, which delimits request parameter settings), that portion of the URL is taken as extra information and is passed to the servlet through the HTTP request object.
Assume for this example that /info1/info2
is the extra path information.
Note that the context path, servlet path, and any path information can all be "compound" components, with one or more forward-slashes in between parts. The preceding example shows this. In many cases, the context path may be simple, such as just foo
, and the servlet path may also be simple, such as just MyServlet
, and any path information may be simple as well. But it is impossible to know by just looking at a URL what part of it is the context path, what part is the servlet path, and what part is extra path information (if any). You must examine the configuration in the Web site XML file and web.xml
file to determine this.
Notes:
|
For a development or testing scenario in OC4J, there is a convenience mechanism for invoking a servlet by class name. For security reasons, use this mechanism only while developing your application. It is not enabled in the OC4J default configuration.
The servlet-webdir
attribute in the <orion-web-app>
element of the global-web-application.xml
file or orion-web.xml
file defines a special URL component used to invoke servlets by class name. This URL component follows the context path in the URL, and anything following this URL component is assumed to be a servlet class name, including applicable package information, within the appropriate servlet context. The servlet class name appears instead of a servlet path in the URL. (Technically, the servlet-webdir
value is the servlet path and acts as a servlet itself, and the class name of the servlet you wish to execute is taken as path information.)
Generally speaking, for any given application, OC4J behavior for invocation by class name is determined by the servlet-webdir
setting in the orion-web.xml
file for that application, if there is a setting. But note the following:
Any setting of servlet-webdir
in the global-web-application.xml
file acts as a default value (as is true with configuration settings in global-web-application.xml
in general). If there is no servlet-webdir
setting in global-web-application.xml
, however, then the default value is ""
(empty quotes). This setting disables invocation by class name. The default value is used in the event that orion-web.xml
is not provided with the application deployment, or does not have a servlet-webdir
setting.
Servlet invocation by class name can be disabled in either of two ways:
A system property http.webdir.enable
setting of false
. This results in any servlet-webdir
setting being ignored.
A servlet-webdir
value of ""
(empty quotes), either through global-web-application.xml
or orion-web.xml
.
For information about OC4J system properties, see the Oracle Application Server Containers for J2EE Stand Alone User's Guide, or the Oracle Application Server Containers for J2EE User's Guide for an Oracle Application Server environment.
The following URL invokes a servlet called SessionServlet
by its class name, assuming a setting of servlet-webdir="/servlet/"
. In this example, assume SessionServlet
is in package foo.bar
and executes in the OC4J default Web application. Also assume a context path of "/
" (the default for the default Web application in OC4J standalone).
http://www.example.com:8888/servlet/foo.bar.SessionServlet
This mechanism applies to any servlet context, however, and not just for the default Web application. If the context path is foo
, for example, the URL to invoke by class name is as follows:
http://www.example.com:8888/foo/servlet/foo.bar.SessionServlet
Important: Allowing the invocation of servlets by class name presents a significant security risk. Do not configure OC4J to operate in this mode in a production environment. See "Additional Security Considerations" for information. |
The following sections describe Oracle HTTP Server and OC4J features for servlet invocation in an Oracle Application Server Environment:
In an Oracle Application Server production environment, OC4J should always be accessed through the Oracle HTTP Server. Oracle HTTP Server uses AJP (Apache JServ protocol) to communicate to OC4J, but this is invisible to the end user.
When a servlet is requested, the OC4J servlet container interprets the URL, as "Summary of URL Components" describes.
Whatever port number you use is mapped to AJP protocol through a <web-site>
element in the default-web-site.xml
file. (This is the typical name, but Web site XML file names are defined according to settings in the server.xml
file and can be changed as desired.) The port mapping is defined through the port
and protocol
attributes of the <web-site>
element, with port
set as desired and protocol
set to "ajp13
". By default, port 7777 is for access through the Oracle HTTP Server with Oracle Application Server Web Cache enabled.
Whenever you use Enterprise Manager to deploy an application, you are prompted for a URL mapping. The mapping you specify results in a new OC4J mount point in mod_oc4j.conf
. If you specify a URL mapping of "/mypath
", for example, this is the context path of your Web application and is defined as a new OC4J mount point. Then you invoke a servlet with a URL such as the following:
http://www.example.com:7777/mypath/MyServlet
See "Application Server Control Console Deploy Application (EAR) Page" and "Application Server Control Console Deploy Web Application (WAR) Page" for information about the Enterprise Manager EAR and WAR deployment pages.
For an overview of deployment to Oracle Application Server, see "OC4J Deployment in Oracle Application Server". For further information, see the Oracle Application Server Containers for J2EE User's Guide. For general information about Enterprise Manager, see Oracle Enterprise Manager Concepts.
See the Oracle HTTP Server Administrator's Guide for information about Oracle HTTP Server configuration, mount points, and the mod_oc4j.conf
file.
An additional element in the default-web-site.xml
file (or other Web site XML file) is relevant in servlet invocation. The <frontend>
subelement of the <web-site>
element can specify a perceived front-end host and port of the Web site as seen by HTTP clients. When the site is behind a load balancer or firewall, the <frontend>
specification is necessary to provide appropriate information to the Web application for functionality such as URL rewriting. Attributes are host
, for the name of the front-end server (such as "www.example.com"
), and port
, for the port number of the front-end server (such as "8080"
). Using this front-end information, the back-end server that is actually running the application knows to refer to www.example.com
, instead of to itself, in any URL rewriting. This way, subsequent requests properly come in through the front-end again, instead of trying to access the back-end directly.
The specified front-end host
and port
settings are also reflected back to the servlet and are the values you receive if you call the getServerName()
or getServerPort()
method of the HTTP request object.
In OC4J standalone, a Web site uses HTTP protocol without going through the Oracle HTTP Server and AJP, and is configured according to settings in the http-web-site.xml
file. (This is the typical name, but Web site XML file names are according to settings in the server.xml
file and can be changed as desired.)
When a servlet is requested, the OC4J servlet container interprets the URL, as "Summary of URL Components" describes.
Whatever port number you use is mapped to HTTP protocol through a <web-site>
element in the http-web-site.xml
file (or other Web site XML file, as applicable). The port mapping is defined through the port
and protocol
attributes of the <web-site>
element, with port
set as desired and protocol
set to "http
". By default, port 8888 is for direct access to OC4J through its own Web listener.
In OC4J standalone, the default context path is "/
" to use HTTP protocol for an application deployed to the OC4J default Web application. Here is an example:
http://www.example.com:8888/MyServlet
If you are not using the default Web application, specify the context path while deploying the application. You can either do this through the admin.jar
utility, or by manual deployment and manual edits of the http-web-site.xml
file (not recommended). Deployment for OC4J standalone is discussed in "Deployment Scenarios to OC4J Standalone", but for complete information see the Oracle Application Server Containers for J2EE Stand Alone User's Guide. That document also has information about OC4J port settings and other default settings.
If you specify "/mypath
" as the context path, for example, you will invoke the servlet with a URL such as the following:
http://www.example.com:7777/mypath/MyServlet
Servlet sessions were introduced in "Introduction to Servlet Sessions". The following sections provide details and examples:
Important: When you deploy a new Web module to an active OC4J instance, the HTTP sessions for every Web application running within the server instance will be lost by default. You can avoid this issue on non-clustered OC4J instances by defining a "persistence directory" in theorion-web.xml file of each Web application. (See information for the persistence-path attribute of <orion-web-app> under "Element Descriptions for global-web-application.xml and orion-web.xml".) Existing HTTP sessions will be stored in this temporary location across application deployments.
Note that the persistence directory feature is not applicable for OC4J instances within a clustered environment. For guidelines on addressing the session state issue in a clustered environment, see the Oracle Application Server High Availability Guide. |
This section provides an overview of servlet session tracking and features, then describes the OC4J implementation.
The HTTP protocol is stateless by design. This is fine for stateless servlets that simply take a request, perform a few computations, output some results, and then in effect go away. But most server-side applications must keep some state information and maintain a dialogue with the client. The most common example of this is a shopping cart application. A client accesses the server several times from the same browser and visits several Web pages. The client decides to buy some of the items offered for sale at the Web site and clicks the BUY ITEM buttons. If each transaction were being served by a stateless server-side object, and the client provided no identification on each request, it would be impossible to maintain a filled shopping cart over several HTTP requests from the client. In this case, there would be no way to relate a client to a server session, so even writing stateless transaction data to persistent storage would not be a solution.
Session tracking involves identifying user sessions by ID numbers and tying requests to their session through use of the ID number. This process is typically performed using cookies or URL rewriting.
The OC4J servlet container, to comply with the servlet specification, implements session tracking through HTTP session objects, which are instances of a class that implements the javax.servlet.http.HttpSession
interface.
When a servlet creates an HTTP session object (through the request object getSession()
method), the client interaction is considered to be stateful.
An HTTP session object has scope over the Web application only. You cannot use session objects to share data between applications. Nor can you use session objects to share data between different clients of the same application. There is one HTTP session object for each client in each application.
Note: To share information between clients or applications, you can store such persistent data in a database if you need the protection, transactional safety, and backup that a database offers. Alternatively, you can save persistent information on a file system or in a remote object. |
Several approaches have been used to add a measure of statefulness to the HTTP protocol. The most widely accepted is the use of cookies, used to transmit an identifier between server and client, in conjunction with stateful servlets that can maintain session objects. Session objects are simply dictionaries that store values (Java objects) together with their associated keys (Java strings).
Cookie usage is as follows:
With the first response from a stateful servlet after a session is created, the server (container) sends a cookie with a session identifier back to the client, often along with a small amount of other useful information (all less than 4 KB). The container sends the cookie, named JSESSIONID
, in the HTTP response header.
Upon each subsequent request from the same Web client session (assuming the client supports cookies), the client sends the cookie back to the server as part of the request, and the server uses the cookie value to look up session state information to pass to the servlet.
With subsequent responses, the container sends the updated cookie back to the client.
The servlet code is not required to do anything to send a cookie; the container handles this. Sending cookies back to the server is handled automatically by the Web browser, unless the user disables cookies.
The container uses the cookie for session maintenance. A servlet can retrieve cookies using the getCookies()
method of the HttpServletRequest
object and can examine cookie attributes using the accessor methods of the javax.servlet.http.Cookie
objects.
An alternative to using cookies is URL rewriting, through the encodeURL()
method of the response object. In this mechanism, the session ID is encoded into the URL path of a request. See "Session Servlet Example" for an example of URL rewriting.
The name of the path parameter is jsessionid
, as in the following example:
http://host:port/myapp/index.html?jsessionid=6789
The value of the rewritten URL is used by the server to look up session state information to pass to the servlet, which is similar to the functionality of cookies.
Although cookies are typically enabled, the only way for you to ensure session tracking is to use encodeURL()
in your servlets, or encodeRedirectURL()
for redirects.
Note: To comply with the servlet specification, calls to theencodeURL() and encodeRedirectURL() methods result in no action if cookies are enabled.
|
Other techniques have been used in the past to relate client and server sessions, including server hidden form fields and user authentication mechanisms to store additional information. Oracle does not recommend these techniques in OC4J applications. They have many drawbacks, including performance penalties and loss of confidentiality.
For session-tracking in OC4J, the servlet container first attempts to accomplish tracking through cookies. If cookies are disabled, the server can maintain session tracking only by using the encodeURL()
method of the response object, or the encodeRedirectURL()
method for redirects. You must include the encodeURL()
or encodeRedirectURL()
calls in your servlet if cookies may be disabled.
You can use the following setting in the global-web-application.xml
or orion-web.xml
file to disable the use of session cookies:
<session-tracking cookies="disabled" ... > ... </session-tracking>
Cookies are enabled by default.
|
The servlet container uses HTTP session objects—instances of a class that implements the javax.servlet.http.HttpSession
interface—in tracking and managing user sessions. The HttpSession
interface specifies the following public methods to get and set session information:
void setAttribute(String name, Object value)
This method binds the specified object to the session, under the specified name.
Object getAttribute(String name)
This method retrieves the object that is bound to the session under the specified name (or null
if there is no match).
Depending on the configuration of the servlet container and the servlet itself, sessions may expire automatically after a set amount of time or may be invalidated explicitly by the servlet. Servlets can manage session lifecycle with the following methods, specified by the HttpSession
interface:
void invalidate()
This method immediately invalidates the session, unbinding any objects from it.
void setMaxInactiveInterval(int interval)
This method sets a session timeout interval, in seconds, as an integer. A negative value indicates no timeout. A value of 0 results in an immediate timeout.
boolean isNew()
This method returns true
within the request that created the session; it returns false
otherwise.
long getCreationTime()
This method returns the time when the session object was created, measured in milliseconds since midnight, January 1, 1970.
long getLastAccessedTime()
This method returns the time of the most recent request associated with the client session, measured in milliseconds since midnight, January 1, 1970. If the client session has not yet been accessed, this method returns the session creation time.
For an example of how a servlet can use an HTTP session object, see "Session Servlet Example".
For complete information about HttpSession
methods, refer to the Sun Microsystems Javadoc at the following location:
http://java.sun.com/products/servlet/2.3/javadoc/index.html
HTTP session objects persist for the duration of the server-side session. A session is either terminated explicitly by the servlet or it "times out" after a certain period and is cancelled by the container.
The default session timeout for the OC4J server is 20 minutes. You can change this for a specific application by setting the <session-timeout>
subelement under the <session-config>
element of web.xml
. Specify the timeout in minutes, as an integer. For example, to reduce the session timeout to five minutes, add the following lines to the application web.xml
file:
<session-config> <session-timeout>5</session-timeout> </session-config>
According to the servlet specification, a negative value specifies the default behavior that a session never times out. For example:
<session-config> <session-timeout>-1</session-timeout> </session-config>
A value of 0 results in an immediate timeout.
The session object of a stateful servlet can be replicated to other OC4J servers in a load-balanced cluster island. If the server handling a request to a servlet should fail, the request can "failover" to another JVM on another server in the cluster island, and the session state will still be available.
The following sections provide more information:
To enable replication of the session state of an application between OC4J servers, you must mark the Web application as distributable, by use of the standard <distributable>
element in the web.xml
file. The presence of this subelement of the <web-app>
element, as follows, specifies that the application is distributable:
<web-app ... > ... <distributable/> ... </web-app>
Note: In an Oracle Application Server environment, accomplish this through Oracle Enterprise Manager 10g. See the discussion of clustering in the Oracle Application Server Containers for J2EE User's Guide for details. |
Objects that are stored by a servlet in the HttpSession
object are replicated. For replication to work properly, objects must be serializable (directly or indirectly implementing the java.io.Serializable
interface) or remoteable (directly or indirectly implementing the java.rmi.Remote
interface). Furthermore, any objects that are referenced by objects in the session object must themselves be serializable or remoteable.
Replicated data is sent asynchronously to the other OC4J servers in the cluster island. For performance reasons, OC4J does not wait to confirm successful replication. Therefore, either of the following scenarios is possible, though highly unlikely:
Broadcast latency, where session replication messages are not received and processed by the other OC4J servers before a client is rerouted:
A client sends a request and receives a response from the OC4J server.
The server broadcasts a replication message to the other OC4J servers in the cluster island with the updated state for the client.
The client sends another request before the broadcast of the updated state has been received and processed by all OC4J servers.
The original server fails, and the client is rerouted to one of the OC4J servers that does not yet have the new state information, resulting in the client receiving old data.
Failure before response to client, where a server fails after it has broadcast its replication message to other servers, but before it has completed its response to the client:
A client sends a request to the OC4J server.
The server broadcasts a replication message to the other OC4J servers in the cluster island with the updated state for the client.
The server fails, however, before completing its response to the client. This results in the client being unaware of the processing completed by the server, even though other OC4J servers are aware.
Because of the possible error scenarios, OC4J and Oracle HTTP Server maintain session affinity, meaning they make every effort to always route requests and responses through the same OC4J JVM. The session cookie, JSESSIONID
, maintains the required, detailed routing information across HTTP requests to ensure that subsequent requests through Oracle HTTP Server are dispatched to the originating JVM wherever possible.
In addition, the OC4J 10.1.2 implementation supports two environment flags that you can use to reduce the risk of either error scenario occurring:
cluster.thread.priority
: By default, OC4J clustering threads run with the same priority as the other main OC4J threads. You can, however, set this flag to any integer value from 6 through 10 to give clustering threads higher priority, with 10 being the highest priority.
cluster.failover.delay
: In the event that an OC4J server fails, this flag results in a delay of the specified number of milliseconds before a client is rerouted to an alternate server. The default is no delay. A setting between 7000 and 9000 is probably sufficient to avoid the first of the error scenarios described above.
For a distributable application, session replication is triggered each time there is a setAttribute()
call on the session object. The name and value specified in the call are serialized and replicated, with the serialized value being stored using the specified name as the key. The value is deserialized only upon first access by a failed-over servlet.
Note that you must explicitly call setAttribute()
whenever you update a data item belonging to the session object. For example, if you call getAttribute()
on the session object to retrieve a bean and then call a method on the bean to change its state, you must then call setAttribute()
on the session object to update the bean in the session. This is in contrast to the situation in a nondistributable environment, in which the bean is passed to you by reference and updated directly within the session object as soon as you call the method on the bean.
Also note the performance implications of this functionality. A servlet with a large number of setAttribute()
calls may have lower performance because of the small overhead introduced when performing state replication.
Note: You can observe the runtime status of replication and session state updates by enabling the OC4J debugging flagshttp.session.debug and http.cluster.debug . See "OC4J Debugging Flags" and "Setting OC4J Debugging Flags".
|
The following SessionServlet
code implements a servlet that establishes an HttpSession
object and prints data held by the request and session objects.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.Date; public class SessionServlet extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Get the session object. Create a new one if it doesn't exist. HttpSession session = req.getSession(true); res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<head><title> " + "SessionServlet Output " + "</title></head><body>"); out.println("<h1> SessionServlet Output </h1>"); // Set up a session hit counter. "sessionservlet.counter" is just the // conventional way to create a key for the value to be stored in the // session object "dictionary". Integer ival = (Integer) session.getAttribute("sessionservlet.counter"); if (ival == null) { ival = new Integer(1); } else { ival = new Integer(ival.intValue() + 1); } // Save the counter value. session.setAttribute("sessionservlet.counter", ival); // Report the counter value. out.println(" You have hit this page <b>" + ival + "</b> times.<p>"); // This statement provides a target that the user can click // to activate URL rewriting. It is not done by default. out.println("Click <a href=" + res.encodeURL(HttpUtils.getRequestURL(req).toString()) + ">here</a>"); out.println(" to ensure that session tracking is working even " + "if cookies aren't supported.<br>"); out.println("Note that by default URL rewriting is not enabled" + " due to its large overhead."); // Report data from request. out.println("<h3>Request and Session Data</h3>"); out.println("Session ID in Request: " + req.getRequestedSessionId()); out.println("<br>Session ID in Request is from a Cookie: " + req.isRequestedSessionIdFromCookie()); out.println("<br>Session ID in Request is from the URL: " + req.isRequestedSessionIdFromURL()); out.println("<br>Valid Session ID: " + req.isRequestedSessionIdValid()); // Report data from the session object. out.println("<h3>Session Data</h3>"); out.println("New Session: " + session.isNew()); out.println("<br> Session ID: " + session.getId()); out.println("<br> Creation Time: " + new Date(session.getCreationTime())); out.println("<br>Last Accessed Time: " + new Date(session.getLastAccessedTime())); out.println("</body>"); out.close(); } public String getServletInfo() { return "A simple session servlet"; } }
In OC4J standalone, save the preceding code into a file SessionServlet.java
in the OC4J default Web application /WEB-INF/classes
directory. By default, the default Web application root directory is j2ee/home/default-web-app
. (See "OC4J Default Application and Default Web Application" for more information.)
For convenience, use the development="true"
setting in the <orion-web-app>
element of the global-web-application.xml
file. See "Element Descriptions for global-web-application.xml and orion-web.xml" for more information about the development
flag.
Figure 2-1 shows the output of this servlet when a Web browser that has cookies enabled invokes it the second time in a session. Experiment with different Web browser settings—for example, by disabling cookies—then select the HREF that causes URL rewriting.
OC4J supports Secure Socket Layer (SSL) communication between Oracle HTTP Server and OC4J in an Oracle Application Server environment, using secure AJP. This is the secure version of Apache JServ Protocol, the protocol Oracle HTTP Server uses to communicate with OC4J. The following sections provide details:
This discussion is followed by a section of general security considerations:
Notes:
|
See the following documents for additional information about Oracle Application Server security and Oracle HTTP Server.
Oracle Application Server Security Guide (including information about secure protocol between a client and Oracle HTTP Server)
Oracle Application Server Containers for J2EE Security Guide (including an overview of SSL keys, certificates, and related concepts)
The following sections discuss how to use SSL features with OC4J and Oracle HTTP Server:
The steps below are for using keys and certificates for SSL communication in OC4J. These are server-level steps, typically executed prior to deployment of an application that will require secure communication, perhaps when you first set up an Oracle Application Server instance.
Note that a keystore stores certificates, including the certificates of all trusted parties, for use by a program. Through its keystore, an entity such as OC4J (for example) can authenticate other parties, as well as authenticate itself to other parties. Oracle HTTP Server uses what is called a wallet for the same purpose.
In Java, a keystore is a java.security.KeyStore
instance that you can create and manipulate using the keytool
utility that is provided with the Sun Microsystems JDK. The underlying physical manifestation of this object is a file. Go to the following Web site for information about keytool
:
http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html
The Oracle Wallet Manager has functionality for Oracle wallets that is equivalent to the functionality of keytool
for keystores.
Here are the steps in using certificates between OC4J and Oracle HTTP Server:
Use keytool
to generate a private key, public key, and unsigned certificate.You can place this information into either a new keystore or an existing keystore.
Obtain a signature for the certificate, using either of the following two approaches.
Generate your own signature:
Use keytool
to "self-sign" the certificate. This is appropriate if your clients trust you as, in effect, your own certificate authority.
Alternatively, obtain a signature from a recognized certificate authority:
Using the certificate from Step 1, use keytool
to generate a certificate request, which is a request to have the certificate signed by a certificate authority.
Submit the certificate request to a certificate authority.
Receive the signature from the certificate authority, and import it into the keystore, again using keytool
. In the keystore, the signature is matched with the associated certificate.
Note: Oracle Application Server includes Oracle Application Server Certificate Authority (OCA). OCA allows customers to create and issue certificates for themselves and their users, although these certificates would probably be unrecognized outside a customer's organization without prior arrangements. See the Oracle Application Server Certificate Authority Administrator's Guide for information about OCA. |
The process for requesting and receiving signatures is up to the particular certificate authority you use. Because that is outside the scope and control of Oracle Application Server, the documentation does not cover it. You can go to the Web site of any certificate authority for information. (Any browser should have a list of trusted certificate authorities.) Here are the Web addresses for VeriSign, Inc. and Thawte, Inc., for example:
http://www.verisign.com/
http://www.thawte.com/
For SSL communication between OC4J and Oracle HTTP Server, execute the preceding steps for Oracle HTTP Server, but use a wallet and Oracle Wallet Manager instead of a keystore and the keytool
utility. See the Oracle Application Server Security Guide for information about wallets and the Oracle Wallet Manager.
In addition to steps 1 and 2 above, execute the following steps as necessary:
If the OC4J certificate is signed by an entity that Oracle HTTP Server does not yet trust, obtain the certificate of the entity and import it into Oracle HTTP Server. The specifics depend on whether the OC4J certificate in question is self-signed, as follows.
If OC4J has a self-signed certificate (essentially, Oracle HTTP Server does not yet trust OC4J):
From OC4J, use keytool
to export the OC4J certificate. This step places the certificate into a file that is accessible to Oracle HTTP Server.
From Oracle HTTP Server, use Oracle Wallet Manager to import the OC4J certificate.
Alternatively, if OC4J has a certificate that is signed by another entity (that Oracle HTTP Server does not yet trust):
Obtain the certificate of the entity in any appropriate way, such as by exporting it from the entity. The exact steps vary widely, depending on the entity.
From Oracle HTTP Server, use Oracle Wallet Manager to import the certificate of the entity.
If the Oracle HTTP Server certificate is signed by an entity that OC4J does not yet trust, and OC4J is in a mode of operation that requires client authentication (as "Requesting Client Authentication" discusses):
Obtain the certificate of the entity in any appropriate way, such as by exporting it from the entity. The exact steps vary widely, depending on the entity.
From OC4J, use keytool
to import the certificate of the entity.
Note: During communications over SSL between Oracle HTTP Server and OC4J, all data on the communications channel between the two is encrypted. The following steps are executed: 1) The OC4J certificate chain is authenticated to Oracle HTTP Server during establishment of the encrypted channel. 2) Optionally, if OC4J is in client-authentication mode, Oracle HTTP Server is authenticated to OC4J. This process also occurs during establishment of the encrypted channel. 3) Any further communication after this initial exchange will be encrypted. |
Example: Creating an SSL Certificate and Generating Your Own Signature This example corresponds to Step 2 above, in the mode where you generate your own signature by using keytool
to self-sign the certificate.
First, create a keystore with an RSA private/public keypair, using the keytool
command. The following example (in which %
is the system prompt) uses the RSA keypair algorithm to generate a keystore to reside in a file named mykeystore
, which has a password of 123456
and is valid for 21 days:
% keytool -genkey -keyalg "RSA" -keystore mykeystore -storepass 123456 -validity 21
Note the following:
The keystore
option specifies the name of the file in which the keys are stored.
The storepass
option sets the password for protecting the keystore.
The validity
option sets the number of days for which the certificate is valid.
The keytool
prompts you for more information, as follows:
What is your first and last name? [Unknown]: Test User What is the name of your organizational unit? [Unknown]: Support What is the name of your organization? [Unknown]: Oracle What is the name of your City or Locality? [Unknown]: Redwood Shores What is the name of your State or Province? [Unknown]: CA What is the two-letter country code for this unit? [Unknown]: US Is <CN=Test User, OU=Support, O=Oracle, L=Reading, ST=Berkshire, C=GB> correct? [no]: yes Enter key password for <mykey> (RETURN if same as keystore password):
Note: To determine your two-letter country code, use the ISO country code list at the following URL:
|
The mykeystore
file is created in the current directory. The default alias of the key is mykey
.
OC4J supports a client authentication mode in which the server explicitly requests authentication from the client before the server communicates with the client. In an Oracle Application Server environment, Oracle HTTP Server acts as the client to OC4J.
For client authentication, Oracle HTTP Server must have its own certificate and authenticates itself by sending a certificate and a certificate chain that ends with a root certificate. You can configure OC4J to accept only root certificates from a specified list in establishing a chain of trust back to a client.
A certificate that OC4J trusts is called a trust point. In the certificate chain from Oracle HTTP Server, the trust point is the first certificate OC4J encounters that matches one in its own keystore. There are three ways to establish trust:
The client certificate is in the keystore.
One of the intermediate CA certificates in the certificate chain from Oracle HTTP Server is in the keystore.
The root CA certificate in the certificate chain from Oracle HTTP Server is in the keystore.
OC4J verifies that the entire certificate chain, up to and including the trust point, is valid to prevent any forged certificates.
If you request client authentication with the needs-client-auth
attribute, perform the following steps. See "OC4J Configuration Steps for SSL" for how to configure this attribute.
Decide which of the certificates in the chain from Oracle HTTP Server is to be your trust point. Ensure that you either have control over the issuance of certificates using this trust point or that you trust the certificate authority as an issuer.
Import the intermediate or root certificate in the server keystore as a trust point for authentication of the client certificate.
Note: If you do not want OC4J to accept certain trust points, make sure these trust points are not in the keystore. |
Execute the steps to create the client certificate (documented in "Using Certificates with OC4J and Oracle HTTP Server"). The client certificate includes the intermediate or root certificate that is installed in the server. If you wish to trust another certificate authority, obtain a certificate from that authority.
Save the certificate in a file on Oracle HTTP Server.
Provide the certificate for the Oracle HTTP Server initiation of the secure AJP connection.
For secure communication between Oracle HTTP Server and OC4J, configuration steps are required at each end, as the following sections discuss:
In Oracle HTTP Server, verify proper SSL settings in mod_oc4j.conf
for secure communication. SSL must be enabled, with a wallet file and password specified, as follows:
Oc4jEnableSSL on Oc4jSSLWalletFile wallet_path Oc4jSSLWalletPassword pwd
The wallet_path
value is a directory path to the wallet file, without a file name. (The wallet file name is already known.) The pwd
value is the wallet password.
For more information about the mod_oc4j.conf
file, see the Oracle HTTP Server Administrator's Guide.
In the default-web-site.xml
file (or other Web site XML file, as appropriate), you must specify appropriate SSL settings under the <web-site>
element.
Turn on the secure
flag to specify secure communication, as follows:
<web-site ... secure="true" ... > ... </web-site>
Setting secure="true"
specifies that the AJP protocol should use an SSL socket.
Use the <ssl-config>
subelement and its keystore
and keystore-password
attributes to specify the path and password for the keystore, as follows:
<web-site ... secure="true" ... > ... <ssl-config keystore="path_and_file" keystore-password="pwd" /> </web-site>
The <ssl-config>
element is required whenever the secure
flag is set to "true"
.
The path_and_file
value can indicate either an absolute or relative directory path and includes the file name. A relative path is relative to the location of the Web site XML file.
Optionally, to specify that client authentication is required, turn on the needs-client-auth
flag. This is an attribute of the <ssl-config>
element.
<web-site ... secure="true" ... > ... <ssl-config keystore="path_and_file" keystore-password="pwd" needs-client-auth="true" /> </web-site>
This step sets up a mode in which OC4J accepts or rejects a client entity, such as Oracle HTTP Server, for secure communication, depending on its identity. The needs-client-auth
flag instructs OC4J to request the client certificate chain upon connection. If OC4J recognizes the root certificate of the client, then the client is accepted.
The keystore that is specified in the <ssl-config>
element must contain the certificates of any clients that are authorized to connect to OC4J through secure AJP and SSL.
Here is an example that sets up secure communication with client authentication:
<web-site display-name="OC4J Web Site" protocol="ajp13" secure="true" > <default-web-app application="default" name="defaultWebApp" root="/j2ee" /> <access-log path="../log/default-web-access.log" /> <ssl-config keystore="../keystore" keystore-password="welcome" needs-client-auth="true" /> </web-site>
Only the portions in bold are specific to security. The protocol value is always "ajp13"
for communication through Oracle HTTP Server, whether or not you use secure communication. A protocol value of ajp13
with secure="false"
indicates AJP protocol; ajp13
with secure="true"
indicates secure AJP protocol.
For more information about elements and attributes of the <web-site>
and <ssl-config>
elements, see "Element Descriptions for Web Site XML Files".
Also see "Requesting Client Authentication" for related information.
This section discusses some common SSL errors and their causes and remedies, followed by a brief discussion of general SSL debugging.
The following errors may occur when using SSL certificates:
keytool
utility cannot locate the root CA certificates in your keystore, and therefore cannot build the certificate chain from your server key to the trusted root certificate authority.
keytool -keystore keystore -import -alias cacert -file cacert.cer (keytool -keystore keystore -import -alias intercert -file inter.cer)
If you use an intermediate CA keytool
utility, then execute this command:
keystore keystore -genkey -keyalg RSA -alias serverkey keytool -keystore keystore -certreq -file my.host.com.csr
Get the certificate from the Certificate Signing Request (CSR), then execute the following command:
keytool -keystore keystore -import -file my.host.com.cer -alias serverkey
While you are developing in OC4J standalone, you can display verbose debug information from the Java Secure Socket Extension (JSSE) implementation. To get a list of options, start OC4J as follows:
java -Djavax.net.debug=help -jar oc4j.jar
Start it as follows to enable full verbosity:
java -Djavax.net.debug=all -jar oc4j.jar
This will display the browser request header, server HTTP header, server HTTP body, content length (before and after encryption), and SSL version.
In addition to the SSL functionality discussed previously, the following are considerations for the security of your Web application running in the OC4J servlet container:
In the global-web-application.xml
file or orion-web.xml
file, use the <jazn-web-app>
subelement of <orion-web-app>
to configure the OracleAS JAAS Provider and Single Sign-On (SSO) properties for servlet execution. These features must be set appropriately in order to invoke a servlet under the privileges of a particular security subject. This element is described under "Element Descriptions for global-web-application.xml and orion-web.xml".
OC4J includes standard support for security constraints and security roles through the <security-role>
element of the web.xml
deployment descriptor. For general information, refer to the servlet specification. OC4J also offers related support through the global-web-application.xml
file <security-role-mapping>
element. See "Configuration for global-web-application.xml and orion-web.xml" for details about elements and attributes of global-web-application.xml
.
Invocation by class name should be considered only in a development environment, because there is a significant security risk when users are allowed to invoke servlets in this way.
Invocation by class name can bypass standard security constraints unless this is specifically addressed in the web.xml
file. In addition, when a servlet is invoked by class, any exception it throws may reveal the physical path of the servlet location, which is highly undesirable.
To resolve security issues, particularly in a production environment, you can disable servlet invocation by class name in either of two ways:
A system property http.webdir.enable
setting of false
. This setting results in any servlet-webdir
setting being ignored.
A servlet-webdir
value of ""
(empty quotes), either through global-web-application.xml
or orion-web.xml
.
(Invocation by class name is described in "Servlet Invocation by Class Name During OC4J Development", including additional information about servlet-webdir
settings.)
The following configuration in orion-web.xml
, for example, would disable invocation by class name:
<orion-web-app ... servlet-webdir="" ... > ... </orion-web-app>
To guard against the guessing or "hacking" of session ID numbers for destructive purposes, OC4J uses java.security.SecureRandom
functionality to generate random session ID numbers.
This section summarizes a few best practices to consider in your OC4J servlet coding and configuration.
We recommend the following general coding practices:
For flexibility, do not hardcode URLs for resource connections. See "Use of JDBC in Servlets" for information about data source configuration.
For efficiency, use servlet filters where appropriate. See "Servlet Filters".
Always use the contextual classloader for loading resources or classes. The following call returns the contextual classloader for the currently executing thread:
Thread.currentThread().getContextClassLoader();
We recommend the following practices for your HTTP sessions. See "Servlet Sessions" for related information.
Ensure that sessions are invalidated when the code is done with them.
Persist session state whenever that is appropriate and feasible, or replicate sessions if persistence is not feasible.
Do not store shared resources in a session.
Set an appropriate session timeout value.
Think about clustering and security early in your development process.
We recommend the following configuration practices in a production environment:
To improve performance, disable the check-for-updates
flag, which is intended for development. See "Key OC4J Flags for Development" for information about this flag.
Disable servlet invocation by class name, which poses a significant security risk and is intended only as a convenience during development. See "Servlet Invocation by Class Name During OC4J Development" for information.
Carefully consider whether you want to share your libraries at the server level, or have them be application-specific. Do not share them if there is no need. For server-level libraries, use a <library>
element in the OC4J server.xml
file or global application.xml
file. For an application-level library, use a <library>
element in the application orion-application.xml
file. See the Oracle Application Server Containers for J2EE User's Guide for information about these files.
Never use the system classpath for your libraries.