Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.server -> Re: Web Application Server / Java
In article <36CBC23D.F619BCDB_at_spin.ch>,
sjo_at_spin.ch wrote:
> Paul wrote: > > > > in the Java Cartridge parameter page of the administration > > web system, enter a new parameter: > > > > JavaCacheTimeout > > > > its value should them be set to > > > > 10 > > Where did you find the description of such parameters? I didn't > find anything in the WAS docs.
It's mentioned here and there in the documents at http://technet.oracle.com and/or at http://www.olab.com I highly recommend you visit these sites.
Below is a document detailing various Java cartridge tips for OAS3.
Using the Oracle Application Server Java Web cartridge
to develop Web Applications
NCA Center of Excellence
Oracle Corporation
8 January, 1998
Introduction
The Java Web cartridge in Oracle Application Server (OAS) provides many features for developing HTML based web applications using Java. The purpose of this paper is to highlight some of these features and provide examples on how they can be used to build web applications which access Oracle databases.
Configuring the Java Web Cartridge (OAS 3.0)
The default configuration of OAS 3.0 contains a Java Web cartridge which is used to execute demos which come with the server. It is better to create a new cartridge and then copy all the standard Java Web cartridge configuration parameters since using the same Java Web cartridge for all applications can create name clashes and security problems.
Configuring the virtual path
To allow web browsers to access your web application, you must specify a virtual path to your web application's startup class. The virtual path has a physical path which the Web Request Broker uses to find the startup class file for your web application. Also, a single virtual path could be used to invoke different web applications if the class files for these web applications reside in the same physical path.
For example, if the virtual path is defined as /yskjava and is mapped to the physical path /web/apps/classes and there are HelloWorld1.class and HelloWorld2.class in the physical path, you can access both applications using the virtual paths:
http://<hostname>/yskjava/HelloWorld1 and http://<hostname>/web/apps/classes/HelloWorld2.
NOTE: The virtual path should be specified in the "Web Request Broker parameters" section of the Java Cartridge configuration page, not in the listener directory mapping configuration page.
Configuring CLASSPATH and LD_LIBRARY_PATH
If the Java web application relies uses non-JDK standard classes such as JDBC classes, the CLASSPATH for the Java Web cartridge needs to be modified to point to the JDBC classes. Also, if the extra classes have associated native libraries associated, the LD_LIBRARY_PATH has to be changed to point to these libraries.
For example, if your application uses JDBC, and is located in the $ORACLE_HOME/javatest directory you should add the paths in bold to the CLASSPATH and LIBRARY_PATH as follows:
Sun Solaris: CLASSPATH =
%ORAWEB_HOME%/java/classes.zip:%ORAWEB_HOME%/java/oracle.zip:%ORAWEB_HOME%/ja
va /:%ORACLE_HOME%/jdbcoci73/lib/classes102.zip LD_LIBRARY_PATH =
%ORAWEB_HOME%/lib:%ORAWEB_HOME%/java/lib:%ORACLE_HOME%/jdbcoci73/lib
Windows NT: CLASSPATH =
%ORAWEB_HOME%\java\classes.zip:%ORAWEB_HOME%\java\oracle.zip:%ORAWEB_HOME%\ja
va :%ORACLE_HOME%\jdbc\lib\classes102.zip:%ORACLE_HOME%\javatest
LD_LIBRARY_PATH =
%ORAWEB_HOME%\lib:%ORAWEB_HOME%\java\lib:%ORACLE_HOME%\jdbc\lib
Configuring JavaCacheTimeout
Once a Java application has been loaded into the Java Web cartridge, the Java Web Cartridge will remain in memory and cache the Java application so that it can process the next request for the Java application without reloading the Java application again. This makes development and debugging cumbersome in OAS 3.0 because there is no way of shutting down a specific Java Web cartridge. Therefore, if there is a code change, you have to shut down the entire server to force the Java Web cartridge to reload the modified Java application classes.
One alternative is to change the JavaCacheTimeout to a low value during development to force the Java Web cartridge to expire the Java application classes from memory more quickly. If the JavaCacheTimeout is set to 10, the Java Web cartridge will expire the Java application from memory if it has not been accessed for more than 10 seconds. The JavaCacheTimeout setting is an undocumented feature which can be set in the same screen as the CLASSPATH and the LD_LIBRARY_PATH as follows:
CLASSPATH = %ORAWEB_HOME%/java/classes? LD_LIBRARY_PATH = %ORAWEB_HOME%/lib:%ORAWE? JAVA_HOME = %ORAWEB_HOME%/java SYSTEM_PROPERTY = ORACLE_HOME=/local/oracle/? SYSTEM_PROPERTY = ORAWEB_HOME=%ORAWEB_HOME%? JavaCacheTimeout = 10
Accessing HTTP request information
Accessing FORMS input parameters
The Java Web cartridge provides access to FORMS input parameters through classes which are included in the oracle.zip archive which is part of the standard CLASSPATH configuration. To use any of the Oracle packages defined in the archive, you must import the package into your Java source file. Also to access Java Web cartridge classes for accessing FORMS input parameters, you should import the following package:import oracle.owas.wrb.services.http.*;
To access the FORMS input parameters, you first have to get access to the HTTP request object and then use the getURLParameter method as follows:
HTTP request = HTTP.getRequest();
String parm_value = request.getURLParameter("form_param_name");
Alternatively, you can use overloaded methods to get the FORMS input values as a hash table or a vector pair as follows:
Hash table:
HTTP request = HTTP.getRequest();
HashTable table = new HashTable();
request.getURLParameters(table);
Vector pair:
HTTP request = HTTP.getRequest();
Vector forms_names = new Vector();
Vector forms_values = new Vector();
request.getURLParameters(forms_names, forms_values);
The nice thing about the HTTP request class is that it supports both the QUERY STRING method and the POST/PUT method of passing FORMS input parameters. Therefore the application does not have to use different methods depending on how the FORMS input parameters were passed to the cartridge. Also, this means that the same web application can support both QUERY STRING input parameters and POST/PUT input parameters simultaneously.
Accessing CGI environment variables
The HTTP request object also provides access to CGI environment variables which can be used to access miscellaneous information about the HTTP request such as web browser information. You can access CGI environment variables using a name or as a hash table as follows:
Using name lookup:
HTTP request = HTTP.getRequest();
String env_var_value = request.getCGIEnvironment("env_var_name");
Hash table:
HTTP request = HTTP.getRequest();
HashTable table = request.getCGIEnvironment();
Accessing Oracle Databases
There are two options for accessing Oracle databases from within the Java Web cartridge. One option is to add the JDBC classes and libraries to the CLASSPATH and LD_LIBRARY_PATH and use the JDBC driver directly, and the other option is to use the PL2JAVA toolkit.
Using JDBC within the Java Web cartridge
Since the Java Web cartridge contains a standard JDK1.0.2 compliant JVM, you can use various Oracle JDBC drivers such as the OCI7, OCI8 and thin driver in your application. However, because the Java Web cartridge resets instance variables and re-executes the main loop whenever the browser sends a HTTP request, database connection objects will get reinitialized with every request. This means that the Java application will logout and login to the database with every HTTP request which is very inefficient.
Maintaining persistent database connections
To get around this database connection problem, you can use static variables to store the database connection objects in your Java application. The Java Web cartridge will not reset static variables and will keep their values around as long as the Java application remains loaded inside the Java Web cartridge instance. However, since the static variable are stored inside the Java Web cartridge instance, a single database connection stored inside a static variable cannot be shared among different Java Web cartridge instances running in memory.
Here is an example of a simple Java application which re-uses the Oracle database connection using static class variables:
import java.sql.*;
import java.util.*;
class DbApp {
private static Connection connection = null; public static void main(String args[]) { if (connection ==
// establish database connection
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
connection = DriverManager.getConnection("jdbc:oracle:oci7:@", "scott", "tiger");
} catch (Exception e) {
e.printStackTrace();
return;
}
}
// else reuse existing
database connection
// use database
connection
System.out.println("Content-type: text/html\n\n");
try {
Statement sql = connection.createStatement();
ResultSet rset = sql.executeQuery("select ename from emp");
while (rset.next()) {
System.out.println("Ename: " + rset.getString(1));
}
rset.close();
sql.close();
} catch (SQLException
e) {
e.printStackTrace();
return;
} }
The important thing to note in this sample program is that the JDBC connection object is declared as a static variable and that it is initially set to null. When the Java Web Cartridge loads this application for the first time, connection will be set to null and the first IF clause will call the DriverManager to establish a connection to the database. However, when the application is executed again and if the request goes to the same Java Web cartridge instance, the IF clause will not establish a new connection to the database since the connection static variable will point to the JDBC connection object. The main body can then reuse the existing connection object to start another query.
Closing Statement objects and ResultSet objects
Although Java has automatic garbage collection, you should still close Statement objects and ResultSet objects explicitly within your Java applications. Even though the Statement objects and ResultSet objects go out of scope, the finalize method is not automatically called on these objects unless the JVM sees the
need for garbage collection. Therefore, if you do not close Statement objects and ResultSet objects explicitly and you reuse the database connection using static variables, you will soon run into the OPEN_CURSORS limit for a session and your SQL statements will not be executed.
Using the PL2JAVA toolkit
An alternative to using the JDBC classes directly is to use the OAS PL2JAVA toolkit to generate Java wrapper classes for PL/SQL packages stored in the database. You can then instantiate the wrapper classes within your application and execute its methods which will then execute the stored procedures in the database. The advantage of using the PL2JAVA utility is that it provides an easy way of accessing PL/SQL packages and data stored in an Oracle database.
PL2JAVA toolkit configuration and usage
To use the PL2JAVA toolkit, you must run the dbpkins.sql (dbpkins8.sql for Oracle8) which is under the $ORAWEB_HOME/java/sql directory. This script must be run as the SYS user and it will create PL/SQL packages which are used by the PL2JAVA toolkit. Once you have installed the package, you can run the utility as follows: $ $ORACLE_HOME/java/bin/pl2java <username>/<password>@<connect string> <PackageName>
This will then generate a class file called PackageName.class which should be placed in the same directory as the Java application. To use this class in your application, you should import the following packages: import oracle.rdbms.*; import.oracle.plsql.*;
Also, you have to create a Session object which will maintain the database connection context which will be passed to the wrapper class as follows:
// Get Oracle Home environment variable from cartridge setting Session.setProperty("ORACLE_HOME", System.getProperty("ORACLE_HOME"));
// Create a new database session and logon Session session = new Session(); session.logon(<username>, <password>, <connect string>);
// Instantiate wrapper classPackageName pkg = new PackageName(session);
Wrapper class argument passing
Once you have instantiated your wrapper class, you can call methods which map directly to the stored procedures defined in the database package. However, if the method has PL/SQL IN variables or OUT variables, you have to pass and receive arguments using the PL2JAVA toolkit classes such as PStringBuffer and PDouble. Here are some examples of calling methods with arguments:
Passing IN arguments:
PStringBuffer arg1 = new PStringBuffer(80);
arg1.setValue("argument1");pkg.method1(arg1);
Getting OUT arguments:
PDouble arg2 = new Pdouble(); pkg.method2(arg2); int
Getting PL/SQL table OUT arguments:
// Allocate buffer for OUT arguments PStringBuffer pEmpNameList[]; pEmpNameList = new PStringBuffer[80]; for (int i=0; i < 80;
// Execute function to
populate OUT parameters and get employee count
Pdouble pEmpCount; pEmpCount =
// Display employee
list
for (int i=0; i <
(int)pEmpCount.intValue(); i++) { System.out.println(pEmpNameList[i]); }
NOTE: When passing PL/SQL table OUT arguments from stored procedures, the starting index of the PL/SQL table should be 1. This table will then be mapped into a PStringBuffer array with a starting index of 0.
Maintaining persistent database connections with PL2JAVA toolkit
Since the database connection is maintained using the Session object, the database connection will be broken and established whenever the web application is accessed by a browser. To maintain persistent database connections, you can make the Session object a static class variable so that the connection is maintained across multiple HTTP requests as follows:
static Session session = null; if (session == null) {
// Get Oracle Home environment variable from cartridge setting
Session.setProperty("ORACLE_HOME", System.getProperty("ORACLE_HOME"));
// Create a new database session and logon
session = new Session(); session.logon(<username>, <password>, <connect string>); }
// Instantiate wrapper class
PackageName pkg = new PackageName(session);
Returning HTML output
The simple way of return HTML output to the browser from the Java Web cartridge is to write to the standard output stream in the Java application. Anything that is sent to the standard output stream is sent directly to the browser and interpreted by the browser based. Therefore, if you are using the standard output stream to return output, you should always set the MIME type
as the first thing you send as follows: System.out.println("Content-type: text/html\n\n");System.out.println("<HTML>Hello World</HTML>");
Using oracle.html classes
Instead of sending raw HTML output to the standard output stream, you can use the oracle.html package to construct a HTML page using Java classes and then send the whole page to the browser. The advantage of using the oracle.html classes is that you do not have to enter any HTML commands to display complex pages with tables, forms, select lists etc. Instead you instantiate oracle.html classes and then add them to the HTML page object. The advantage of using this approach is that it allows you to compose your HTML page using Java objects instead of returning HTML output a line at a time.
To use the oracle.html classes, you must import the following package:
import oracle.html.*;
You then create a HTML page object which contains all the HTML components that you want displayed in the browser and then add HTML components to the page as follows:
HtmlPage page = new HtmlPage(); page.addItem("This is
To add more complex HTML components such as tables, you construct the components piece by piece and then add them to the HTML page. Here is an example of adding an HTML table to the page:
// Create dynamic HTML table with 3 columns DynamicTable OutputTable = new DynamicTable(3); for (int i=0; i <
// Create a new table row and elements to row
TableRow row = new TableRow();
row.addCell(new TableDataCell(new SimpleItem(pEmpNameList.elementAt(i))));
row.addCell(new TableDataCell(new SimpleItem(pSalList.elementAt(i)));
row.addCell(new TableDataCell(new SimpleItem(pJobList.elementAt(i))));
// Add row to table
OutputTable.addRow(row); }
// Add table to HTML page
Page.addItem(OutputTable);
Once you have constructed the HTML page, you return the HTML output to the browser as follows:
Page.printHeader(); Page.print();
Extending oracle.html classes
The oracle.html classes are organized in a hierarchy with most of the HTML classes inheriting from the Item class. You can extend the hierarchy to support new HTML items or to construct application specific HTML widgets in your Java application. The recommended way of extending the oracle.html classes is to extend the CompoundItem class which acts as a container for Item objects (ie. oracle.html classes which inherit from Item).
Here is an example which extends the CompoundItem to create a new class which displays a one column table given a vector:
import java.util.*; import oracle.html.*; class OneColumnTable extends CompoundItem { public
// create dynamic table
DynamicTable table = new DynamicTable(1);
// add rows to table
for (int i=0; i < data.size(); i++) {
TableRow row = new TableRow();
row.addCell(new TableDataCell((String)data.elementAt(i))); table.addRow(row);
}
// add table to compound item
addItem(table); } } Here is a sample program which illustrates how this new HTML class can be used: import java.util.*; import oracle.html.*; class JavaTest {
public static void main(String args[]) {
// create html page object
HtmlPage page = new HtmlPage();
// create sample data
Vector data = new Vector();
data.addElement("row1");
data.addElement("row2");
data.addElement("row3");
// Create custom HTML class and add to page using addItem since
// OneColumnTable inherits from CompoundItem
OneColumnTable oc = new OneColumnTable(data);
page.addItem(oc);
page.printHeader();
page.print();
}
}
Debugging Java Web cartridge applications
Unfortunately, the Java Web cartridge provides limited debugging facilities for debugging Java applications. Also, it is very difficult to debug Java Web cartridge applications using standard Java debugging tools because they rely on Java Web cartridge classes which only work under the Oracle Application Server environment.
Therefore, the key to debugging Java Web cartridge applications is to rely on writing messages to a file to record the progress of the Java application. It is not a good idea to use the standard output stream or the
Oracle HTML classes to send debugging output because they will not get displayed unless the Java cartridge has finished executing without crashing. Also, it is useful to put a "try catch" block around the main loop of the Java application to catch any unhandled exception as follows:
public static void main(String args[]) {
try { ? program code ? } catch (Exception e) {
System.out.println("Content-type: text/html\n\n");
System.out.println("Unhandled exception: " + e);
e.printStackTrace();
}
}
This will catch all unhandled exception and display an HTML page to the browser with details on the unhandled exception which will provide clues as to what went wrong in the application.
Summary
This paper has outlined some of the features of the Java Web cartridge which are useful for developers developing applications which access Oracle databases. The Java Web cartridge comes with a rich set of features which are not all covered in this paper. Therefore, please consult the list of documents mentioned in the Reference section for more detailed information on using the Java Web cartridge.
References
1.Oracle Application Server Online documentation: "Using the Java Cartridge" 2.Oracle Application Server Online documentation: "Java toolkit reference" 3."Using Session Enabled Cartridges to maintain state across multiple HTTPrequests"
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own Received on Thu Feb 18 1999 - 22:07:58 CST
![]() |
![]() |