07 December 2005

The Xtra Easy version of the Database

Oracle Database XE

All I can say so far is that this thing rocks.


Simple to install.
Simple to manage – dead easy in fact.
And … simple to import data from Excel!

The Seminal Classloading Paper for OC4J

For anyone working with OC4J prior to the 10.1.3 release and interested in knowing more about the way in which the classloaders work, this paper addresses most of the questions I've ever heard.


23 November 2005

Dumping System Properties with OC4J

A Simple Dump of System Properties from a JSP With OC4J

A point was made recenttly that a query on Google returned zero hits for showing how to print details of the runtime environment with OC4J.

So here’s my attempt at getting at least one hit for how to do this.

Assumption – OC4J is running somewhere

Step1 – Open a text editor.

Step 2 – Enter the following into the editor.

<%@ page import="java.util.*, java.io.*"%>
<h3>System Properties</h3>
Properties props = System.getProperties();
props.list(new PrintWriter(out));

Step 3 – Save the file as $ORACLE_HOME/j2ee/home/default-web-app/sysprops.jsp

Step 4 – Access the page from a browser http://localhost:8888/sysprops.

26 September 2005

A weekend on the Peninsula

I used to live in the SF Bay Area for near on six and a half years. Over that time, I got to see many of its beautiful areas and attractions. Being a runner and a bit of a cyclist, my favourite way to spend a few hours was always out on the wonderful trails and paths in and around the foothills.

With my Open World commitments over and a weekend on my hands, I've been able to get out and about and visit some of my favourite places all over again.

I went for a run on Thursday with my IronMan colleague Tug (well soon to be IronMan). We went out to Edgewood park -- and did a 40min run on an old favourite trail. Even at the end of summer, it was still a very nice place to run. It was dry and quite brown in patches, but the trails following a few of the little ridges there were all shaded by lovely trees and it was great to be back. Tug spanked me on the uphill portion of the run as evidenced by my Polar HRM which showed me running at 98% of my max heart rate on one portion of the trail.

I have a Polar Heart Rate Meter which I wear when I run and ride. It's got an amazing array of features which allow it to measure the heart rate of a wearer using a wireless transmitter and a chest strap. The version I have also works with a bike by placing a speed-sensor on the front fork. It then can keep track of the speed of the bike, allowing speed v heart rate comparisons to be made. Even better, it has an altitude sensor, so it can plot speed v heart rate v altirude -- which makes for very interesting viewing once a run/ride is over. Finally it allows the captured data from the watch to be uploaded to a computer so it can be easily viewed and stored.

On Saturday I went to what I think is my favourite run in the bay area -- Woodside. It starts on Woodside road at the Woodside school and winds its way through the quiet backroads until you reach Huddart County park. This place is sensational. The path I take follows a creek until it reaches the end and then climbs up and around a ridge. It then winds back down to the creek following a trail surrounded with majestic redwood trees, with the trail being soft underfoot from all of the fallen leaves from all of the trees. I could run there forever. The run then follows the way out to the starting point. It takes about 58min at a pretty good clip. When I lived here with my wife, we'd always do this around mid morning then head off to the Roberts store at Woodside for a Smoked Chicken foccacia for lunch. We'd have it every time we ran at Woodside. As much as I loved being back there this weekend, I missed running next to Jules, and my great mate, Dirty Rickster. He's worth an entire blog on his own.

Today I headed out to another favourite run -- Crystal Springs (or Sawyer Camp trail). It's a paved, marked (every 0.5 mi) trail which has an out and back trail of 6 miles. I took a shorter run today and just went out 3mi and turned around for a total of 6 miles. I ran quite hard today and pleasantly found that I was sitting quite comfortably on around 6:30 min/miles, giving me a total time of 39:15 for the 6 miles. I was very happy with that as my previous best time on that length was 39:46, which was in the midst of marathon training. So I was quite pleased -- pleased enough to go and get sushi and sapporro for dinner.

I have a few busy days at HQ to meet up with all the people I work with, before heading off back to Australia. I am not looking forward to the 15hr leg from SFO to SYD in cattle class. But I'll be stoked to see my little boy Sam and Jules at the airport when I get back.

A trip to Oracle World in San Francisco

I am right in the middle of a visit back to Oracle HQ in Redwood Shores. The primary reason was to participate at Oracle World, but it also provides a good opportunity to hang around for a few days and catch up with the various engineering groups I work with.

Oracle World was a zoo this year. People everywhere. I guess that happens when you pull a few big companies into the fold and incorporate their user conferences into the one event. It's nice to see so many people around.

I didn't get to see any of the big keynotes -- we employees were relegated to booth bunnies, with the lucky ones of us also being able to present a session or two.

This year was quite relaxed for me as I only had one session to present. Normally I have 2 or more to deliver, quite often on a topic which is not core to my heart ... this year I co-shared a session on the new high availibility features we have in our 10.1.3 release. I covered off the new install functions as well as the new state replication framework.

Working on the booth is always a good experience -- we get to speak to all sorts of customers who usually have very interesting questions. I saw one chap this year who was walking around with his laptop all fired up and asking questions about how to get his EJB 3.0 application which he built inside of Eclipse to run on OC4J and work against a SqlServer database. After a bit of a chat he went away and came back a few hours later with it all sorted out -- EJB 3.0 beans running against SqlServer on OC4J. I then showed him which of our Ant tasks enables deployment operations to perform a bind-web operation to map a Web module to a web-site. Since he had Eclipse, it was trivial to add the new task to do the web binding since the Eclipse IDE shows tool-tips for Ant tasks -- it was beautiful to behold.

15 September 2005

An OPMN discovery alternative

Multicast is the basic network infrastructure used when wiring together separate OPMN instances like I’ve been describing in these entries.

When you use opmnctl to configure the OPMN instances to work together, you specify a shared multicast address such as * The * prefix tells OPMN that it works in discovery mode where it will add peers discovered from the shared communication bus, etc.

However if you don't want to use multicast, but still want to use this cool discovery approach to construct the OPMN topology (ie you don't want to use a fully connected OPMN cluster where each instance has a static pointer to each other instance which is hard to maintain) then you can use a slightly different approach.

What you do is to dedicate one specific instance as the discovery node and then configure each instance with the the OPMN address (host:remote_port) of the chosen discovery node. Each instance will then announce itself to the discovery node when it comes online, obtain the details of the other instances from the discovery node itself, and participatge in other various broadcast activities.

How does it work – let’s say I have 3 installs on 3 different servers. Each install has the default OPMN port set since it’s the single install on that server.

felt.au.oracle.com : remote=6200
giant.au.oracle.com : remote=6200
cervelo.au.oracle.com : remote=6200

We'll designate the “giant” server as our discovery node.

To setup a non multicast discovery cluster, you execute opmnctl on each one as follows:

opmnctl config topology update discover="giant.au.oracle.com:6200"

Note the missing "*" from the address and the use of the actual servername (or IP) with the OPMN request port -- instead of a multicast style address:port entry.

This will insert into the opmn.file the relevant entry which defines the giant.au.oracle.com:6200 instance as the discovery node.

Once you have done that on each instance, you should have an OPMN discoverable topology using direct TCP connections. Goodness never tasted so good.

The OPMN server running on the chosen discovery node (ie giant) should be started before any of the others, but besides that, you should then be able to use the this form of cluster in exactly the same way as if you'd used the multicast model.

06 September 2005

Creating JDeveloper connections to OracleAS 10.1.3

Tip on deploying from JDeveloper

Deploying to an OracleAS instance from JDeveloper requires the creation of a connection to the target instance.

Using the Connection wizard, specify the Connection Type to be Oracle Application Server 10g 10.1.3. This ultimately constructs a JSR88 based connection to the desired server.

As you proceed through the connection wizard, step3 will ask you to enter the details of the target instance.

The hostname and OC4J instance name are obvious values.

But what about the OPMN port value? What does that value point at?

Well, what that is asking you for is the port setting for the OPMN request port. Since the OC4J instance is being managed by OPMN, it is OPMN itself that knows that the current port details are for the specified OC4J instance. So this connection model goes through OPMN to get the port values. Thus it requires the value of the OPMN request port*.

The default value used is 6003. Which is fine if you only have one OracleAS installation on the server. But if you have more than one installation, the OPMN request port of the second installation will be different.

In previous versions of the product, the only way to determine the OPMN request port was to actually open up the $ORACLE_HOME/opmn/conf/opmn.xml file for the OracleAS instance you want to connect to, and look at the port attributes in the file.


With the actual 10.1.3 release, we have just implemented** a new opmnctl command to print out the port to use.

>opmnctl status –port

So all you need to do is to execute that command on the OracleAS instance you wish to connect to, and then feed that value into the JDeveloper connection details page.

*: The OPMN request port is a fixed port value defined automatically at install time. It doesn’t change over time. Unlike the actual OC4J RMI port which is allocated dynamically by OPMN when OC4J is started and is therefore subject to change if a port conflict needs to be avoided.

**: This command is not in the current Developer Preview 4 distribution. It will be in the production release.

05 September 2005

Cluster control pattern for opmnctl

Top usage tip for opmnctl

One of our OPMN engineers pointed out a blindingly obvious but very helpful usage pattern for opmnctl the other day. Which I’m dutifully passing on. Thanks Jon.

The opmn service/daemon is responsible for managing a process set within an OracleAS installation. At its simplest it starts/stops and actively monitors processes which make up an OracleAS instance.

As the notion of a cluster has evolved, the concept of a ‘scope’ has been introduced into opmnctl to extend the application of the command to a remote instance or the entire cluster, which I’ll loosely define as the collection of all known instances within the current OPMN topology.

The desired scope is applied as a prefix to the command :

>opmnctl @[cluster|remote]

Common Startup Pattern

A common use pattern is to issue the following command to start an OracleAS instace:

>opmnctl startall

Which causes the OPMN daemon/service itself to start, which then further starts each of the managed processes such as OC4J, Oracle HTTP Server, etc.

Since this use of opmnctl implicitly starts the OPMN daemon/service, it can’t have a scope applied to it.

Refined Startup Pattern

The prior opmnctl use pattern is equivalent to the following operations:

>opmnctl start
>opmnctl startproc

So what, it’s more typing for the same thing, right?

Well maybe.

Where it pays dividends is with the abilility to apply a scope command to the latter command, such as:

>opmnctl @cluster startproc

Or even perform commands on a specific remote instance:

>opmnctl @remote:j2ee_blue.duraace.au.oracle.com stopproc

So once you the OPMN daemon/service is running on each instance (which is a safe assumption in most cases) you can perform a significant set of operational commands across the entire cluster from one command line operation.

Getting used to treating OPMN as a fixed daemon/service provider and then using the scoped commands from opmnctl as a separate task can save you lots of time and effort, allowing you to use opmnctl command against whatever topology you can construct!

31 August 2005

Classloader query framework

With the introduction of the new classloading framework, an advanced diagnostic capability has been added to allow runtime queries to be performed against the current classloader state.

A number of prebuilt-queries are provided.

The query framework can be accessed in two ways.

Command Line Access

From the command line using System properties to specify the query to execute and any parameters to pass to the query.

Try this to see the list of available queries:

>java -Doc4j.start.query=ListQueries+Exit -jar oc4j.jar

To see the current state of the classloader tree for the default application, try this:

>java -Doc4j.start.query=LoaderTree(default.root)+Exit -jar oc4j.jar

+- ascontrol.root:0.0.0
+- test-tl-import.root:0.0.0
| |
| +- test-tl-import.web.web-app-log4j:0.0.0
| |
| +- test-tl-import.web.web-app-log4j.jsp151:0.0.0
+- default.web.defaultWebApp:0.0.0
| +- default.web.defaultWebApp.jsp2152:0.0.0
+- default.web.jmsrouter_web:0.0.0

+- default.web.jmsrouter_web.jsp187:0.0.0

Application Server Control Classloading MBean

Classloading queries can be executed via the Classloading MBean accessible from the System MBean browser available in Application Server Control.

Access the MBean:

Fire up ASC and access the System MBean Browser from the Administration tab.

The ClassLoading > Singleton MBean has an operation called executeQuery.

There are two executeQuery operations. The operation with 2 parameters can be used from this browser MBean client.

Click executeQuery (2) access the invoke operation page.

Invoking the executeQuery operation:

The executeQuery operation page shows the parameters the MBean operation takes.

The first parameter is the fully qualified classname of the query to execute.

All queries are packaged within the oracle.oc4.query package. The actual classname is the name of the query shown with the help page.

The second parameter allows the entry of parameters to be supplied to the query.

To see the state of the current classloader tree for the Default application, and all of it's children use the following parameters

queryClassName: oracle.oc4j.query.LoaderTree
queryArguments: default.root

You can see the list of queries, with a description of each by executing a query using the following parameters.

queryClassName: oracle.oc4j.query.ListQueries

30 August 2005

Classloading in OC4J 10.1.3

Updated 13-Nov-2006:

1. Link to official classloading documentation for
2. Linked to classloading related how-to examples
The classloading implementation in OC4J 10g (10.1.3.x) has been entirely reworked. One of the general goals of the project was to cleanly separate the classloaders used by the OC4J runtime from the classloaders used by applications -- to ultimately provide applications with the freedom to use whatever libraries they require without effecting the overall OC4J runtime.

As part of the new framework, a number of new concepts have been introduced:

1. A new entity called a shared-libary has been added, which enables a set of libraries to be explicitly named and versioned. A named/versioned shared-library can subsequently be made available (imported) to a classloader (an created for an application) so the libraries can be accessed by the application.

2. All the new classloader implementation classes are capable of outputting detailed diagnostic information when classloading errors occur. The diagnostic included detailed such as the names of any missing classes which are attempted to be loaded, where the call was made from and the name/version of any shared-libraries in which the missing class is available.

3. A query mechanism which can be used to extract and display information from the classloaders that are in use. This for example allows the classloader tree to be displayed for a specific application, showing the path from which classes are loaded. The classloader tree also lists all of the code-sources associated with each loader.

A lot of the new classloading framework is documented in the OC4J 10g (10.1.3) Developer's Guide on OTN.

System status using opmnctl

An OracleAS installation contains the Oracle Process Management and Notification (OPMN) server. This server performns a specific task within an OracleAS environment -- it manages (starts/stops) and keeps watch on the processes that are part of OracleAS, performing remediary restart action required when a process experiences a failure.

The OPMN command line utility -- opmnctl -- has a flag which enables various actions to be performed. It also allows the status of the current system to be viewed.

Basic Status

The basic system status (up/down for each managed process) can be obtained using the simple command below.

$>opmnctl status

Processes in Instance: 050825_j2ee_red.duraace.au.oracle.com
ias-component | process-type | pid | status
OC4J | home | 3276 | Alive

Extended Status

A more extended status can be obtained using the "-l" command.

$>opmnctl status -l

Processes in Instance: 050825_j2ee_red.duraace.au.oracle.com
ias-component | process-type | pid | status | uid | mem used | uptime | ports
OC4J | home | 3324 | Alive | 1888158126 | 49152 | 0:00:31 | jms:12601,default-web-site:8888,rmi:12401

Cluster Status

$>opmnctl @cluster status
$>opmnctl @cluster status -l

Processes in Instance: 050825_j2ee_red.duraace.au.oracle.com
ias-component | process-type | pid | status
OC4J | home | 3324 | Alive

Processes in Instance: 050825_j2ee_blue.duraace.au.oracle.com
ias-component | process-type | pid | status
OC4J | home | N/A | Down

Processes in Instance: 050825_http.duraace.au.oracle.com
ias-component | process-type | pid | status
HTTP_Server | HTTP_Server | 2140 | Alive

25 August 2005

The dynamic duo - mod_oc4j and OC4J

With the DP4 release, the mod_oc4j module in Oracle HTTP Server now uses a dynamic mapping approach to expose OC4J web applications.

In previous releases, each OC4J context-root that was to be exposed by OHS required a static entry to be made in the $ORACLE_HOME/Apache/Apache/conf/mod_oc4j.conf file.

Oc4jMount /path ajp13://duraace.au.oracle.com

With the new dynamic model in 10.1.3 , OC4J broadcasts the list of context-root mappings it has to OHS which enables OHS to expose them as they are received.

As OC4Js instances start and stop, or as applications are deployed/undeployed, the mount points are added or removed from OHS with no user intervention required.

This reduces the amount of configuration steps required to deploy applications, and makes the architecure more agile as the mapping changes are done on the fly and don't require the OHS process to be bounced.

You can still use static mount points if you wish, or a combination of both.

The routing mode can specified within the mod_oc4j.conf file. It can specify whether to use only dynamic routing, only the older style static style routing or to do both and default to either dynamic or static in the case of conflicts. By default Dynamic is used.

Oc4jRoutingMode Dynamic (which is the implicit default value)


Oc4jRoutingMode StaticOverride (allows any static bindings to take precedence)

Its possible to configure OHS so that it will display in a HTML page what its current list of mount points are when operating in dynamic mode.

To do this, open up the $ORACLE_HOME/Apache/Apache/conf/mod_oc4j.conf file and add the following bold text between the tags.

<IfModule mod_oc4j.c>
Oc4jSet StatusUri /oc4j-status
</IfModule mod_oc4j.c>

Restart OHS and then access the page using http://host:port/oc4j-status

The resulting page will list all of the mount points OHS currently has from the OC4J instances it is collaborating with.

mod_oc4j Global Configuration

hostname : duraace.au.oracle.com
local instance : 050823_http.duraace.au.oracle.com
select method : Round-Robin
select affinity : None
routing mode : Dynamic
routing ID : g_rt_id

OC4J Dynamic Routing

application : ascontrol
context : /em
process (Jgroup): 0

application : default
context : /jmsrouter, /j2ee
process (Jgroup): 0, 1

OC4J Process List

0 : duraace, 8888, ALIVE
1 : duraace, 8889, ALIVE

Admin user changes in OC4J DP4

Here are another couple of changes to be aware of with the OC4J 10g (10.1.3) Developer Preview release on OTN.

The default administrator username is now oc4jadmin.  In previous releases this was admin.  

The first time initialization routine that OC4J uses has changed so that on the very first startup of OC4J, you will be prompted to specify the password for the oc4jadmin user.  

We no longer ship the product with a password preset for the administrator of the product.  This password setting is only done on the very first startup of OC4J.

In previous releases you could just unzip the oc4j_extended.zip file and run OC4J as we supplied a default password for the admin user of welcome.  

To now change the password that has been set for the oc4jadmin user, you now need to use the j2ee/home/jazn.jar utility.

In previous releases, to change the password for the admin user, you would specify the –install option when starting OC4J, which would prompt you to enter a new password for the admin user.  The –install functionality has been removed from the product.

24 August 2005

Using OracleAS 10.1.3 DP4

There are a couple of changes with the DP4 release which may catch you out .... unless you read the release notes that go along with it of course.

  • The Application Server Control (ASC) console is now mapped to the default-website with a context-root of "/em".

    In the previous DP3 release, ASC was mapped to a separate website and used a context-root of "/asc".

  • We've made the configurations more consistent between the standalone OC4J and the OracleAS OC4J. The most obvious change is that standalone OC4J now uses the "default-web-site.xml" file as its default website.

    Previous releases of standalone have used a different file -- http-web-site.xml.

  • If you download and use the installable version of Oracle Application Server, and perform the "J2EE Server" installation type, you will ultimately get an OPMN managed OC4J instance. This OC4J instance is configured out of the box to run its request listener using HTTP -- so it can be used immediately and without requiring an OHS instance to sit in front of it (although we recommend that and it can be done very easily).

    The gotcha here is that the default URL to access this instance will be


    Note that the port in use here is allocated at install time. It will be "8888" unless the installer detects that it in use, whereupon it will search for another free port to use instead. The end of install text will show you the port that was used.

  • To see all the active ports in use, you can use the opmnctl utility

    $ORACLE_HOME/opmn/bin/opmnctl status –l

    Processes in Instance: test_j2ee


    ias-component| process-type| status|ports

    OC4J | home | Alive |http:8888,jms:12601,rmi:12401

Wiring OHS and OC4J together

With the recent Oracle Application Server 10g (10.1.3) Developer Preview 4 (what a mouthful!) release we put on OTN, it's possible to perform installations which lay down just Oracle HTTP Server or just Oracle Containers for J2EE (OC4J). This provides a finer grained install model than in previous releases, allowing boxes to be dedicated to servicing HTTP requests, and other boxes to be dedicated to hosting J2EE applications and services.

Once you have these two separate installations done, the question is -- how do you wire them together so that the OHS instance can route requests for J2EE applications to the OC4J instance which is hosting them?

Configuration Steps:

Well it's pretty simple really, here's the quick and dirty commands to do it.

OHS Server (or installation if on same box)

Within the OHS server installation directory, execute the following command:

>cd $ORACLE_HOME/opmn/bin
>opmnctl config topology update discover="*"

OC4J Server** (or installation directory if on same box)

Within the OC4J server installation directory, execute the following commands:

>cd $ORACLE_HOME/opmn/bin
>opmnctl config topology update discover="*"
>opmnctl config port update ias-component=OC4J process-type=home portid=default-web-site protocol="AJP"

** do this for each OC4J installation you want to include within this shared group of instances. The single OHS instance can front end multiple OC4J installations.

Brief Explanation:

So what do these commands do?

>opmnctl config topology update discover="*"

What this command will do is to configure the OPMN infrastructure with a common discovery address, enabling the separate installations to discover and communicate with one another. You will note that we execute the exact same command within both installations, with the exact same address. If the address is different, then the two installations will not be able to discover each other.

>opmnctl config port update ias-component=OC4J process-type=home portid=default-web-site protocol="AJP"

On the OC4J installation, this additional command is performed. What this does it to switch the protocol the OC4J instance is using to listen from requests to the AJP protocol, which is used by mod_oc4j to dispatch requests to an OC4J instance. The out of the box OC4J installation will be configured to use the HTTP protocol, enabling it to be accessed and used directly from a browser.

Whenever you want OHS to sit in front of the OC4J instance, you just need to switch the protocol.

Any of the apps which you've deployed and bound to a context-root within your OC4J instance will then be accessible via the OHS URL.

Arrived on blogspot

Trying to revive my old blog out of its deep coma, I discovered that my registration with radio.weblogs had expired and needed renewing.

I hate filing expense reports at the best of times, so after a bit of a hunt around, I established a new home at buttso.blogspot.com.

The old blog postings are still active at http://radio.weblogs.com/0132383 but this site is where any new thoughts will be posted. Beware :-)