This chapter describes how to use the JavaTM Database Connectivity (JDBCTM) API for database access with the Oracle GlassFishTM Server. This chapter also provides high level JDBC implementation instructions for servlets and EJB components using the GlassFish Server. If the JDK version 1.6 is used, the GlassFish Server supports the JDBC 4.0 API.
The JDBC specifications are available at http://java.sun.com/products/jdbc/download.html.
A useful JDBC tutorial is located at http://java.sun.com/docs/books/tutorial/jdbc/index.html.
The GlassFish Server does not support connection pooling or transactions for an application’s database access if it does not use standard Java EE DataSource objects.
This chapter discusses the following topics:
To prepare a JDBC resource for use in Java EE applications deployed to the GlassFish Server, perform the following tasks:
For information about how to configure some specific JDBC drivers, see Configuration Specifics for JDBC Drivers in Oracle GlassFish Server 3.0.1 Administration Guide.
To use JDBC features, you must choose a JDBC driver to work with the GlassFish Server, then you must set up the driver. This section covers these topics:
Supported JDBC drivers are those that have been fully tested by Oracle. For a list of the JDBC drivers currently supported by the GlassFish Server, see the Oracle GlassFish Server 3.0.1 Release Notes. For configurations of supported and other drivers, see Configuration Specifics for JDBC Drivers in Oracle GlassFish Server 3.0.1 Administration Guide.
Because the drivers and databases supported by the GlassFish Server are constantly being updated, and because database vendors continue to upgrade their products, always check with Oracle technical support for the latest database support information.
To integrate the JDBC driver into a GlassFish Server domain, copy the JAR files into the domain-dir/lib directory, then restart the server. This makes classes accessible to all applications or modules deployed on servers that share the same configuration. For more information about GlassFish Server class loaders, see Chapter 2, Class Loaders.
If you are using an Oracle database with EclipseLink extensions, copy the JAR files into the domain-dir/lib/ext directory, then restart the server. For details, see Oracle Database Enhancements.
The Administration Console detects installed JDBC Drivers automatically when you create a JDBC connection pool. To create a JDBC connection pool using the Administration Console, open the Resources component, open the JDBC component, select Connection Pools, and click on the New button. This displays the New JDBC Connection Pool page.
Based on the Resource Type and Database Vendor you select on the New JDBC Connection Pool page, data source or driver implementation class names are listed in the Datasource Classname or Driver Classname field when you click on the Next button. When you choose a specific implementation class name on the next page, additional properties relevant to the installed JDBC driver are displayed in the Additional Properties section.
When you create a connection pool that uses JDBC technology (a JDBC connection pool) in the GlassFish Server, you can define many of the characteristics of your database connections.
You can create a JDBC connection pool in one of these ways:
In the Administration Console, open the Resources component, open the JDBC component, select Connection Pools, and click on the New button. This displays the New JDBC Connection Pool page. For details, click the Help button in the Administration Console.
Use the asadmin create-jdbc-connection-pool command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
For a complete description of JDBC connection pool features, see the Oracle GlassFish Server 3.0.1 Administration Guide.
In the Administration Console, some JDBC connection pool attributes are advanced, and you cannot set them during JDBC connection pool creation. You can only set them when modifying an existing JDBC connection pool. You can also use the asadmin set command to set or reset a JDBC connection pool's attributes.
You can modify a JDBC connection pool in one of these ways:
In the Administration Console, open the Resources component, open the JDBC component, select Connection Pools, and click on the name of the connection pool you want to modify. This displays the Edit Connection Pool page. To edit advanced attributes, click on the Advanced tab. This displays the Edit Connection Pool Advanced Attributes page. For details, click the Help button in the Administration Console.
Use the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.pooling=false |
For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
You can test a JDBC connection pool for usability in one of these ways:
In the Administration Console, open the Resources component, open the JDBC component, select Connection Pools, and select the connection pool you want to test. Then select the Ping button in the top left corner of the page. For details, click the Help button in the Administration Console.
Use the asadmin ping-connection-pool command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Both these commands fail and display an error message unless they successfully connect to the connection pool.
You can also specify that a connection pool is automatically tested when created or reconfigured by setting the Ping attribute to true (the default is false) in one of the following ways:
Enter a Ping value in the New JDBC Connection Pool or Edit Connection Pool page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----ping option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the ping option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.ping=true |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Flushing a JDBC connection pool recreates all the connections in the pool and brings the pool to the steady pool size without the need for reconfiguring the pool. Connection pool reconfiguration can result in application redeployment, which is a time-consuming operation. Flushing destroys existing connections, and any existing transactions are lost and must be retired.
You can flush a JDBC connection pool in one of these ways:
In the Administration Console, open the Resources component, open the JDBC component, select Connection Pools, and select the connection pool you want to flush. Then select the Flush button in the top left corner of the page. For details, click the Help button in the Administration Console.
Use the asadmin flush-connection-pool command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
A JDBC resource, also called a data source, lets you make connections to a database using getConnection. Create a JDBC resource in one of these ways:
In the Administration Console, open the Resources component, open the JDBC component, and select JDBC Resources. For details, click the Help button in the Administration Console.
Use the asadmin create-jdbc-resource command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
An application that uses the JDBC API is an application that looks up and connects to one or more databases. This section covers these topics:
The following features pertain to statements:
You can specify a statement that executes each time a physical connection to the database is created (not reused) from a JDBC connection pool. This is useful for setting request or session specific properties and is suited for homogeneous requests in a single application. Set the Init SQL attribute of the JDBC connection pool to the SQL string to be executed in one of the following ways:
Enter an Init SQL value in the Edit Connection Pool Advanced Attributes page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----initsql option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the init-sql option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.init-sql="sql-string" |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
An abnormally long running JDBC query executed by an application may leave it in a hanging state unless a timeout is explicitly set on the statement. Setting a statement timeout guarantees that all queries automatically time out if not completed within the specified period. When statements are created, the queryTimeout is set according to the statement timeout setting. This works only when the underlying JDBC driver supports queryTimeout for Statement, PreparedStatement, CallableStatement, and ResultSet.
You can specify a statement timeout in the following ways:
Enter a Statement Timeout value in the Edit Connection Pool Advanced Attributes page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----statementtimeout option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Statement caching stores statements, prepared statements, and callable statements that are executed repeatedly by applications in a cache, thereby improving performance. Instead of the statement being prepared each time, the cache is searched for a match. The overhead of parsing and creating new statements each time is eliminated.
Statement caching is usually a feature of the JDBC driver. The GlassFish Server provides caching for drivers that do not support caching. To enable this feature, set the Statement Cache Size for the JDBC connection pool in one of the following ways:
Enter a Statement Cache Size value in the Edit Connection Pool Advanced Attributes page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----statementcachesize option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the statement-cache-size option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.statement-cache-size=10 |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
By default, this attribute is set to zero and the statement caching is turned off. To enable statement caching, you can set any positive nonzero value. The built-in cache eviction strategy is LRU-based (Least Recently Used). When a connection pool is flushed, the connections in the statement cache are recreated.
You can trace the SQL statements executed by applications that use a JDBC connection pool. Set the SQL Trace Listeners attribute to a comma-separated list of trace listener implementation classes in one of the following ways:
Enter an SQL Trace Listeners value in the Edit Connection Pool Advanced Attributes page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----sqltracelisteners option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the sql-trace-listeners option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.sql-trace-listeners=listeners |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
The GlassFish Server provides a public interface, org.glassfish.api.jdbc.SQLTraceListener, that implements a means of recording SQLTraceRecord objects. To make custom implementations of this interface available to the GlassFish Server, place the implementation classes in as-install/lib.
The GlassFish Server provides an SQL tracing logger to log the SQL operations in the form of SQLTraceRecord objects in the server.log file. The module name under which the SQL operation is logged is javax.enterprise.resource.sqltrace. SQL traces are logged as FINE messages along with the module name to enable easy filtering of the SQL logs. A sample SQL trace record looks like this:
[#|2009-11-27T15:46:52.202+0530|FINE|glassfishv3.0|javax.enterprise.resource.sqltrace.com.sun.gjc.util |_ThreadID=29;_ThreadName=Thread-1;ClassName=com.sun.gjc.util.SQLTraceLogger;MethodName=sqlTrace; |ThreadID=77 | ThreadName=p: thread-pool-1; w: 6 | TimeStamp=1259317012202 | ClassName=com.sun.gjc.spi.jdbc40.PreparedStatementWrapper40 | MethodName=executeUpdate | arg[0]=insert into table1(colName) values(100) | arg[1]=columnNames | |#] |
This trace shows that an executeUpdate(String sql, String columnNames) operation is being done.
The following features pertain to connections:
To disable connection pooling, set the Pooling attribute to false. The default is true. You can enable or disable connection pooling in one of the following ways:
Enter a Pooling value in the Edit Connection Pool Advanced Attributes page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----pooling option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the pooling option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.pooling=false |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
The pooling option and the system property com.sun.enterprise.connectors.SwitchoffACCConnectionPooling, which turns off connection pooling in the Application Client Container, do not affect each other.
An exception is thrown if associate-with-thread is set to true and pooling is disabled. An exception is thrown if you attempt to flush a connection pool when pooling is disabled. A warning is logged if the following attributes are used, because they are useful only in a pooled environment:
connection-validation
validate-atmost-once-period
match-connections
max-connection-usage
idle-timeout
To associate connections with a thread, set the Associate With Thread attribute to true. The default is false. A true setting allows connections to be saved as ThreadLocal in the calling thread. Connections get reclaimed only when the calling thread dies or when the calling thread is not in use and the pool has run out of connections. If the setting is false, the thread must obtain a connection from the pool each time the thread requires a connection.
The Associate With Thread attribute associates connections with a thread such that when the same thread is in need of connections, it can reuse the connections already associated with that thread. In this case, the overhead of getting connections from the pool is avoided. However, when this value is set to true, you should verify that the value of the Max Pool Size attribute is comparable to the Max Thread Pool Size attribute of the thread pool. If the Max Thread Pool Size value is much higher than the Max Pool Size value, a lot of time is spent associating connections with a new thread after dissociating them from an older one. Use this attribute in cases where the thread pool should reuse connections to avoid this overhead.
You can set the Associate With Thread attribute in the following ways:
Enter an Associate With Thread value in the Edit Connection Pool Advanced Attributes page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----associatewiththread option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the associate-with-thread option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.associate-with-thread=true |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
You can specify a custom implementation for Connection Validation that is faster or optimized for a specific database. Set the Validation Method attribute to the value custom-validation. (Other validation methods available are table (the default), auto-commit, and meta-data.) The GlassFish Server provides a public interface, org.glassfish.api.jdbc.ConnectionValidation, which you can implement to plug in your implementation. A new attribute, Validation Classname, specifies the fully qualified name of the class that implements the ConnectionValidation interface. The Validation Classname attribute is required if Connection Validation is enabled and Validation Method is set to Custom Validation.
To enable this feature, set Connection Validation, Validation Method, and Validation Classname for the JDBC connection pool in one of the following ways:
Enter Connection Validation, Validation Method, and Validation Classname values in the Edit Connection Pool Advanced Attributes page in the Administration Console. You can select from among validation class names for common databases in the Validation Classname field. For more information, click the Help button in the Administration Console.
Specify the ----isconnectionvalidatereq, ----validationmethod, and ----validationclassname options in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the is-connection-validation-required, connection-validation-method, and validation-classname options in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.MyPool.is-connection-validation-required=true asadmin set domain1.resources.jdbc-connection-pool.MyPool.connection-validation-method=custom-validation asadmin set domain1.resources.jdbc-connection-pool.MyPool.validation-classname=impl-class |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
By default, optimized validation mechanisms are provided for Java DB, MySQL, Oracle, and PostgreSQL databases. Additionally, for JDBC 4.0 compliant database drivers, a validation mechanism is provided that uses the Connection.isValid(0) implementation.
When multiple connections acquired by an application use the same JDBC resource, the connection pool provides connection sharing within the same transaction scope. For example, suppose Bean A starts a transaction and obtains a connection, then calls a method in Bean B. If Bean B acquires a connection to the same JDBC resource with the same sign-on information, and if Bean A completes the transaction, the connection can be shared.
Connections obtained through a resource are shared only if the resource reference declared by the Java EE component allows it to be shareable. This is specified in a component’s deployment descriptor by setting the res-sharing-scope element to Shareable for the particular resource reference. To turn off connection sharing, set res-sharing-scope to Unshareable.
For general information about connections and JDBC URLs, see Chapter 14, Administering Database Connectivity , in Oracle GlassFish Server 3.0.1 Administration Guide.
The DataSource implementation in the GlassFish Server provides a markConnectionAsBad method. A marked bad connection is removed from its connection pool when it is closed. The method signature is as follows:
public void markConnectionAsBad(java.sql.Connection con)
For example:
com.sun.appserv.jdbc.DataSource ds= (com.sun.appserv.jdbc.DataSource)context.lookup("dataSource"); Connection con = ds.getConnection(); Statement stmt = null; try{ stmt = con.createStatement(); stmt.executeUpdate("Update"); } catch (BadConnectionException e){ ds.markConnectionAsBad(con) //marking it as bad for removal } finally{ stmt.close(); con.close(); //Connection will be destroyed during close. }
If a ConnectionErrorOccured event occurs, the GlassFish Server considers the connection invalid and removes the connection from the connection pool. Typically, a JDBC driver generates a ConnectionErrorOccured event when it finds a ManagedConnection object unusable. Reasons can be database failure, network failure with the database, fatal problems with the connection pool, and so on.
If the fail-all-connections setting in the connection pool configuration is set to true, and a single connection fails, all connections are closed and recreated. If this setting is false, individual connections are recreated only when they are used. The default is false.
The is-connection-validation-required setting specifies whether connections have to be validated before being given to the application. If a resource’s validation fails, it is destroyed, and a new resource is created and returned. The default is false.
The prefer-validate-over-recreate property specifies that validating idle connections is preferable to closing them. This property has no effect on non-idle connections. If set to true, idle connections are validated during pool resizing, and only those found to be invalid are destroyed and recreated. If false, all idle connections are destroyed and recreated during pool resizing. The default is false.
You can set the fail-all-connections, is-connection-validation-required, and prefer-validate-over-recreate configuration settings during creation of a JDBC connection pool. Or, you can use the asadmin set command to dynamically reconfigure a setting. For example:
asadmin set server.resources.jdbc-connection-pool.JCPool1.fail-all-connections="true" asadmin set server.resources.jdbc-connection-pool.JCPool1.is-connection-validation-required="true" asadmin set server.resources.jdbc-connection-pool.JCPool1.property.prefer-validate-over-recreate="true" |
For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
The interface ValidatingManagedConnectionFactory exposes the method getInvalidConnections to allow retrieval of the invalid connections. The GlassFish Server checks if the JDBC driver implements this interface, and if it does, invalid connections are removed when the connection pool is resized.
The following features pertain to connection wrapping:
If the Wrap JDBC Objects option is true (the default), wrapped JDBC objects are returned for Statement, PreparedStatement, CallableStatement, ResultSet, and DatabaseMetaData.
This option ensures that Statement.getConnection() is the same as DataSource.getConnection(). Therefore, this option should be true when both Statement.getConnection() and DataSource.getConnection() are done.
You can specify the Wrap JDBC Objects option in the following ways:
Check or uncheck the Wrap JDBC Objects box on the Edit Connection Pool Advanced Attributes page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----wrapjdbcobjects option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
The DataSource implementation in the GlassFish Server provides a getConnection method that retrieves the JDBC driver’s SQLConnection from the GlassFish Server’s Connection wrapper. The method signature is as follows:
public java.sql.Connection getConnection(java.sql.Connection con) throws java.sql.SQLException
For example:
InitialContext ctx = new InitialContext(); com.sun.appserv.jdbc.DataSource ds = (com.sun.appserv.jdbc.DataSource) ctx.lookup("jdbc/MyBase"); Connection con = ds.getConnection(); Connection drivercon = ds.getConnection(con); //get physical connection from wrapper // Do db operations. // Do not close driver connection. con.close(); // return wrapped connection to pool.
If the JDK version 1.6 is used, the GlassFish Server supports JDBC 4.0 if the JDBC driver is JDBC 4.0 compliant. Using the Connection.unwrap() method on a vendor-provided interface returns an object or a wrapper object implementing the vendor-provided interface, which the application can make use of to do vendor-specific database operations. Use the Connection.isWrapperFor() method on a vendor-provided interface to check whether the connection can provide an implementation of the vendor-provided interface. Check the JDBC driver vendor's documentation for information on these interfaces.
The following features pertain to transactions:
You can specify a non-transactional database connection in any of these ways:
Check the Non-Transactional Connections box on the New JDBC Connection Pool or Edit Connection Pool page in the Administration Console. The default is unchecked. For more information, click the Help button in the Administration Console.
Specify the ----nontransactionalconnections option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the non-transactional-connections option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.non-transactional-connections=true |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Use the DataSource implementation in the GlassFish Server, which provides a getNonTxConnection method. This method retrieves a JDBC connection that is not in the scope of any transaction. There are two variants.
public java.sql.Connection getNonTxConnection() throws java.sql.SQLException
public java.sql.Connection getNonTxConnection(String user, String password) throws java.sql.SQLException
Create a resource with the JNDI name ending in __nontx. This forces all connections looked up using this resource to be non transactional.
Typically, a connection is enlisted in the context of the transaction in which a getConnection call is invoked. However, a non-transactional connection is not enlisted in a transaction context even if a transaction is in progress.
The main advantage of using non-transactional connections is that the overhead incurred in enlisting and delisting connections in transaction contexts is avoided. However, use such connections carefully. For example, if a non-transactional connection is used to query the database while a transaction is in progress that modifies the database, the query retrieves the unmodified data in the database. This is because the in-progress transaction hasn’t committed. For another example, if a non-transactional connection modifies the database and a transaction that is running simultaneously rolls back, the changes made by the non-transactional connection are not rolled back.
Here is a typical use case for a non-transactional connection: a component that is updating a database in a transaction context spanning over several iterations of a loop can refresh cached data by using a non-transactional connection to read data before the transaction commits.
For general information about transactions, see Chapter 15, Using the Transaction Service and Chapter 21, Administering Transactions, in Oracle GlassFish Server 3.0.1 Administration Guide. For information about last agent optimization, which can improve performance, see Transaction Scope.
Not all database vendors support all transaction isolation levels available in the JDBC API. The GlassFish Server permits specifying any isolation level your database supports. The following table defines transaction isolation levels.
Table 14–1 Transaction Isolation Levels
Transaction Isolation Level |
Description |
---|---|
read-uncommitted |
Dirty reads, non-repeatable reads, and phantom reads can occur. |
read-committed |
Dirty reads are prevented; non-repeatable reads and phantom reads can occur. |
repeatable-read |
Dirty reads and non-repeatable reads are prevented; phantom reads can occur. |
serializable |
Dirty reads, non-repeatable reads and phantom reads are prevented. |
You can specify the transaction isolation level in the following ways:
Select the value from the Transaction Isolation drop-down list on the New JDBC Connection Pool or Edit Connection Pool page in the Administration Console. For more information, click the Help button in the Administration Console.
Specify the ----isolationlevel option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the transaction-isolation-level option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.transaction-isolation-level=serializable |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Note that you cannot call setTransactionIsolation during a transaction.
You can set the default transaction isolation level for a JDBC connection pool. For details, see Creating a JDBC Connection Pool.
To verify that a level is supported by your database management system, test your database programmatically using the supportsTransactionIsolationLevel method in java.sql.DatabaseMetaData, as shown in the following example:
InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("jdbc/MyBase"); Connection con = ds.getConnection(); DatabaseMetaData dbmd = con.getMetaData(); if (dbmd.supportsTransactionIsolationLevel(TRANSACTION_SERIALIZABLE) { Connection.setTransactionIsolation(TRANSACTION_SERIALIZABLE); }
For more information about these isolation levels and what they mean, see the JDBC API specification.
Applications that change the isolation level on a pooled connection programmatically risk polluting the pool, which can lead to errors.
The following additional features related to JDBC are provided:
You can allow non-Java-EE components, such as servlet filters, lifecycle modules, and third party persistence managers, to use this JDBC connection pool. The returned connection is automatically enlisted with the transaction context obtained from the transaction manager. Standard Java EE components can also use such pools. Connections obtained by non-component callers are not automatically closed at the end of a transaction by the container. They must be explicitly closed by the caller.
You can enable non-component callers in the following ways:
Check the Allow Non Component Callers box on the Edit Connection Pool Advanced Attributes page in the Administration Console. The default is false. For more information, click the Help button in the Administration Console.
Specify the ----allownoncomponentcallers option in the asadmin create-jdbc-connection-pool command. For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Specify the allow-non-component-callers option in the asadmin set command. For example:
asadmin set domain1.resources.jdbc-connection-pool.DerbyPool.allow-non-component-callers=true |
For more information, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Create a JDBC resource with a __pm suffix.
Accessing a DataSource using the Synchronization.beforeCompletion() method requires setting Allow Non Component Callers to true. For more information about the Transaction Synchronization Registry, see The Transaction Manager, the Transaction Synchronization Registry, and UserTransaction.
This section discusses restrictions and performance optimizations that affect using the JDBC API.
By default, DataDirect and Oracle JDBC drivers for Sybase databases create a stored procedure for each parameterized PreparedStatement. On the GlassFish Server, exceptions are thrown when primary key identity generation is attempted. To disable the creation of these stored procedures, set the property PrepareMethod=direct for the JDBC connection pool.
The Java EE platform provides several abstractions that simplify development of dependable transaction processing for applications. This chapter discusses Java EE transactions and transaction support in the Oracle GlassFishTM Server.
This chapter contains the following sections:
For more information about the JavaTM Transaction API (JTA) and Java Transaction Service (JTS), see Chapter 21, Administering Transactions, in Oracle GlassFish Server 3.0.1 Administration Guide and the following sites: http://java.sun.com/javaee/technologies/jta/index.jsp and http://java.sun.com/javaee/technologies/jts/index.jsp.
You might also want to read Chapter 34, Transactions, in The Java EE 6 Tutorial.
There are three types of transaction resource managers:
Databases - Use of transactions prevents databases from being left in inconsistent states due to incomplete updates. For information about JDBC transaction isolation levels, see Using JDBC Transaction Isolation Levels.
The GlassFish Server supports a variety of JDBC XA drivers. For a list of the JDBC drivers currently supported by the GlassFish Server, see the Oracle GlassFish Server 3.0.1 Release Notes. For configurations of supported and other drivers, see Configuration Specifics for JDBC Drivers in Oracle GlassFish Server 3.0.1 Administration Guide.
Java Message Service (JMS) Providers - Use of transactions ensures that messages are reliably delivered. The GlassFish Server is integrated with GlassFish Message Queue, a fully capable JMS provider. For more information about transactions and the JMS API, see Chapter 17, Using the Java Message Service.
J2EE Connector Architecture (CA) components - Use of transactions prevents legacy EIS systems from being left in inconsistent states due to incomplete updates. For more information about connectors, see Chapter 12, Developing Connectors.
For details about how transaction resource managers, the transaction service, and applications interact, see Chapter 21, Administering Transactions, in Oracle GlassFish Server 3.0.1 Administration Guide.
A local transaction involves only one non-XA resource and requires that all participating application components execute within one process. Local transaction optimization is specific to the resource manager and is transparent to the Java EE application.
In the GlassFish Server, a JDBC resource is non-XA if it meets either of the following criteria:
In the JDBC connection pool configuration, the DataSource class does not implement the javax.sql.XADataSource interface.
The Resource Type setting is not set to javax.sql.XADataSource.
A transaction remains local if the following conditions remain true:
One and only one non-XA resource is used. If any additional non-XA resource is used, the transaction is aborted.
No transaction importing or exporting occurs.
Transactions that involve multiple resources or multiple participant processes are distributed or global transactions. A global transaction can involve one non-XA resource if last agent optimization is enabled. Otherwise, all resourced must be XA. The use-last-agent-optimization property is set to true by default. For details about how to set this property, see Configuring the Transaction Service.
If only one XA resource is used in a transaction, one-phase commit occurs, otherwise the transaction is coordinated with a two-phase commit protocol.
A two-phase commit protocol between the transaction manager and all the resources enlisted for a transaction ensures that either all the resource managers commit the transaction or they all abort. When the application requests the commitment of a transaction, the transaction manager issues a PREPARE_TO_COMMIT request to all the resource managers involved. Each of these resources can in turn send a reply indicating whether it is ready for commit (PREPARED) or not (NO). Only when all the resource managers are ready for a commit does the transaction manager issue a commit request (COMMIT) to all the resource managers. Otherwise, the transaction manager issues a rollback request (ABORT) and the transaction is rolled back.
You can configure the transaction service in the GlassFish Server in the following ways:
To configure the transaction service using the Administration Console, open the Transaction Service component under the relevant configuration. For details, click the Help button in the Administration Console.
To configure the transaction service, use the asadmin set command to set the following attributes.
server-config.transaction-service.automatic-recovery = false server-config.transaction-service.heuristic-decision = rollback server-config.transaction-service.keypoint-interval = 2048 server-config.transaction-service.retry-timeout-in-seconds = 600 server-config.transaction-service.timeout-in-seconds = 0 server-config.transaction-service.tx-log-dir = domain-dir/logs
You can also set these properties:
server-config.transaction-service.property.oracle-xa-recovery-workaround = false server-config.transaction-service.property.disable-distributed-transaction-logging = false server-config.transaction-service.property.xaresource-txn-timeout = 600 server-config.transaction-service.property.pending-txn-cleanup-interval = 60 server-config.transaction-service.property.use-last-agent-optimization = true server-config.transaction-service.property.db-logging-resource = jdbc/TxnDS server-config.transaction-service.property.xa-servername = myserver
You can use the asadmin get command to list all the transaction service attributes and properties. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Changing keypoint-interval, retry-timeout-in-seconds, or timeout-in-seconds does not require a server restart. Changing other attributes or properties requires a server restart.
To access a UserTransaction instance, you can either look it up using the java:comp/UserTransaction JNDI name or inject it using the @Resource annotation.
If you need to access the javax.transaction.TransactionManager implementation, you can look up the GlassFish Server implementation of this interface using the JNDI name java:appserver/TransactionManager. If possible, you should use the javax.transaction.TransactionSynchronizationRegistry interface instead, for portability. You can look up the implementation of this interface by using the JNDI name java:comp/TransactionSynchronizationRegistry. For details, see the Javadoc page for Interface TransactionSynchronizationRegistry and Java Specification Request (JSR) 907.
Accessing a DataSource using the Synchronization.beforeCompletion() method requires setting Allow Non Component Callers to true. The default is false. For more information about non-component callers, see Allowing Non-Component Callers.
The transaction service writes transactional activity into transaction logs so that transactions can be recovered. You can control transaction logging in these ways:
Set the location of the transaction log files using the Transaction Log Location setting in the Administration Console, or set the tx-log-dir attribute using the asadmin set command.
Turn off transaction logging by setting the disable-distributed-transaction-logging property to true and the automatic-recovery attribute to false. Do this only if performance is more important than transaction recovery.
For multi-core machines, logging transactions to a database may be more efficient.
To log transactions to a database, follow these steps:
Create a JDBC connection Pool, and set the non-transactional-connections attribute to true.
Create a JDBC resource that uses the connection pool and note the JNDI name of the JDBC resource.
Create a table named txn_log_table with the schema shown in Table 15–1.
Add the db-logging-resource property to the transaction service. For example:
asadmin set server-config.transaction-service.property.db-logging-resource="jdbc/TxnDS" |
The property's value should be the JNDI name of the JDBC resource configured previously.
To disable file synchronization, use the following asadmin create-jvm-options command:
asadmin create-jvm-options -Dcom.sun.appserv.transaction.nofdsync |
Restart the server.
For information about JDBC connection pools and resources, see Chapter 14, Using the JDBC API for Database Access. For more information about the asadmin create-jvm-options command, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Table 15–1 Schema for txn_log_table
Column Name |
JDBC Type |
---|---|
LOCALTID |
BIGINT |
SERVERNAME |
VARCHAR(n) |
GTRID |
VARBINARY |
The size of the SERVERNAME column should be at least the length of the GlassFish Server host name plus 10 characters.
The size of the GTRID column should be at least 64 bytes.
To define the SQL used by the transaction manager when it is storing its transaction logs in the database, use the following flags:
-Dcom.sun.jts.dblogging.insertquery=sql statement -Dcom.sun.jts.dblogging.deletequery=sql statement
The default statements are as follows:
-Dcom.sun.jts.dblogging.insertquery=insert into txn_log_table values ( ?, ? , ? ) -Dcom.sun.jts.dblogging.deletequery=delete from txn_log_table where localtid = ? and servername = ?
To set one of these flags using the asadmin create-jvm-options command, you must quote the statement. For example:
create-jvm-options '-Dcom.sun.jts.dblogging.deletequery=delete from txn_log_table where gtrid = ?'
You can also set JVM options in the Administration Console. Select the Application Server component and the JVM Settings tab. These flags and their statements must also be quoted in the Administration Console. For example:
'-Dcom.sun.jts.dblogging.deletequery=delete from txn_log_table where gtrid = ?'
The GlassFish Server provides workarounds for some known issues with transaction recovery implementations.
These workarounds do not imply support for any particular JDBC driver.
In the Oracle thin driver, the XAResource.recover method repeatedly returns the same set of in-doubt Xids regardless of the input flag. According to the XA specifications, the Transaction Manager initially calls this method with TMSTARTSCAN and then with TMNOFLAGS repeatedly until no Xids are returned. The XAResource.commit method also has some issues.
To disable the GlassFish Server workaround, set the oracle-xa-recovery-workaround property value to false. For details about how to set this property, see Configuring the Transaction Service. This workaround is used unless explicitly disabled.
Manual transaction recovery cannot recover transactions after a server crash. Manual operations are intended for cases when a resource dies unexpectedly while the server is running. In case of a server crash, only start-up recovery can recover in-doubt transactions.
A naming service maintains a set of bindings, which relate names to objects. The Java EE naming service is based on the Java Naming and Directory InterfaceTM (JNDI) API. The JNDI API allows application components and clients to look up distributed resources, services, and EJB components. For general information about the JNDI API, see http://java.sun.com/products/jndi/.
You can also see the JNDI tutorial at http://java.sun.com/products/jndi/tutorial/.
This chapter contains the following sections:
The Web Profile of the GlassFishTM Server supports the EJB 3.1 Lite specification, which allows enterprise beans within web applications, among other features. The full GlassFish Server supports the entire EJB 3.1 specification. For details, see JSR 318.
The Oracle GlassFish Server provides a naming environment, or context, which is compliant with standard Java EE requirements. A Context object provides the methods for binding names to objects, unbinding names from objects, renaming objects, and listing the bindings. The InitialContext is the handle to the Java EE naming service that application components and clients use for lookups.
The JNDI API also provides subcontext functionality. Much like a directory in a file system, a subcontext is a context within a context. This hierarchical structure permits better organization of information. For naming services that support subcontexts, the Context class also provides methods for creating and destroying subcontexts.
The rest of this section covers these topics:
Each resource within the server must have a unique name.
Global JNDI names are assigned according to the following precedence rules:
A global JNDI name assigned in the sun-ejb-jar.xml, sun-web.xml, or sun-application-client.xml deployment descriptor file has the highest precedence. See Mapping References.
A global JNDI name assigned in a mapped-name element in the ejb-jar.xml, web.xml, or application-client.xml deployment descriptor file has the second highest precedence. The following elements have mapped-name subelements: resource-ref, resource-env-ref, ejb-ref, message-destination, message-destination-ref, session, message-driven, and entity.
A global JNDI name assigned in a mappedName attribute of an annotation has the third highest precedence. The following annotations have mappedName attributes: @javax.annotation.Resource, @javax.ejb.EJB, @javax.ejb.Stateless, @javax.ejb.Stateful, and @javax.ejb.MessageDriven.
A default global JNDI name is assigned in some cases if no name is assigned in deployment descriptors or annotations.
For an EJB 2.x dependency or a session or entity bean with a remote interface, the default is the fully qualified name of the home interface.
For an EJB 3.0 dependency or a session bean with a remote interface, the default is the fully qualified name of the remote business interface.
If both EJB 2.x and EJB 3.0 remote interfaces are specified, or if more than one 3.0 remote interface is specified, there is no default, and the global JNDI name must be specified.
For all other component dependencies that must be mapped to global JNDI names, the default is the name of the dependency relative to java:comp/env. For example, in the @Resource(name="jdbc/Foo") DataSource ds; annotation, the global JNDI name is jdbc/Foo.
The preferred way of accessing the naming service, even in code that runs outside of a Java EE container, is to use the no-argument InitialContext constructor. However, if EJB client code explicitly instantiates an InitialContext that points to the CosNaming naming service, it is necessary to set the java.naming.factory.initial property to com.sun.jndi.cosnaming.CNCtxFactory in the client JVM software when accessing EJB components. You can set this property as a command-line argument, as follows:
-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory |
Or you can set this property in the code, as follows:
Properties properties = null; try { properties = new Properties(); properties.put("java.naming.factory.initial", "com.sun.jndi.cosnaming.CNCtxFactory"); ...
The recommended approach for looking up an EJB component in a remote GlassFish Server from a client that is a servlet or EJB component is to use the Interoperable Naming Service syntax. Host and port information is prepended to any global JNDI names and is automatically resolved during the lookup. The syntax for an interoperable global name is as follows:
corbaname:iiop:host:port#a/b/name
This makes the programming model for accessing EJB components in another GlassFish Server exactly the same as accessing them in the same server. The deployer can change the way the EJB components are physically distributed without having to change the code.
For Java EE components, the code still performs a java:comp/env lookup on an EJB reference. The only difference is that the deployer maps the ejb-reference element to an interoperable name in a GlassFish Server deployment descriptor file instead of to a simple global JNDI name.
For example, suppose a servlet looks up an EJB reference using java:comp/env/ejb/Foo, and the target EJB component has a global JNDI name of a/b/Foo.
The ejb-ref element in sun-web.xml looks like this:
<ejb-ref> <ejb-ref-name>ejb/Foo</ejb-ref-name> <jndi-name>corbaname:iiop:host:port#a/b/Foo</jndi-name> <ejb-ref>
The code looks like this:
Context ic = new InitialContext(); Object o = ic.lookup("java:comp/env/ejb/Foo");
For a client that doesn’t run within a Java EE container, the code just uses the interoperable global name instead of the simple global JNDI name. For example:
Context ic = new InitialContext(); Object o = ic.lookup("corbaname:iiop:host:port#a/b/Foo");
Objects stored in the interoperable naming context and component-specific (java:comp/env) naming contexts are transient. On each server startup or application reloading, all relevant objects are re-bound to the namespace.
Lifecycle listener modules provide a means of running short or long duration tasks based on Java technology within the GlassFish Server environment, such as instantiation of singletons or RMI servers. These modules are automatically initiated at server startup and are notified at various phases of the server life cycle. For details about lifecycle modules, see Chapter 13, Developing Lifecycle Listeners.
The configured properties for a lifecycle module are passed as properties during server initialization (the INIT_EVENT). The initial JNDI naming context is not available until server initialization is complete. A lifecycle module can get the InitialContext for lookups using the method LifecycleEventContext.getInitialContext() during, and only during, the STARTUP_EVENT, READY_EVENT, or SHUTDOWN_EVENT server life cycle events.
The GlassFish Server exposes the following special resources in the naming environment. Full administration details are provided in the following sections:
An external JNDI resource defines custom JNDI contexts and implements the javax.naming.spi.InitialContextFactory interface. There is no specific JNDI parent context for external JNDI resources, except for the standard java:comp/env/.
Create an external JNDI resource in one of these ways:
To create an external JNDI resource using the Administration Console, open the Resources component, open the JNDI component, and select External Resources. For details, click the Help button in the Administration Console.
To create an external JNDI resource, use the asadmin create-jndi-resource command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
A custom resource specifies a custom server-wide resource object factory that implements the javax.naming.spi.ObjectFactory interface. There is no specific JNDI parent context for external JNDI resources, except for the standard java:comp/env/.
Create a custom resource in one of these ways:
To create a custom resource using the Administration Console, open the Resources component, open the JNDI component, and select Custom Resources. For details, click the Help button in the Administration Console.
To create a custom resource, use the asadmin create-custom-resource command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
The GlassFish Server provides built-in factories for the following types of custom resources:
Template sun-resources.xml files for these built-in factories and a README file are available at as-install/lib/install/templates/resources/custom/. For more information about the sun-resources.xml file, see the Oracle GlassFish Server 3.0.1 Application Deployment Guide.
To create a custom resource that provides instances of a JavaBean class, follow these steps:
Set the custom resource's factory class to org.glassfish.resources.custom.factory.JavaBeanFactory.
Create a property in the custom resource for each setter method in the JavaBean class.
For example, if the JavaBean class has a method named setAccount, specify a property named account and give it a value.
Make sure the JavaBean class is accessible to the GlassFish Server.
For example, you can place the JavaBean class in the as-install/lib directory.
To create a custom resource that provides properties to applications, set the custom resource's factory class to org.glassfish.resources.custom.factory.PropertiesFactory, then specify one or both of the following:
Create a property in the custom resource named fileName and specify as its value the path to a properties file or an XML file.
The path can be absolute or relative to as-install. The file must be accessible to the GlassFish Server.
If an XML file is specified, it must match the document type definition (DTD) specified in the API definition of java.util.Properties.
Create the desired properties directly as properties of the custom resource.
If both the fileName property and other properties are specified, the resulting property set is the union. If the same property is defined in the file and directly in the custom resource, the value of the latter takes precedence.
To create a custom resource that provides Java primitives to applications, follow these steps:
Set the custom resource's factory class to org.glassfish.resources.custom.factory.PrimitivesAndStringFactory.
Set the custom resource's resource type to one of the following or its fully qualified wrapper class name equivalent:
int
integer
long
double
float
char
character
short
byte
boolean
String
Create a property in the custom resource named value and give it the value needed by the application.
For example, If the application requires a double of value 22.1, create a property with the name value and the value 22.1.
To create a custom resource that provides URL instances to applications, follow these steps:
Set the custom resource's factory class to org.glassfish.resources.custom.factory.URLFactory.
Choose which of the following constructors to use:
URL(protocol, host, port, file)
URL(protocol, host, file)
URL(spec)
Define properties according to the chosen constructor.
For example, for the first constructor, define properties named protocol, host, port, and file. Example values might be http, localhost, 8085, and index.html, respectively.
For the third constructor, define a property named spec and assign it the value of the entire URL.
To use a custom jndi.properties file, place the file in the domain-dir/lib/classes directory or JAR it and place it in the domain-dir/lib directory. This adds the custom jndi.properties file to the Common class loader. For more information about class loading, see Chapter 2, Class Loaders.
For each property found in more than one jndi.properties file, the Java EE naming service either uses the first value found or concatenates all of the values, whichever makes sense.
The following XML elements in the GlassFish Server deployment descriptors map resource references in application client, EJB, and web application components to JNDI names configured in the GlassFish Server:
resource-env-ref - Maps the @Resource or @Resources annotation (or the resource-env-ref element in the corresponding Java EE XML file) to the absolute JNDI name configured in the GlassFish Server.
resource-ref - Maps the @Resource or @Resources annotation (or the resource-ref element in the corresponding Java EE XML file) to the absolute JNDI name configured in the GlassFish Server.
ejb-ref - Maps the @EJB annotation (or the ejb-ref element in the corresponding Java EE XML file) to the absolute JNDI name configured in the GlassFish Server.
JNDI names for EJB components must be unique. For example, appending the application name and the module name to the EJB name is one way to guarantee unique names. In this case, mycompany.pkging.pkgingEJB.MyEJB would be the JNDI name for an EJB in the module pkgingEJB.jar, which is packaged in the pkging.ear application.
These elements are part of the sun-web.xml, sun-application-client.xml, and sun-ejb-ref.xml deployment descriptor files. For more information about how these elements behave in each of the deployment descriptor files, see Appendix C, Elements of the GlassFish Server Deployment Descriptors, in Oracle GlassFish Server 3.0.1 Application Deployment Guide.
The rest of this section uses an example of a JDBC resource lookup to describe how to reference resource factories. The same principle is applicable to all resources (such as JMS destinations, JavaMail sessions, and so on).
The @Resource annotation in the application code looks like this:
@Resource(name="jdbc/helloDbDs") javax.sql.DataSource ds;
This references a resource with the JNDI name of java:comp/env/jdbc/helloDbDs. If this is the JNDI name of the JDBC resource configured in the GlassFish Server, the annotation alone is enough to reference the resource.
However, you can use a GlassFish Server specific deployment descriptor to override the annotation. For example, the resource-ref element in the sun-web.xml file maps the res-ref-name (the name specified in the annotation) to the JNDI name of another JDBC resource configured in the GlassFish Server.
<resource-ref> <res-ref-name>jdbc/helloDbDs</res-ref-name> <jndi-name>jdbc/helloDbDataSource</jndi-name> </resource-ref>
This chapter describes how to use the JavaTM Message Service (JMS) API. The Oracle GlassFishTM Server has a fully integrated JMS provider: the GlassFish Message Queue software.
JMS resources are supported only in the full GlassFish Server, not in the Web Profile.
For detailed information about JMS concepts and JMS support in the GlassFish Server, see Chapter 19, Administering the Java Message Service (JMS) , in Oracle GlassFish Server 3.0.1 Administration Guide.
For more information about Message Queue software, see the Oracle GlassFish Message Queue 4.4.2 Administration Guide.
This chapter contains the following sections:
The GlassFish Server support for JMS messaging, in general, and for message-driven beans, in particular, requires messaging middleware that implements the JMS specification: a JMS provider. The GlassFish Server uses the GlassFish Message Queue software as its native JMS provider. The Message Queue software is tightly integrated into theGlassFish Server, providing transparent JMS messaging support. This support is known within GlassFish Server as the JMS Service. The JMS Service requires only minimal administration.
The relationship of the Message Queue software to the GlassFish Server can be one of these types: EMBEDDED, LOCAL, or REMOTE. The effects of these choices on the Message Queue broker life cycle are as follows:
If the type is EMBEDDED, the GlassFish Server and Message Queue software run in the same JVM, and the networking stack is bypassed. The Message Queue broker is started and stopped automatically by the GlassFish Server. This is the default for the Domain Administration Server (DAS).
Lazy initialization starts the default embedded broker on the first access of JMS services rather than at GlassFish Server startup.
If the type is LOCAL, the Message Queue broker starts when the GlassFish Server starts. This is the default for all GlassFish Server instances except the DAS.
The LOCAL setting implicitly sets up a 1:1 relationship between a GlassFish Server instance and a Message Queue broker.
If the type is REMOTE, the Message Queue broker must be started separately. For information about starting the broker, see the Oracle GlassFish Message Queue 4.4.2 Administration Guide.
For more information about setting the type and the default JMS host, see Configuring the JMS Service.
For more information about the Message Queue software, refer to the documentation at http://docs.sun.com/coll/1343.13.
For general information about the JMS API, see the JMS web page at http://java.sun.com/products/jms/index.jsp.
The Message Queue software is integrated into the GlassFish Server using a resource adapter that is compliant with the Connector specification. The module name of this system resource adapter is jmsra. Every JMS resource is converted to a corresponding connector resource of this resource adapter as follows:
Connection Factory – A connector connection pool with a max-pool-size of 250 and a corresponding connector resource
Destination (Topic or Queue) – A connector administered object
You use connector configuration tools to manage JMS resources. For more information, see Chapter 12, Developing Connectors.
The GlassFish Server provides a generic resource adapter for JMS, for those who want to use a JMS provider other than Message Queue. For details, see https://genericjmsra.dev.java.net/ and Configuring Resource Adapters for JMS in Oracle GlassFish Server 3.0.1 Administration Guide.
To configure the JMS Service and prepare JMS resources for use in applications deployed to the GlassFish Server, you must perform these tasks:
For more information about JMS administration tasks, see Chapter 19, Administering the Java Message Service (JMS) , in Oracle GlassFish Server 3.0.1 Administration Guide and the Oracle GlassFish Message Queue 4.4.2 Administration Guide.
The JMS Service configuration is available to all inbound and outbound connections pertaining to the GlassFish Server instance. You can edit the JMS Service configuration in the following ways:
To edit the JMS Service configuration using the Administration Console, open the Java Message Service component under the relevant configuration. For details, click the Help button in the Administration Console.
To configure the JMS service, use the asadmin set command to set the following attributes:
server.jms-service.init-timeout-in-seconds = 60 server.jms-service.type = EMBEDDED server.jms-service.start-args = server.jms-service.default-jms-host = default_JMS_host server.jms-service.reconnect-interval-in-seconds = 60 server.jms-service.reconnect-attempts = 3 server.jms-service.reconnect-enabled = true server.jms-service.addresslist-behavior = random server.jms-service.addresslist-iterations = 3 server.jms-service.mq-scheme = mq server.jms-service.mq-service = jms
You can also set these properties:
server.jms-service.property.instance-name = imqbroker server.jms-service.property.instance-name-suffix = server.jms-service.property.append-version = false server.jms-service.property.user-name = server.jms-service.property.password =
You can use the asadmin get command to list all the JMS service attributes and properties. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
You can override the JMS Service configuration using JMS connection factory settings. For details, see Chapter 19, Administering the Java Message Service (JMS) , in Oracle GlassFish Server 3.0.1 Administration Guide.
The GlassFish Server instance must be restarted after configuration of the JMS Service.
A JMS host refers to a Message Queue broker. A default JMS host for the JMS service is provided, named default_JMS_host. This is the JMS host that the GlassFish Server uses for performing all Message Queue broker administrative operations, such as creating and deleting JMS destinations.
If you have created a multi-broker cluster in the Message Queue software, delete the default JMS host, then add the Message Queue cluster’s brokers as JMS hosts. In this case, the default JMS host becomes the first JMS host in the AddressList. For more information about the AddressList, see JMS Connection Features. You can also explicitly set the default JMS host; see Configuring the JMS Service.
When the GlassFish Server uses a Message Queue cluster, it executes Message Queue specific commands on the default JMS host. For example, when a physical destination is created for a Message Queue cluster of three brokers, the command to create the physical destination is executed on the default JMS host, but the physical destination is used by all three brokers in the cluster.
You can create additional JMS hosts in the following ways:
Use the Administration Console. Open the Java Message Service component under the relevant configuration, then select the JMS Hosts component. For details, click the Help button in the Administration Console.
Use the asadmin create-jms-host command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
For machines having more than one host, use the Host field in the Administration Console or the ---–mqhost option of create-jms-host to specify the address to which the broker binds.
You can use the asadmin jms-ping command to check whether a Message Queue instance is running. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
Produced messages are delivered for routing and subsequent delivery to consumers using physical destinations in the JMS provider. A physical destination is identified and encapsulated by an administered object (a Topic or Queue destination resource) that an application component uses to specify the destination of messages it is producing and the source of messages it is consuming.
If a message-driven bean is deployed and the Queue physical destination it listens to doesn’t exist, the GlassFish Server automatically creates the physical destination. However, it is good practice to create the Queue physical destination beforehand.
You can create a JMS physical destination in the following ways:
Use the Administration Console. Open the Resources component, open the JMS Resources component, then select Physical Destinations. For details, click the Help button in the Administration Console.
Use the asadmin create-jmsdest command. This command acts on the default JMS host of its target. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
To purge all messages currently queued at a physical destination, use the asadmin flush-jmsdest command. This deletes the messages before they reach any message consumers. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
To create a destination resource, see Creating JMS Resources: Destinations and Connection Factories.
You can create two kinds of JMS resources in the GlassFish Server:
Connection Factories – administered objects that implement the ConnectionFactory, QueueConnectionFactory, or TopicConnectionFactory interfaces.
Destination Resources – administered objects that implement the Queue or Topic interfaces.
In either case, the steps for creating a JMS resource are the same. You can create a JMS resource in the following ways:
To create a JMS resource using the Administration Console, open the Resources component, then open the JMS Resources component. Click Connection Factories to create a connection factory, or click Destination Resources to create a queue or topic. For details, click the Help button in the Administration Console.
A JMS resource is a type of connector. For more information about connectors, see Chapter 12, Developing Connectors.
All JMS resource properties that used to work with version 7 of the GlassFish Server are supported for backward compatibility.
When a JMS client accesses a JMS administered object for the first time, the client JVM retrieves the JMS service configuration from the GlassFish Server. Further changes to the configuration are not available to the client JVM until the client is restarted.
The Message Queue software supports the following JMS connection features:
Both these features use the AddressList configuration, which is populated with the hosts and ports of the JMS hosts defined in the GlassFish Server. The AddressList is updated whenever a JMS host configuration changes. The AddressList is inherited by any JMS resource when it is created and by any MDB when it is deployed.
In the Message Queue software, the AddressList property is called imqAddressList.
The GlassFish Server pools JMS connections automatically.
To dynamically modify connection pool properties using the Administration Console, go to either the Connection Factories page (see Creating JMS Resources: Destinations and Connection Factories) or the Connector Connection Pools page.
To use the command line, use the asadmin create-connector-connection-pool command to manage the pool.
The addresslist-behavior JMS service attribute is set to random by default. This means that each ManagedConnection (physical connection) created from the ManagedConnectionFactory selects its primary broker in a random way from the AddressList.
The addresslist-behavior JMS service attribute can be set to priority. This means that the first broker in the AddressList is selected first.
When a JMS connection pool is created, there is one ManagedConnectionFactory instance associated with it. If you configure the AddressList as a ManagedConnectionFactory property, the AddressList configuration in the ManagedConnectionFactory takes precedence over the one defined in the GlassFish Server.
To specify whether the GlassFish Server tries to reconnect to the primary broker if the connection is lost, set the reconnect-enabled attribute in the JMS service. To specify the number of retries and the time between retries, set the reconnect-attempts and reconnect-interval-in-seconds attributes, respectively.
If reconnection is enabled and the primary broker goes down, the GlassFish Server tries to reconnect to another broker in the AddressList. The AddressList is updated whenever a JMS host configuration changes. The logic for scanning is decided by two JMS service attributes, addresslist-behavior and addresslist-iterations.
You can override these settings using JMS connection factory settings. For details, see Chapter 19, Administering the Java Message Service (JMS) , in Oracle GlassFish Server 3.0.1 Administration Guide.
The Message Queue software transparently transfers the load to another broker when the failover occurs. JMS semantics are maintained during failover.
During transaction recovery, non-persistent messages might be lost. If the broker fails between the transaction manager’s prepare and commit operations, any non-persistent message in the transaction is lost and cannot be delivered. A message that is not saved to a persistent store is not available for transaction recovery.
The Java EE Connector 1.6 specification allows a resource adapter to use the transaction-support attribute to specify the level of transaction support that the resource adapter handles. However, the resource adapter vendor does not have a mechanism to figure out the current transactional context in which a ManagedConnectionFactory is used.
If a ManagedConnectionFactory implements an optional interface called com.sun.appserv.connectors.spi.ConfigurableTransactionSupport, the GlassFish Server notifies the ManagedConnectionFactory of the transaction-support configured for the connector connection pool when the ManagedConnectionFactory instance is created for the pool. Connections obtained from the pool can then be used with a transaction level at or lower than the configured value. For example, a connection obtained from a pool that is set to XA_TRANSACTION could be used as a LOCAL resource in a last-agent-optimized transaction or in a non-transactional context.
If your web, EJB, or client module has res-auth set to Container, but you use the ConnectionFactory.createConnection("user","password") method to get a connection, the GlassFish Server searches the container for authentication information before using the supplied user and password. Version 7 of the GlassFish Server threw an exception in this situation.
The Message Queue software uses a default directory for storing data such as persistent messages and its log file. This directory is called varhome. The GlassFish Server uses domain-dir/imq as the varhome directory if the type of relationship between the GlassFish Server and the Message Queue software is LOCAL or EMBEDDED. If the relationship type is REMOTE, the Message Queue software determines the varhome location. For more information about the types of relationships between the GlassFish Server and Message Queue, see The JMS Provider.
When executing Message Queue scripts such as as-install/imq/bin/imqusermgr, use the -varhome option to point the scripts to the Message Queue data if the relationship type is LOCAL or EMBEDDED. For example:
imqusermgr -varhome $AS_INSTALL/domains/domain1/imq add -u testuser
For more information about the Message Queue software, refer to the documentation at http://docs.sun.com/coll/1343.13.
Web service clients use the Simple Object Access Protocol (SOAP) to communicate with web services. SOAP uses a combination of XML-based data structuring and Hyper Text Transfer Protocol (HTTP) to define a standardized way of invoking methods in objects distributed in diverse operating environments across the Internet.
For more information about SOAP, see the Apache SOAP web site at http://xml.apache.org/soap/index.html.
You can take advantage of the JMS provider’s reliable messaging when delivering SOAP messages. You can convert a SOAP message into a JMS message, send the JMS message, then convert the JMS message back into a SOAP message. The following sections explain how to do these conversions:
Import the MessageTransformer library.
import com.sun.messaging.xml.MessageTransformer;
This is the utility whose methods you use to convert SOAP messages to JMS messages and the reverse. You can then send a JMS message containing a SOAP payload as if it were a normal JMS message.
Initialize the TopicConnectionFactory, TopicConnection, TopicSession, and publisher.
tcf = new TopicConnectionFactory(); tc = tcf.createTopicConnection(); session = tc.createTopicSession(false,Session.AUTO_ACKNOWLEDGE); topic = session.createTopic(topicName); publisher = session.createPublisher(topic);
Construct a SOAP message using the SOAP with Attachments API for Java (SAAJ).
/*construct a default soap MessageFactory */ MessageFactory mf = MessageFactory.newInstance(); * Create a SOAP message object.*/ SOAPMessage soapMessage = mf.createMessage(); /** Get SOAP part.*/ SOAPPart soapPart = soapMessage.getSOAPPart(); /* Get SOAP envelope. */ SOAPEnvelope soapEnvelope = soapPart.getEnvelope(); /* Get SOAP body.*/ SOAPBody soapBody = soapEnvelope.getBody(); /* Create a name object. with name space */ /* http://www.sun.com/imq. */ Name name = soapEnvelope.createName("HelloWorld", "hw", "http://www.sun.com/imq"); * Add child element with the above name. */ SOAPElement element = soapBody.addChildElement(name) /* Add another child element.*/ element.addTextNode( "Welcome to GlassFish Web Services." ); /* Create an atachment with activation API.*/ URL url = new URL ("http://java.sun.com/webservices/"); DataHandler dh = new DataHandler (url); AttachmentPart ap = soapMessage.createAttachmentPart(dh); /*set content type/ID. */ ap.setContentType("text/html"); ap.setContentId("cid-001"); /** add the attachment to the SOAP message.*/ soapMessage.addAttachmentPart(ap); soapMessage.saveChanges();
Convert the SOAP message to a JMS message by calling the MessageTransformer.SOAPMessageintoJMSMessage() method.
Message m = MessageTransformer.SOAPMessageIntoJMSMessage (soapMessage, session );
Publish the JMS message.
publisher.publish(m);
Close the JMS connection.
tc.close();
Import the MessageTransformer library.
import com.sun.messaging.xml.MessageTransformer;
This is the utility whose methods you use to convert SOAP messages to JMS messages and the reverse. The JMS message containing the SOAP payload is received as if it were a normal JMS message.
Initialize the TopicConnectionFactory, TopicConnection, TopicSession, TopicSubscriber, and Topic.
messageFactory = MessageFactory.newInstance(); tcf = new com.sun.messaging.TopicConnectionFactory(); tc = tcf.createTopicConnection(); session = tc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); topic = session.createTopic(topicName); subscriber = session.createSubscriber(topic); subscriber.setMessageListener(this); tc.start();
Use the OnMessage method to receive the message. Use the SOAPMessageFromJMSMessage method to convert the JMS message to a SOAP message.
public void onMessage (Message message) { SOAPMessage soapMessage = MessageTransformer.SOAPMessageFromJMSMessage( message, messageFactory ); }
Retrieve the content of the SOAP message.
This chapter describes how to use the JavaMailTM API, which provides a set of abstract classes defining objects that comprise a mail system.
This chapter contains the following sections:
JavaMail resources are supported only in the full OracleGlassFishTM Server, not in the Web Profile.
The JavaMail API defines classes such as Message, Store, and Transport. The API can be extended and can be subclassed to provide new protocols and to add functionality when necessary. In addition, the API provides concrete subclasses of the abstract classes. These subclasses, including MimeMessage and MimeBodyPart, implement widely used Internet mail protocols and conform to the RFC822 and RFC2045 specifications. The JavaMail API includes support for the IMAP4, POP3, and SMTP protocols.
The JavaMail architectural components are as follows:
The abstract layer declares classes, interfaces, and abstract methods intended to support mail handling functions that all mail systems support.
The internet implementation layer implements part of the abstract layer using the RFC822 and MIME internet standards.
JavaMail uses the JavaBeans Activation Framework (JAF) to encapsulate message data and to handle commands intended to interact with that data.
For more information, see Chapter 18, Administering the JavaMail Service, in Oracle GlassFish Server 3.0.1 Administration Guide and the JavaMail specification at http://java.sun.com/products/javamail/. A useful JavaMail tutorial is located at http://java.sun.com/developer/onlineTraining/JavaMail/.
You can create a JavaMail session in the following ways:
In the Administration Console, open the Resources component and select JavaMail Sessions. For details, click the Help button in the Administration Console.
Use the asadmin create-javamail-resource command. For details, see the Oracle GlassFish Server 3.0.1 Reference Manual.
You can set properties for a JavaMail Session object. Every property name must start with a mail- prefix. The GlassFish Server changes the dash (-) character to a period (.) in the name of the property and saves the property to the MailConfiguration and JavaMail Session objects. If the name of the property doesn’t start with mail-, the property is ignored.
For example, if you want to define the property mail.from in a JavaMail Session object, first define the property as follows:
Name – mail-from
Value – john.doe@sun.com
The standard Java Naming and Directory Interface (JNDI) subcontext for JavaMail sessions is java:comp/env/mail.
Registering JavaMail sessions in the mail naming subcontext of a JNDI namespace, or in one of its child subcontexts, is standard. The JNDI namespace is hierarchical, like a file system’s directory structure, so it is easy to find and nest references. A JavaMail session is bound to a logical JNDI name. The name identifies a subcontext, mail, of the root context, and a logical name. To change the JavaMail session, you can change its entry in the JNDI namespace without having to modify the application.
The resource lookup in the application code looks like this:
InitialContext ic = new InitialContext(); String snName = "java:comp/env/mail/MyMailSession"; Session session = (Session)ic.lookup(snName);
For more information about the JNDI API, see Chapter 16, Using the Java Naming and Directory Interface.
The following sections describe how to send and read messages using the JavaMail API:
Import the packages that you need.
import java.util.*; import javax.activation.*; import javax.mail.*; import javax.mail.internet.*; import javax.naming.*;
Look up the JavaMail session.
InitialContext ic = new InitialContext(); String snName = "java:comp/env/mail/MyMailSession"; Session session = (Session)ic.lookup(snName);
For more information, see Looking Up a JavaMail Session.
Override the JavaMail session properties if necessary.
For example:
Properties props = session.getProperties(); props.put("mail.from", "user2@mailserver.com");
Create a MimeMessage.
The msgRecipient, msgSubject, and msgTxt variables in the following example contain input from the user:
Message msg = new MimeMessage(session); msg.setSubject(msgSubject); msg.setSentDate(new Date()); msg.setFrom(); msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(msgRecipient, false)); msg.setText(msgTxt);
Send the message.
Transport.send(msg);
Import the packages that you need.
import java.util.*; import javax.activation.*; import javax.mail.*; import javax.mail.internet.*; import javax.naming.*;
Look up the JavaMail session.
InitialContext ic = new InitialContext(); String snName = "java:comp/env/mail/MyMailSession"; Session session = (javax.mail.Session)ic.lookup(snName);
For more information, see Looking Up a JavaMail Session.
Override the JavaMail session properties if necessary.
For example:
Properties props = session.getProperties(); props.put("mail.from", "user2@mailserver.com");
Get a Store object from the Session, then connect to the mail server using the Store object’s connect method.
You must supply a mail server name, a mail user name, and a password.
Store store = session.getStore(); store.connect("MailServer", "MailUser", "secret");
Get the INBOX folder.
Folder folder = store.getFolder("INBOX");
It is efficient to read the Message objects (which represent messages on the server) into an array.
Message[] messages = folder.getMessages();