« June 2007 | Main | August 2007 »

July 2007 Archives

July 10, 2007

UPDATE: "RMIConnection Disconnected" Issue

At a specific project in the US, colleagues of mine faced the "RMIConnection Disconnected" issue. Unfortunately, this wasn't a problem that could be easily solved like in my earlier post on that one.

This one is different as it involves two different OC4J/AS versions (10.1.2 and 10.1.3). It is really a bug and fixed in patch 6114217 for OC4J/AS 10.1.3.[012] and also made it into the 10.1.3.3 one-off patch 6148874.

July 16, 2007

Reclaim your disk space

After 7 weeks of constant travelling, I thought it would be good idea to backup my data.

Where to find unneeded backup copies?

JDeveloper and the embedded OC4J use a number of directories to put temporary files to.
  • OC4J: Your OSs temporary directory. Contents in this directory can be deleted once your applications aren't running. But be aware that some OSs put valuable information there. During deployment OC4J puts WAR and EAR files there. It is same safe to delete them after a deployment.
  • JDeveloper: $JDEV_HOME/jdev/extensions and $JDEV_HOME/jdev/system. During Check for Updates JDeveloper creates a backup copy of the previous version of the JAR file containing the Addin in the extension directory. It also creates a new Addin-related directory in the system directory. Once your new and updated Addin works as expected you're free to delete the backups. Be aware that all files with the .jar suffix should remain in the extension directory.
By checking these directories and deleting the appropriate files, you might be able to reclaim up to 1GB or more of disk space. Depending of the length of the interval between your individual deletes...


July 23, 2007

OC4J: Interaction between 10.1.3.x & 10.1.2.0.2, Part 1

Cyrillic Signs:
See this post as a follow-up on my 
Make JDev 10.1.3 talk to Oracle AS 10.l.2 post from last year.

The Issue

Having applied patch 4676768 or related to your still existing Oracle
AS 10.1.2.x instance helps to communicate with newer Oracle AS 10.1.3
based applications. As long as these are behaving correctly.

In case of an exception you'll end up with a

oracle.oc4j.rmi.OracleRemoteException: Class not found: com.evermind.server.rmi.OrionRemoteException

This is quite unfortunate as the exception might contain valuable information for the application or the developer.

Approach 1

The usual reflex is to include the client library (oc4jclient.jar) from
OC4J 10.1.2.x. Although this works in most cases, this might lead to
other library or class version conflicts.

Approach 2

Create a simple library to be included in the class path. This library just contains the com.evermind.server.rmi.OrionRemoteException class from the aforementioned library. For good reasons you shouldn't do this either, as it might be a License Agreement violation and your lawyers should be pretty alert. I also hate to include unneeded libraries into the class path.

Approach 3

Ask the vendor to include the missing com.evermind.server.rmi.OrionRemoteException class into OC4J 10.1.3 class path. This is the best and therefore I've filed Bug 6252184 to get it solved.

July 24, 2007

OC4J: Configuring and Using AQ w/ Remote Clients

Caveat

For a better understanding of the details used herein please refer to the How-To on OTN.

Requirements

You need an Oracle Database that supports AQ configuration. Also OC4J/Oracle Application Server 10.1.3.3 or later is required. I've tested this with OC4J 10.1.3.3 standalone and SOA Suite 10.1.3.1 patched to 10.1.3.3. Tests with OC4J 10.1.3.2 showed some issues.

The Application

In JDeveloper create a new application called AQ. Don't create a new project (simply cancel that window). This application will eventually contain two projects for the AQ configuration and a remote client test project.

The Resource Adapter

Create a new empty project named AQRA for AQ Resource Adapter. In this project create two new deployment descriptors: ra.xml and oc4j-ra.xml. Finally create a RAR deployment profile named aqjms to package the resource adapter. We can use the deployment profile as it was created.

ra.xml

After JDeveloper has created the default file content for the ra.xml we replace the whole content with the one from the ra.xml that comes with the How-to (see References). You can either remove or keep the comments. Now comes the tricky part: We need to have good, easier to type names. Therfore we replace the OEMSJMSDReference with aqRP. Secondly the <adminobject>'s that have the jndiName Queues/MY_QUEUE or Topics/MY_TOPIC should be removed. The generic approach for accessing the queues is good enough for us.

oc4j-ra.xml

We do the same as with the ra.xml with the oc4j-ra.xml file, ie replacing the whole content of the file with the content of the sample oc4j-ra.xml from the How-to. The tricky part is the same here, we need to have good, easier to type names:
  • Replace connector-name="OEMSJMSDRAInstanceName" with connector-name="AQRA"
  • Likewise we change the location="OEMSJMSDRASubcontext to location="AQJMSSubcontext

Deployment Profile

We can use the RAR deployment profile as created by JDeveloper. Doing a Recompile All will move the deployment descriptors to classes directory and makes them visible for the profile.

The Enterprise Application

Once we have done the resource adapter, we need to package it properly as a Java EE Enterprise Application in an EAR file. For this we create a new empty project called EAR. In this project we need to create three OC4J-specific deployment descriptors: data-sources.xml, orion-application.xml, and oc4j-connectors.xml. Next, we create an EAR deployment profile called aqear for the final EAR creation.

data-sources.xml

The data-sources.xml contains just the configuration needed for the AQ data source. Nothing more. Here is the complete file:
<?xml version = '1.0' encoding = 'windows-1252'?>
<data-sources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/data-sources-10_1.xsd">
   <managed-data-source connection-pool-name="aqPool" jndi-name="jdbc/aqDS"
                        name="aqDS"/>
   <connection-pool name="aqPool">
      <connection-factory factory-class="oracle.jdbc.pool.OracleDataSource"
                          user="jmsuser" password="welcome1"
                          url="jdbc:oracle:thin:@//localhost:1521/XE">
         <proxy-interface sql-object="PreparedStatement"
                          interface="oracle.jdbc.OraclePreparedStatement"/>
         <proxy-interface sql-object="Connection"
                          interface="oracle.jdbc.internal.OracleConnection"/>
         <proxy-interface sql-object="CallableStatement"
                          interface="oracle.jdbc.OracleCallableStatement"/>
         <proxy-interface sql-object="Statement"
                          interface="oracle.jdbc.OracleStatement"/>
         <proxy-interface sql-object="ResultSet"
                          interface="oracle.jdbc.OracleResultSet"/>
      </connection-factory>
   </connection-pool>
</data-sources>

orion-application.xml

In the orion-application.xml we configure the link between the data source and the resource adapter, the <resource-provider> tag. Here is the complete file:
<?xml version = '1.0' encoding = 'windows-1252'?>
<orion-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/orion-application-10_0.xsd">
  <data-sources path="./data-sources.xml" />
  <connectors path="./oc4j-connectors.xml" />
  <resource-provider class="oracle.jms.OjmsContext" name="aqRP">
    <property name="datasource" value="jdbc/aqDS" />
  </resource-provider>
</orion-application>

oc4j-connectors.xml

The next file is the oc4j-connectors.xml. In this file we configure the link between the resource provider and the JNDI space. Here is the complete file:
<?xml version="1.0" encoding="windows-1252" ?>
<oc4j-connectors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:noNamespaceSchemaLocation="http://www.oracle.com/technology/oracleas/schema/oc4j-connectors-10_0.xsd"
                 schema-major-version="10" schema-minor-version="0">
<connector name="AQRA" path="aqjms.rar">
  <config-property name="lookupMethod" value="resourceProvider" />
  <config-property name="resourceProviderName" value="aqRP" />
  <adminobject-config location="aq/Queues">
   <adminobject-class>oracle.j2ee.ra.jms.generic.AdminObjectQueueImpl</adminobject-class>
   <config-property name="resourceProviderName" value="aqRP" />
  </adminobject-config>
  <adminobject-config location="aq/Topics">
  <adminobject-class>oracle.j2ee.ra.jms.generic.AdminObjectTopicImpl</adminobject-class>
   <config-property name="resourceProviderName" value="aqRP" />
  </adminobject-config>
</connector>
</oc4j-connectors>

EAR deployment profile

By default the EAR deployment profile includes the standard deployment descriptors. To add the oc4j-connectors.xml we need some extra steps. Double click on the deployment profile and create a new file group (I called it files). In the Filters sub item select only the oc4j-connectors.xml to be included. The rest will be included automagically.

Deployment Profile Screenshot for AQ:

The AQ Setup

To setup the AQ Queues and Topics you should use a SQL script. This comes in handy to redo it when needed (eg. when moving from Development to Production). Here is a simple script:
BEGIN
   DBMS_AQADM.CREATE_QUEUE_TABLE(
        queue_table => 'FromTable',
        queue_payload_type => 'SYS.AQ$_JMS_MESSAGE',
        sort_list => 'PRIORITY,ENQ_TIME',
        multiple_consumers => false,
        compatible => '9.2');
   DBMS_AQADM.CREATE_QUEUE(
      queue_name => 'FROM_QUEUE',
      queue_table => 'FromTable');
   DBMS_AQADM.START_QUEUE(
      queue_name => 'FROM_QUEUE');
   DBMS_AQADM.CREATE_QUEUE_TABLE(
      Queue_table => 'ToTable',
      Queue_payload_type => 'SYS.AQ$_JMS_MESSAGE',
      sort_list => 'PRIORITY,ENQ_TIME',
      multiple_consumers => false,
      compatible => '9.2');
   DBMS_AQADM.CREATE_QUEUE(
      Queue_name => 'TO_QUEUE',
      Queue_table => 'ToTable');
   DBMS_AQADM.START_QUEUE(
      queue_name => 'TO_QUEUE');
   DBMS_AQADM.CREATE_QUEUE_TABLE(
      Queue_table        => 'LOGQTABLE',
      Queue_payload_type => 'SYS.AQ$_JMS_MESSAGE',
      sort_list => 'PRIORITY,ENQ_TIME',
  multiple_consumers => false,
      compatible         => '9.2');
   DBMS_AQADM.CREATE_QUEUE(
      Queue_name  => 'logQ',
      Queue_table => 'LOGQTABLE',
      max_retries => '2');
   DBMS_AQADM.START_QUEUE(
      queue_name => 'logQ');
END;

The Remote Client

Finally, we create an empty project called client for the remote test client. As it is always useful to test your configuration, this one can always be used for configuration verification and sanity checks. It both sends and receives from the queues. For brevity I'll show the sending part only. The receiving part is left as an exercise to the reader.
    System.out.println("Testing queue using " + factoryName + ' ' + 
                       destinationName);
    Connection conn = null;
    Session sess = null;
    MessageProducer prod = null;
    boolean verbose = false;
    try {
      ConnectionFactory factory = (ConnectionFactory)ctx.lookup(factoryName);
      Destination destSend = (Destination)ctx.lookup(destinationName);
      conn = factory.createConnection();
      conn.start();
      sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
      prod = sess.createProducer(destSend);
      TextMessage payload = sess.createTextMessage();
      payload.setText(msg);
      payload.setJMSCorrelationID(new Long(System.currentTimeMillis()).toString());
      prod.send(payload);
      System.out.print("Send " + payload.getJMSCorrelationID());
      if (verbose) {
        System.out.print(' ' + payload.getText());
      }
      System.out.println();
    } finally {
      closeJMSResources(prod, sess, conn);
      prod = null;
      sess = null;
      conn = null;
    }
As good developer we use the jndi.properties file for configuring the JNDI connection and credentials setup.

Needed Libraries

The remote client needs a number of libraries to work properly. These are (within JDeveloper 10.1.3.3):
  • J2EE
  • Oracle 9 iAS
  • $OC4J_HOME/j2ee/home/lib/javax77.jar
  • $OC4J_HOME/j2ee/home/lib/jmxri.jar
  • $OC4J_HOME/j2ee/home/lib/connector.jar
  • $OC4J_HOME/j2ee/home/lib/adminclient.jar
  • $OC4J_HOME/j2ee/home/lib/bcel.jar
  • $OC4J_HOME/j2ee/home/jazncore.jar
  • Oracle JDBC

What JNDI names should I use then?

The JNDI names you should use are:
  • AQJMSsubcontext/My{CF,QCF,TCF,XACF,XAQCF,XATCF}
  • aq/Queues/Queues/<queue_name> or aq/Topics/Topics/<topic_name>

Global Setup

For a server global setup of the AQ resource adapter, you can deploy the RAR file directly from the aqjms deployment profile to OC4J. The only downside is that you have to do the configuration of the global configuration files application.xml, data-sources.xml, and oc4j-connectors.xml manually.

References

July 25, 2007

OC4J: Interaction between 10.1.3.x & 10.1.2.0.2, Part 2

The following is a solution that works for products only certified with OC4J/Application Server 10.1.2.x and an application build on OC4J/Application Server 10.1.3.x...

Cyrillic Signs:

Background

The product called Oracle Healthcare Transaction Base (HTB) is currently certified for OC4J/Application Server 10.1.2.x only. It has a client library that hides all the nitty-gritty details of connecting to several SessionFacades but still needs the usual JNDI configuration details like Context.INITIAL_CONTEXT_FACTORY and Context.PROVIDER_URL. The Context.SECURITY_PRINCIPAL and Context.SECURITY_CREDENTIALS are handled through a special UserManager (hence not yet certified for OC4J 10.1.3.x).

Server Setup


To be able to connect to the HTB server running on OC4J/Application
Server 10.1.2 you need to apply patch 4676768 or related, first.

Library Requirements

Every caller of the HTB client library (htbclnt.jar) must use the HTB client library as well as a specific Oracle JDBC driver (classes12dms.jar). The default Oracle JDBC driver available in OC4J will not work for reasons that easily fill another post. You also need a library containing the class com.evermind.server.rmi.OrionRemoteException. See my post on this topic.

Scenario 1: Web application

If you only use a web application, the issue with the specific JDBC library can be solved by putting the above mentioned libraries into the WEB-INF/libs dircetory and include a WEB-INF/orion-web.xml with this line
<web-app-class-loader
search-local-classes-first="true"
include-war-manifest-class-path="false"/>

Scenario 2: Web application, EJBs

A typical Java EE application with EJB and WAR modules. One of the EJB modules is calling the HTB Session Facades. The WAR is displaying the results.

WAR module

The WAR module can be any normal or high sophisticated web application. The only difference to scenario 1 is that we do not include the HTB libraries!

EJB module

The EJB module is also quite normal in terms of EJBs. Surely there is one Session Bean that acts as a facade to HTB and uses the HTB API to call it. In our IDE we configure the above mentioned HTB libs for compilation, but not for inclusion in the EJB JAR package!

EAR packaging

Since OC4J 10.1.3 we can use the Java EE 5 "shared library approach" to specify our libraries used by all modules. We also need to tell OC4J not to include pre-packaged shared libraries from the OC4J environment. For this we need to configure the EAR deployment descriptors: application.xml and orion-application.xml.
application.xml
The standard Java EE deployment descriptor application.xml contains the standard tags for EJB and WAR modules, plus the Java EE 5 <library-directory> tag and the version="5" attribute setting for the <application> tag. Here is a sample:
<?xml version = '1.0' encoding = 'windows-1252'?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
             version="5" xmlns="http://java.sun.com/xml/ns/javaee">
  <display-name>ear-application</display-name>
  <module>
    <ejb>quoteBeans.jar</ejb>
  </module>
  <module>
    <web>
      <web-uri>quoteUI.war</web-uri>
      <context-root>quote</context-root>
    </web>
  </module>
  <library-directory>libs</library-directory>
</application>
orion-application.xml
The OC4J-specific deployment descriptor orion-application.xml tells OC4J not to include the JDBC driver from the default OC4J library environment. Here is a sample:
<?xml version = '1.0' encoding = 'windows-1252'?>
<orion-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/orion-application-10_0.xsd">
  <imported-shared-libraries>
    <remove-inherited name="oracle.jdbc" />
  </imported-shared-libraries>
</orion-application>

Adding the Libraries
Since we haven't included the HTB libraries yet, we need to do that now! In your IDE make sure that the libraries are included in a directory with the same name as specified in the application.xml deployment descriptor (libs in this text).

About July 2007

This page contains all entries posted to Olaf Heimburger's Blog in July 2007. They are listed from oldest to newest.

June 2007 is the previous archive.

August 2007 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type and Oracle