SOA/BI Planet - English
I was recently approached by an internal co-worker within Accenture about our teams experience with Extjs. Out of 150,000+ employees in Accenture he was able to find us through Yammer, a free private twitter-like service for companies. Originally I was just going to respond to him via email after our phone conversation, but that would only benefit him. Instead I thought it might be a good idea to share that experience on this blog.

My current team has been using Extjs for about 2 years. I don't consider myself an expert nor do I actually like developing in a language that needs to work in multiple browsers. We started out with version 2.x and late last year converted our projects to version 3, which was no easy task.

I will say Extjs has impressed this Java developer. Their documentation and examples are excellent and feedback on the forums is great. Most of my team didn't have any prior heavy javascript backgrounds and all have been able to come up to speed quickly. Right now I think the biggest drawback is the GPL licensing of version 3. I understand why they did it, but doesn't mean I have to like it.

Extjs Resources
  • Examples - Extjs comes with a nice library of great examples on all kinds of things you can do with Extjs. All the examples also come with the download. One of the neatest examples is the Advanced Grid Filtering. One of the main reasons we upgraded to version 3 was for this feature.
  • API Documentation - The javadoc for extjs. This is the most important and most referenced documentation for any extjs developer. Keep in mind this only shows the most recent version. If you want the API documentation for previous versions, you'll need to download that version of Extjs. The download includes the same API documentation. For local installation or offline reference, there is also a very nice Adobe Air app (see download page).
  • Forums - The forums are very active and we have received a lot of help. We also have purchased the premium support and overall I'd say it was worth it. Especially since we no longer have that goto javascript guru anymore (yeah you know who you are).
  • Community Plugins - It's not huge but between the examples noted above and the community plugins we have been able to reuse a lot and create some neat stuff pretty fast.
  • Blogs - I'd recommend subscribing to the official Extjs blog as well as this search related feed from DZone. And, just because I think it is cool, here is Google Reader bundle I created that captures everything I tag with extjs. Finally, here is a search on my blog about articles I have written about Extjs.
  • Books - According to Amazon there are multiple books out right now about developing with Extjs. I have "Learning Ex JS" by Shea Frederick.
Miscellaneous
  • Javascript/CSS Consolidator - One of the best moves we made was investing in a javascript/css consolidator. Props go out to Joe Kueser for doing this for us. After a few months of development, our application started to grind to a slow crawl as several (80+) javascript and css files where being downloaded. Using the jawr framework we reduced that to around 20 GET requests which improved performance dramatically. Not only does it combine multiple files into one but it also minifies them (removes comments and spaces, etc) and supports gzipping them. I have been very impressed with jawr. It has exceeded our expectations and I would recommend it to anyone.
  • Development Environment - No web developer would be complete without Firefox and Firebug. But for those occansional nasty IE issues I haven't found the perfect solution. In the past I have had some luck with jsdt. Currently I am using IE8 in virutalbox in IE7 mode with it's built in Developer Tools. Although not firebug, it's the closest I have come to find. For those really bad IE6 issues I have used the Internet Explorer Developer Toolbar which beats scattered alerts in your code and is better than nothing.
  • Extjs version 2.x or 3.x - There has been a lot of history surrounding the licensing strategy so I won't go into all of that. Just know that version 2.x is LGPL and can be used or embedded into your applications for free. Version 3.x is GPL which means if your project isn't some internal IT app or also GPL you need to purchase developer licenses.
  • Public Uses - Here are just a few well known sites I have noticed using Extjs: Quicken Online and Dow Jones Industrial Index.
  • jQuery Integration - In case you want to combine jQuery and Extjs you can by using the extjs-jquery-adapter available in the download. I haven't really used jQuery a lot but from what I have read and heard, it's a great javascript library that supports animation and DOM querying. You can do these things in Extjs, but jQuery looks like it might do it better and cleaner. I think Extjs excels in providing out of the box prebuilt and customizable Widgets/Components like the Grid (Table).

For my last blog entry here, I thought I'd post a few links for those wondering where they can get more information about Oracle's plans for Sun's middleware offerings.

Oracle hosted a 5 hour event on Wednesday where executives covered all of the plans for Sun's products at a high level.  You can take a look at all of the webcasts and presentations but for Sun's middleware customers, pay close attention to Thomas Kurian's webcast and presentation.

Subsequently, detailed strategy webcasts were made available providing deeper insight into the strategy and plans including timelines for continued support of existing Sun products.  Those of most interest to Sun's middleware customers will be the Application Server, SOA, Identity Management, and Developer Tools webcasts.

As far as my blogging going forward goes, you'll be able to find me at ktschmidt.blogspot.com.

In the major writeup called “GlassFish ESB v2.2 Field Notes - Exercising Load Balanced, Highly Available, Horizontally Scalable HL7 v2 Processing Solutions”, at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_2_field1, in section called “WS Projects”, pages 35-36 , I discuss how NMProeprties in BPEL 2.0 can be used to force the HTTP BC to send the “connection: close” HTTP header, instead of the “connection: keep-alive” HTTP header, which it sends by default. Normally this does not matter but if a load balancer is to be used as a proxy, and a round robin load balancing is desired, the “connection: keep-alive” gets in the way. Rather then closing a connection after each HTTP request/response, as HTTP protocol was designed to do, “connection: keep-alive” HTTP header indicates to the server that connection is not to be closed in anticipation of another request coming form the same source “shortly”. Since the HTTP BC does not seem to have a place where this header can be removed or changed to “connection: close”, NMProperties in BPEL have to be used to force connection closure and enable correct load balancing behavior.
In the major writeup, now called “CH05_WSSecurityExploration_r0.4.2.pdf”, at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/CH05_WSSecurityExploration_r0.4.2.pdf/details, in section 5.14.3, “Using WS-Addressing for Explicit Routing”, I discuss how WS-Addressing can be used to implement a variant of the “Routing Ticket” EIP Pattern. A one-way web service consumer sends a request to a request/reply web service, indicating, using WS-Addressing, the address of a one-way web service to which to send the response. 
As I develop bigger prices of work, which have writeups associated with them, I inevitably have to solve small problems that crop up. The problems I solve I typically get written about in the corresponding writeup but may be missed by these who might need these kinds of solutions but who don’t have an interest in the major piece. For example, when writing about the HL7 HA solution, “GlassFish ESB v2.2 Field Notes - Exercising Load Balanced, Highly Available, Horizontally Scalable HL7 v2 Processing Solutions”, at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_2_field1, I had to work what host the instance of the business process was using and how to make the process instance wait for a random amount of time. I did separate writeups on these as “GlassFish ESB v2.1 - Using JavaScript Codelets to Extend BPEL 2.0 Functionality”, at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_1_using, and “GlassFish ESB v2.1 Field Notes - JavaScript Codelets to Make BPEL Process Wait for a Random Duration Up to a Maximum number of Milliseconds”, at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_1_field.

Here I call reader’s attention to the problem of reading values of SOAP Headers in a BPEL 2.0 process. I discussed one method in “Java CAPS 5 / 6, OpenESB, GlassFish ESB - Handling SOAP Headers in BPEL”, at http://blogs.sun.com/javacapsfieldtech/entry/java_caps_5_6_openesb. In the major writeup, now called “CH05_WSSecurityExploration_r0.4.2.pdf”, at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/CH05_WSSecurityExploration_r0.4.2.pdf/details, I am discussing, in passing, in Section 5.14.2, “Interacting with WS-Addressing Headers in BPEL”, a method that uses Normalized Message Properties (NMProperties) in BPEL 2.0, to access SOAP headers. While this piece discusses how to access WS-Addressing SOAP headers it is equally applicable to other SOAP headers. Similarly, in section 5.14.3, “Using WS-Addressing for Explicit Routing”, I discuss how arbitrary SOAP headers can be added and populated using NMProperties in BPEL 2.0. So if you need to manipulate SOAP header in BPEL 2.0, have a look a these sections.

The writeup, CH05_WSSecurityExploration_r0.4.2.pdf, is available at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/CH05_WSSecurityExploration_r0.4.2.pdf/details
Don't envy me..........Your about to witness my efforts from the past 2-3 weeks.

For the past week I have been trying to get precompiled JSPs working for WebSphere 6.1, because our target environment does not include the Java Development Kit (JDK) for security reasons. The following is a brief explanation on how to precompile JSPs for WebSphere 6.1 using maven2. And as an added bonus, I'll also explain how to use the maven-was6-plugin to automate deployment of a WAR using Jython.

Precompiling JSPs for WebSphere
First off, let me say, this was not fun. I spent a ton of time trying to figure out why the precompiled JSPs worked on JBoss 4.2.1, but not WebSphere 6.1. Both maven jspc plugins (jspc-maven-plugin and maven-jetty-jspc-plugin) produced precompiled JSPs that worked on JBoss, but not WebSphere. From what I could tell it all boiled down to the fact that JBoss 4.2.1 includes the 2.1 version of jsp-api while WebSphere 6.1.0.27 includes the 2.0 version. Just so you believe me, the 2 conflicting jars in WebSphere were: $WAS_HOME/lib/j2ee.jar and $WAS_HOME/plugins/com.ibm.ws.webcontainer_2.0.0.jar. On the plus side, I did find a great Java decompiler for linux called jd-gui. I'd highly recommend it for any operation system. It uses jad, but provides a nice GUI interface that even lets you open a jar and explore any .class file.

In summary, based on my experience, the 2 existing maven jspc plugins do not create compatible precompiled JSPs with WebSphere 6.1.0.27. Surprisingly, the solution that ended up working was using the JspBatchCompiler.sh script that comes with WebSphere.

The JspBatchCompiler.sh was exactly what we needed. Thankfully, you can give this script a WAR or EAR file and it will explode it, precompile all the JSPs, and repackage it back up again. This script is located under $WAS_HOME/bin. Once I verified it by manually running the script, the next step was to automate it using maven. Since I wasted so much time figuring everything else out, I didn't spend a ton of time improving the maven portion. Instead I decided to go with what I knew and that was using the exec-maven-plugin to run the script. The following is the profile I used to precompile the JSPs in the WARs located in the EAR.



<profile>
<id>precompile</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>precompile-was-ear-jsps</id>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${wasHome}/bin/JspBatchCompiler.sh</executable>
<arguments>
<argument>-ear.path</argument>
<argument>${pom.basedir}/target/${project.artifactId}-${project.version}.${project.packaging}</argument>
<argument>-jdkSourceLevel</argument>
<argument>15</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>rename-replace-was-ear</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<move file="${java.io.tmpdir}/${project.artifactId}-${project.version}.${project.packaging}"
tofile="${pom.basedir}/target/${project.artifactId}_jspc-${project.version}.${project.packaging}"/>
<delete file="${pom.basedir}/target/${project.artifactId}-${project.version}.${project.packaging}"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
The first plugin section uses the exec-maven-plugin to run the JspBatchCompiler.sh and takes the EAR as input. The second plugin section uses the maven-antrun-plugin to basically rename the EAR to include a keyword (_jspc) in the EAR filename so everyone knows when they have an EAR with precompiled JSPs. It then moves the new EAR from it's tmp location back to the modules target directory where everything expects it to be. Once that is done, it removes the old EAR to avoid confusion.

About the only improvement that could be made is making it portable to other Operating Systems like Windows. This "could" be accomplished by using the JspC ant task WebSphere provides, but I couldn't find any good examples of how to do that via maven, so I took a rain check.

Deploy WAR to WebSphere 6.1
This Jython code snippet literally saved our sprint. I am not sure how I would have automated deploying and undeploying a WAR via maven without it as the maven-was6-plugin really only works with EARs. This is because when deploying a WAR you need to provide the WARs contextroot, which the plugin currently doesn't support (MWAS-59). I was however able to call the Jython script from the maven-was6-plugin to undeploy and deploy a WAR.

The following profiles and Jython scripts show how to use maven and Jython to undeploy and deploy a WAR. The Jython scripts exist in files under the same directory as the pom.



<profile>
<id>undeploy-war</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>was6-maven-plugin</artifactId>
<executions>
<execution>
<id>undeploy</id>
<phase>validate</phase>
<goals>
<goal>wsAdmin</goal>
</goals>
</execution>
</executions>
<configuration>
<wasHome>${wasHome}</wasHome>
<profileName>AppSrv01</profileName>
<conntype>SOAP</conntype>
<applicationName>petstore_war</applicationName>
<earFile>${pom.basedir}/target/petstore.war</earFile>
<updateExisting>false</updateExisting>
<language>jython</language>
<script>uninstallApp.py</script>
<host>localhost</host>
</configuration>
</plugin>
</plugins>
</build>
</profile>

# File: uninstallApp.py
# Jython script to undeploy WAR
# FYI, the was6 plugin does support the ability to pass in params to the jython script
cellName = 'testbed01Node01Cell'
nodeName = 'testbed01Node01'
serverName = 'server1'

#Install the app
print "Installing App: "
AdminApp.install("../petstore.war", "-contextroot /petstore -defaultbinding.virtual.host default_host -usedefaultbindings");
AdminConfig.save();

#Start the app
apps = AdminApp.list().split("\n");
theApp = ""
for iApp in apps:
if str(iApp).find("petstore") >= 0:
theApp = iApp;
print "Starting App: ", theApp
appManager = AdminControl.queryNames('cell='+cellName+',node='+nodeName+',type=ApplicationManager,process='+serverName+',*')
AdminControl.invoke(appManager, 'startApplication', theApp)
print "Application installed and started successfuly!"

Here is the profile and Jython script I used to Deploy a WAR:


<profile>
<id>deploy-war</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>was6-maven-plugin</artifactId>
<executions>
<execution>
<id>deploy</id>
<phase>validate</phase>
<goals>
<goal>wsAdmin</goal>
</goals>
</execution>
</executions>
<configuration>
<wasHome>${wasHome}</wasHome>
<profileName>AppSrv01</profileName>
<conntype>SOAP</conntype>
<applicationName>petstore_war</applicationName>
<earFile>${pom.basedir}/target/petstore.war</earFile>
<updateExisting>false</updateExisting>
<language>jython</language>
<script>installApp.py</script>
<host>localhost</host>
</configuration>
</plugin>
</plugins>
</build>
</profile>
# File: installApp.py
# Jython script to deploy WAR
# FYI, the was6 plugin does support the ability to pass in params to the jython script
cellName = 'testbed01Node01Cell'
nodeName = 'testbed01Node01'
serverName = 'server1'

#Install the app
print "Installing App: "
AdminApp.install("../petstore.war", "-contextroot /petstore -defaultbinding.virtual.host default_host -usedefaultbindings");
AdminConfig.save();

#Start the app
apps = AdminApp.list().split("\n");
theApp = ""
for iApp in apps:
if str(iApp).find("petstore") >= 0:
theApp = iApp;
print "Starting App: ", theApp
appManager = AdminControl.queryNames('cell='+cellName+',node='+nodeName+',type=ApplicationManager,process='+serverName+',*')
AdminControl.invoke(appManager, 'startApplication', theApp)
print "Application installed and started successfuly!"

That's it. The Jython scripts could be improved by making the cell, node, and server names configurable instead of hardcoded and it "appears" the maven-was6-plugin supports passing in properties, but I just didn't have the time to figure it out at the moment.

By the way, I hope maven 3 has solved the XML verbosity when it comes to doing simple things like creating profiles. That's a lot of XML to do very little.

So, Oracle we are then.

If you are interested in trying out the Oracle SOA Suite from the perspective of someone who is familiar with GlassFish ESB, then attached are several documents which will get you started....

The idea is to create & run your first Oracle SOA Suite project using a familiar GFESB scenario, in fact this is based on the GlassFish ESB HA project that formed part of the recently released document....

1. Create an EJB Webservice

2. Create a BPEL process to call this WebService

3. Use an Oracle Adapter - here we use the database adapter.

4. Add some correlation to the BPEL project. 

 Enjoy !

 PS. you'll need to have Oracle SOA Suite installed beforehand, there are plenty of documents out there on the web that explain how to do this fully.

In the blog entry "GlassFish ESB v2.2 Field Notes - Exercising Load Balanced, Highly Available, Horizontally Scalable HL7 v2 Processing Solutions", at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_2_field1, I present the GlassFish ESB v2.2-based load balanced, highly available, horizontally scalable solution for HL7 v2.x delimited messaging, using both the HL7 Binding Components, Web Services and JMS in request/reply mode. The one and a half hour recording of me discussing and demonstrating this solution is available as a Flash Movie (SWF), "GFESB_LB_HA_Demo_Session SWF " at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/GFESB_LB_HA_Demo_Session_SWF/details  (62.7Mb download)

In this document I explore the effects of selected web services security policies on SOAP message exchange in the GlassFish ESB v2.x.

This is a work-in-progress document, now at rev 0.4.1.

To provide early access I intend to release revisions of this document as significant new sections become available.

Rev 0.1: Content
•    Assumptions and Notes
•    Person Service XML Schema and WSDL Interface
•    Common XML Project
•    PersonSvc BPEL Module
•    PersonCli BPEL Module
•    JBI-based Person Service – Plain End-to-End
•    JBI-based Person Service – SSL with Server-side Authentication

Rev 0.2: Additional Content
•    JBI-based Person Service – SSL with Mutual Authentication (broken)
•    EJB-based Person Service – No security
•    EJB-based Person Service – SSL with Server-side Authentication

Rev 0.3: Additional Content
•    EJB-based Person Service – SSL with Mutual Authentication
•    JBI-based Person Service - Exploring WS-Addressing

Rev 0.4: Additional and Changed Content
•    Modified sections 5.8 and 5.9 (SSL Server side and mutual authentication)
•    Using WS-Addressing for Explicit Dynamic Routing
•    Pre-requisite Cryptographic Objects [TBC]
•    Upgrading Metro to version 1.5 [TBC]
•    Username Token Profile 1.0 (2004) Policy [TBC]

More in CH05_WSSecurityExploration_r0.4.1.pdf at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/CH05_WSSecurityExploration_r0.4.1.pdf/details

The archive, CH05_WSSecurityExploration_r0.4.1.zip, containing all projects developed so far is to be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/CH05_WSSecurityExploration_r0.4.1.zip/details.


Bay BridgeThe new OpenMQ 4.4 release has been eagerly looked forward to by myself and some of my customers for it's ability to bridge brokers without requiring a custom application to consume messages and forward it to a different broker.

In the current setup at one of my customers we have a MQ HA cluster in one network segment and a single MQ node in a different network segment.

Two Composite Applications were made, one on each side, to consume messages and forward it to the node(s) in the other network segment.
The CA consumes messages from a number of destinations (typically queues) and wraps them as a payload in a common container message. This is functionality that we decided we'd do without, instead settling on just straight destination to destination forwarding.

Of course this functionality can be kept, by simply introducing a bridge from the CA's target destination to the corresponding target destination on the other side, thus allowing us to remain unaware on the destination to destination mapping needs in the different network segment.

As we decided to to without the source-> target mapping awareness it allowed us to simplify our deployment and remove the two Bridge CAs entirely.
There are several advantages with this setup:

  • Lower overhead of message passing, no longer would we require a message to be consumed from a queue, de marshaled, inspected, wrapped and passed.
  • Lower footprint on the application servers, doing without two CAs and their associated interfaces and requirements should lower the memory and performance footprint.
  • Easier maintenance, it's way easier to introduce a new link in a Bridge configuration than maintain the increasingly complex composite applications.

As a sub-concequence of this the integration applications are less aware on the topology of the network they're deployed in,  Composite applications consume and deliver messages to destinations, the broker arranges for the interconnectivity between  nodes thus allowing the CAs to be unaware of the location of different subsystems.

Illustration of the BPEL of one of the Bridge composite applications:

Bridge BPEL

So in having settled for using the new MQ 4.4 bridge it's time to introduce the Bridge.

The documentation is on http://docs.sun.com, more specific; Sun Glassfish Message Queue 4.4u1

Some definitions:
Bridge: A service in a broker that consumes messages from one destination and delivers them to a different destination.  Destinations in separate brokers can be bridged as well as internally in a broker. Bridges are managed by the imqbridgemgr  utility.
The Bridge service is JMS 1.1 compliant, supports JNDI administrative objects, uses connection factories of type javax.jms.ConnectionFactory or javax.jms.XAConnectionFactory.
Each broker supports multiple (uniquely named) bridges with separate configuration and life cycles.
Link: In a bridge this is a mapping between two destinations. Links are unidirectional.
Although I won't discuss it here Links also support Message Transformers, allowing you to transform a message prior to delivery by extending  com.sun.messaging.bridge.service.MessageTransformer<T,S> Complete API JavaDoc,
Object Store: This is a store for Administered Objects, objects that encapsulate provider specific configuration and naming  information. This is where a node will store the Connection Factory for itself and the node it will send messages to.
Two different kinds exist, File (which I'll use) and LDAP.
Cluster: Groups of brokers working together to provide delivery services to clients. Clusters allow a message service to  scale its operations to meet an increasing volume of message traffic by distributing client connections among multiple brokers.
A non-HA (also known as a conventional cluster) cluster provides message-service availability.
HA Cluster: Also known as an enhanced cluster. If a broker fails clients connect to a different broker in the cluster, which  performs a takeover of the work the failed broker was involved in, and delivers messages uninterrupted to the clients.  Enhanced clusters provide message and service availability.
The persistent message store for an enhanced cluster is maintained on a HA JDBC database. MySQL Cluster Edition  (5.1.39-ndb-7.0.9), High Availability Session Store (HADB) (4.4.2, 4.5, 4.6) or Oracle Real Application Clusters (RAC) (10g  and 11g) are supported.

Ok, next for the actual setup.


Please excuse my poor Inkscape drawing abilities, I sort of stopped drawing after  moving away from DeluxePaint
For my setup the cluster nodes in c1 was run on one machine, but the broker's control port (cp, the portmapper ) and message port (mp) are  bound to distinct ports. (Easier on firewall administrator's minds :) and to separate the processes from interfering with each other's ports
Each broker in C1 hosts one uniquely named bridge, but each bridge instance reads messages from the same destination name to ensure redundancy if one broker and it's bridge fails.
The drawing above also does not show the bridge from c2 to c1, this is detailed below.
c2 is in my setup comprised of one single node c2b1, but can easily be expanded to multiple nodes by repeating the setup that is done for c1


Setup
Download and install OpenMQ from https://mq.dev.java.net
Please note that the installer requires a 32bit JDK, I did this on a 64bit machine, to get the installer running install a 32bit jdk and set $JAVA_HOME to the 32bit one. The actual JDK to run the broker is selected during the install process and it may be any available JDK
For my install I did:
export JAVA_HOME=export JAVA_HOME=/usr/java/jdk1.5.0_15/ (set to wherever you have your 32bit JDK)

If you see something like:
java.lang.UnsatisfiedLinkError: /root/mq44/openmq4_4-installer/install/lib/external/charva/Unix/Linux/i386/libTerminal.so:  /root/mq44/openmq4_4-installer/install/lib/external/charva/Unix/Linux/i386/libTerminal.so: wrong ELF class: ELFCLASS32  (Possible cause: architecture word width mismatch)
       at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1778)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1703)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1030)
        at charva.awt.Toolkit.<clinit>(Toolkit.java:895)
        at charva.awt.Window.init(Window.java:62)
        at charva.awt.Window.<init>(Window.java:58)
        at charva.awt.Frame.<init>(Frame.java:32)
        at charvax.swing.JFrame.<init>(JFrame.java:34)
        at charvax.swing.JFrame.<init>(JFrame.java:30)
        at org.openinstaller.util.ui.ChaxStandaloneSplash.<init>(ChaxStandaloneSplash.java:91)
        at org.openinstaller.core.Orchestrator.main(Orchestrator.java:428)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.openinstaller.core.EngineBootstrap.main(EngineBootstrap.java:208)
SEVERE INTERNAL ERROR: /root/mq44/openmq4_4-installer/install/lib/external/charva/Unix/Linux/i386/libTerminal.so:  /root/mq44/openmq4_4-installer/install/lib/external/charva/Unix/Linux/i386/libTerminal.so: wrong ELF class: ELFCLASS32  (Possible cause: architecture word width mismatch)


You're using a 64bit JDK (verify with java -version and you'll see something like: java version "1.6.0_11" Java(TM) SE Runtime Environment (build 1.6.0_11-b03) Java HotSpot(TM) 64-Bit Server VM (build 11.0-b16, mixed mode)

As I installed on a headless machine I ran the installer with ./installer -t this provides a text driven wizard.
In the installer I set the install home to /opt/sun/mq44, selected the 1.6.0_11 JDK I had available.


After installing OpenMQ on the two different machines I'd be using I started and stopped to brokers to get them to create the  initial directory layout for the different nodes.

For machine A, which will be running c1
cd /opt/sun/mq44/mq/bin
./imqbrokerd -name c1b1 -port 7777
and ./imqbrokerd -name -c1b1 -port 8888
and on the macine running c2
./imqbrokerd -name -c1b1 -port 7777


The first thing I did was to set up the object stores for the different brokers. This is done using imqobjmgr I also created a directory to hold the object stores (I'm using a file based object store, not an LDAP based one)

On c1:
mkdir /opt/sun/mq44/var/mq/instances/c1b1/c1b1_os
mkdir /opt/sun/mq44/var/mq/instances/c1b2/c1b2_os

note that parts of the DNS names for the machines have been obfuscated using # signs.
On c1b1:
./imqobjmgr add -t xcf -j "java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory" -j  "java.naming.provider.url=file:///opt/sun/mq44/var/mq/instances/c1b1/c1b1_os" -o  "imqAddressList=int-dev02.###.########.##:7777" -o "imqAddressListBehavior=RANDOM" -o  "imqBrokerHostName=int-dev01.###.########.##" -o "imqBrokerHostPort=7777" -o "imqReconnectEnabled=true" -o  "imqAddressListIterations=-1" -l c2b1cf
On c1b2:
./imqobjmgr add -t xcf -j "java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory" -j  "java.naming.provider.url=file:///opt/sun/mq44/var/mq/instances/c1b1/c1b1_os" -o  "imqAddressList=int-dev02.###.########.##:7777" -o "imqAddressListBehavior=RANDOM" -o  "imqBrokerHostName=int-dev01.###.########.##" -o "imqBrokerHostPort=8888" -o "imqReconnectEnabled=true" -o  "imqAddressListIterations=-1" -l c2b2cf
On c2b1:
./imqobjmgr add -t xcf -j "java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory" -j  "java.naming.provider.url=file:///opt/sun/mq44/var/mq/instances/c2b1/c2b1_os" -o  "imqAddressList=int-dev01.###.########.##:7777,int-dev01.###.########.##:8888" -o "imqAddressListBehavior=RANDOM" -o   "imqBrokerHostName=int-dev01.###.########.##" -o "imqBrokerHostPort=7777" -o "imqReconnectEnabled=true" -o  "imqAddressListIterations=-1" -l c1b1b2cf
note that on c2b1 the value of the property for imqAddressList is  int-dev01.###.########.##:7777,int-dev01.###.########.##:8888 this is a , separated list of the nodes in the HA cluster.

Next up is the bridge definitions. A bridge and it's links is owned by one broker. For c1 this means we have to create one bridge in each of the instances. A bridge have to be uniquely named across a cluster,  but there is nothing that stops you from consuming messages from the same destination(s) in both bridge instances. (As a side  note, and I tested it on 4.4RC1 you can also create a simple load balancer in the bridge service by having a link that sends to multiple targets on different machines)
Bridge definitions are described in an XML file, the Bridge service settings, and the link to the bridge definition XML file(s) are in the broker's config.properties file.
Here's the bridge definition for c1b1. I have annotated it with some comments to the different parts:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jmsbridge SYSTEM "sun_jmsbridge_1_0.dtd">
<!--
   Copyright  2000-2008 Sun Microsystems, Inc.  All rights reserved.
   Use is subject to license terms.
-->
<jmsbridge name="c1_to_c2">     <!-- name must be unique within a cluster, one broker owns the instance -->
<!-- the link is what connects the destinations -->
    <link name="initial_link" enabled="true" transacted="true">
        <source connection-factory-ref="c1b1b2cf" destination-ref="src_dst_ref">
        </source>
        <target connection-factory-ref="c2b1cf" destination-ref="trg_dst_ref">
        </target>
    </link>
    <connection-factory ref-name="c1b1b2cf" />
    <connection-factory ref-name="c2b1cf" lookup-name="c2b1cf"> <!-- this is the connection factory created in the object  store -->
        <property name="java.naming.factory.initial"
              value="com.sun.jndi.fscontext.RefFSContextFactory"/>  <!-- using the file jndi service provider -->
        <property name="java.naming.provider.url" value="file:///opt/sun/mq44/var/mq/instances/c1b1/c1b1_os"/>  <!-- where is  the file structure located on disk -->
    </connection-factory>
    <destination ref-name="src_dst_ref" name="sourcedest" type="queue"> <!-- using physical destination names -->
    </destination>
    <destination ref-name="trg_dst_ref" name="targetdest" type="queue">
    </destination>
</jmsbridge>

For c1b2:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jmsbridge SYSTEM "sun_jmsbridge_1_0.dtd">
<!--
   Copyright  2000-2008 Sun Microsystems, Inc.  All rights reserved.
   Use is subject to license terms.
-->
<jmsbridge name="c1b2_to_c2">
    <link name="initial_link" enabled="true" transacted="true">
        <source connection-factory-ref="c1b1b2cf" destination-ref="src_dst_ref">
        </source>
        <target connection-factory-ref="c2b1cf" destination-ref="trg_dst_ref">
        </target>
    </link>
    <connection-factory ref-name="c1b1b2cf" />
    <connection-factory ref-name="c2b1cf" lookup-name="c2b1cf">
        <property name="java.naming.factory.initial"
              value="com.sun.jndi.fscontext.RefFSContextFactory"/>
        <property name="java.naming.provider.url" value="file:///opt/sun/mq44/var/mq/instances/c1b2/c1b2_os"/>
    </connection-factory>
    <destination ref-name="src_dst_ref" name="sourcedest" type="queue">
    </destination>
    <destination ref-name="trg_dst_ref" name="targetdest" type="queue">
    </destination>
</jmsbridge>


Notice that save for the bridge name it is identical to c1b1. This is because a bridge instance is owned by one broker. For failover if c1b1 goes down it reads the same destinations.
To complete the picture here is the bridge definition for c2b1:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jmsbridge SYSTEM "sun_jmsbridge_1_0.dtd">
<!--
   Copyright  2000-2008 Sun Microsystems, Inc.  All rights reserved.
   Use is subject to license terms.
-->
<jmsbridge name="c2_to_c1">
    <link name="initial_link" enabled="true" transacted="true">
        <source connection-factory-ref="c2b1cf" destination-ref="src_dst_ref">
        </source>
        <target connection-factory-ref="c1b1b2cf" destination-ref="trg_dst_ref">
        </target>
    </link>
<!--
   This connection factory creates connections to the broker that
   this jmsbridge is running in
-->
    <connection-factory ref-name="c2b1cf" />
    <connection-factory ref-name="c1b1b2cf" lookup-name="c1b1b2cf">
        <property name="java.naming.factory.initial"
              value="com.sun.jndi.fscontext.RefFSContextFactory"/>
        <property name="java.naming.provider.url" value="file:///opt/sun/mq44/var/mq/instances/c2b1/c2b1_os"/>
    </connection-factory>
    <destination ref-name="src_dst_ref" name="sourcedest" type="queue">
    </destination>
    <destination ref-name="trg_dst_ref" name="targetdest" type="queue">
    </destination>
</jmsbridge>


Now that the bridges are created it's time to do the necessary changes in the broker's props/config.properties files
Ideally for c1 and c2 the properties common to the cluster should be split into a separate cluster configuration file that is accessible for both brokers, either through a shared file system or some other mechanism. I have not done this here, I'll  leave it as an exercise for you if you want to do this.

Next up is the properties for the brokers themselves;

config.properties for c1b2:
#bridge properties imq.bridge.enabled=true
imq.bridge.admin.user=admin
imq.bridge.admin.password=admin
imq.bridge.c1b2_to_c2.type=jms
imq.bridge.c1b2_to_c2.autostart=true
#this is where i put the XML file containing the Bridge declaration
imq.bridge.c1b2_to_c2.xmlurl=file\:///opt/sun/mq44/var/mq/instances/c1b2/props/c1b1b2bridge_2.xml
#which bridge does this broker instance own, do not move to common cluster properties file
imq.bridge.activelist=c1b2_to_c2
#database persistence (see later section on configuration)
imq.persist.store=jdbc
imq.persist.jdbc.dbVendor=oracle
imq.persist.jdbc.oracle.needpassword=true
imq.persist.jdbc.oracle.property.url=jdbc\:oracle\:thin\:@############.###.########.##\:1521\:devdb
imq.persist.jdbc.oracle.user=cluster1
#cluster properties
imq.cluster.transport=tcp
imq.cluster.brokerlist=int-dev01.###.########.##\:8888,int-dev01.###.########.##\:7777
imq.cluster.ha=true
imq.cluster.hostname=int-dev01.###.########.##
imq.cluster.clusterid=c1
#misc properties
imq.brokerid=c1b2
# binds the jms transfer to one port. Advantageous for firewalls :)
imq.jms.tcp=8889
#changes the portmapper to 8888 from the default 7676
imq.portmapper.port=8888
imq.instanceconfig.version=300
#JMX properties
# I want this broker to set up an RMI enabled JMX connector
#The JMX service URL is shown if you do ./imqcmd list jmx
#use the service url to connect from a client, like JConsole or code.
imq.jmx.connector.activelist=jmxrmi
imq.jmx.rmiregistry.use=true
imq.jmx.rmiregistry.start=true
imq.jmx.rmiregistry.port=8899


The properties for c1b1 are identical, except to the port numbers used and the imq.brokerid property. Also refer to the Bridge instance c1_to_c2 that c1b1 will host.
Same for c2b1, the path to follow should be clear. For c2b1 also the imq.cluster.* properties are left out as it is not running in a cluster.
The properties file above also shows how to change the broker's persistence model from the default file based model to JDBC as well as how to enable JMX connectivity for the broker.


To create the database tables necessary after you've added the persistence configuration you can either use the imqdbmgr utility or simply start the brokers which auto creates the tables,
For the HA cluster the tables need an update.
Create tables:
./imqdbmgr create tbl -b c1b1 (no need for c12b)
and
./imqdbmgr upgrade hastore -b c1b1
The jar file for the oracle drivers (the exact jar varies with the JDK you use and db version) should be placed in mq/lib/ext

To start the brokers use the -name switch to start the correct instance.
c1b1:
./imqbrokerd -name c1b1
c1b2:
./imqbrokerd -name c1b2
And on c2b1
c1b1:
./imqbrokerd -name c2b1

To verify functionality and easily inject large numbers of differently sized messages into the broker setup you can use the uclient utility which ships in the demo directory in the broker installation

Once in a while a problem pops up with how a middleware stack supports XA. The problem I'm discussing here is the one of how to exactly enlist and delist XAResource-s with isSameRM()returning true. The XA spec is vague on this very topic, so this warrants some exploration.

First of all, what do I mean with "enlist and delist XAResource-s with isSameRM()returning true?"

Enlisting and delisting

When using an XA capable system, the connection needs to be enlisted in the transaction before it is used. A typical sequence on the XAResource, let's call it r1, is:

   1: r1.start(xid, TMNOFLAGS);
   2: ... // use (r1)
   3: r1.end(xid, TMSUCCESS);
   4: r1.commit(xid, true);

With a second resource in the mix, the call sequence may become:

   1: r1.start(xid1, TMNOFLAGS);
   2: ... // use r1
   3: r2.start(xid2, TMNOFLAGS);
   4: ... // use r2
   5: r2.end(xid2, TMSUCCESS);
   6: r1.end(xid1, TMSUCCESS);
   7: r1.prepare(xid1);
   8: r2.prepare(xid2);
   9: p1.commit(xid1, false);
  10: p2.commit(xid2, false);

The transaction is now escalated to a full two-phase transaction. But if r1 and r2 represent the same resource manager, a shortcut can be taken: one resource can "piggy back ride" on the other resource. The isSameRM() method can be used to check if this should be attempted. If it returns true, the sequence may become:

   1: // MULTIPLE ACTIVE
   2: r1.start(xid, TMNOFLAGS);
   3: r1.isSameRM(r2); // returns true
   4: r2.start(xid, TMJOIN);
   5: r2.end(xid, TMSUCCESS);
   6: r1.end(xid, TMSUCCESS);
   7: r1.commit(xid, true);

The transaction now again is a single-phase transaction, and the performance difference with the two-phase commit case is usually very significant.

This sequence doesn't work for a number of popular systems, e.g. MQSeries and Oracle. Unfortunately the XA specification, but that specification is not quite clear at all about what resource managers should be able to do, so there is to some extent some trial and error involved.

Trial and error

How should isSameRM() be used then? By testing a number of different systems, it turns out that for some systems, there can be only one enlisted XAResource active in the transaction. If a second XAResource joins the transaction, the first one should be deactivated. Here is an example:

   1: // SINGLE ACTIVE 1
   2: r1.start(xid, TMNOFLAGS);
   3: r1.isSameRM(r2); // should return true
   4: ... // use r1
   5: r1.end(xid, TMSUSPEND);
   6:  
   7: r2.start(xid, TMJOIN);
   8: ... // use r2
   9: r2.end(xid, TMSUCCESS);
  10:  
  11: r1.start(xid, TMRESUME);
  12: ... // use r1 again
  13: r1.end(xid, TMSUCESS);
  14:  
  15: r1.commit(xid, true);
A variation of this is calling TMSUCCESS instead of TMSUSPEND. In that case TMJOIN should be called instead of TMRESUME:
   1: // SINGLE ACTIVE 2
   2: r1.start(xid, TMNOFLAGS);
   3: r1.isSameRM(r2); // should return true
   4: ... // use r1
   5: r1.end(xid, TMSUCCESS);
   6:  
   7: r2.start(xid, TMJOIN);
   8: ... // use r2
   9: r2.end(xid, TMSUCCESS);
  10:  
  11: r1.start(xid, TMJOIN);
  12: ... // use r1 again
  13: r1.end(xid, TMSUCESS);
  14:  
  15: r1.commit(xid, true);
I ran these tests on a number of systems, and here is what I found:
  isSameRM() Test: multiple active Test: single active 1 Test: single active 2
STCMS yes yes yes yes
JMQ as of 4.4 yes no: throws on line 7 yes
WebSphereMQ 6 yes no: blocks on line 4 no: blocks on line 7 yes
Derby 10.5.3.0 yes no: blocks on line 4 yes yes
Oracle 11.1.0.6 yes no: blocks on line 4 yes yes
MySQL 5.1 yes no: throws on line 4 no: throws on line 5 no: throws on line 7

As can be seen, the SINGLE ACTIVE 2 code sequence works best.

As a side note, MySQL is showing surprising behavior: TMJOIN and TMSUSPEND are not supported (as documented in the MySQL documentation), so why does it bother to return true on isSameRM()? Behavior like this makes it difficult to write portable code: a container now has to provide a wrapper around the DataSource that corrects for this. It would have been much better if it simply had returned false on isSameRM().

How does this relate to what application code can do in for instance a Java EE container? That's the topic of a different blog post.


I have a problem: The DZone Top Links section is great but doesn't support an RSS feed. It has feeds for just about everything else. This would be like digg or tweetmeme not having a feed for their most popular links. What makes it worse is I read a majority of their Top Links, but in order to do so I have to keep a tab open in firefox. Wouldn't it be great if I could just subscribe via Google Reader? And now thanks to Yahoo Pipes's screen scrapping capability you can.

Click this link to subscribe to the DZone Top Links Feed: http://pipes.yahoo.com/jlorenzen/dzonetoplinks.

This was accomplished by cloning my RssHuskerPedia pipe and changing a few things around. These pipes depend on the Fetch Page module which essentially lets you scrap the page allowing you to create a list. This feed doesn't contain all the metadeta that would normally come from an official DZone feed, but it supports the basics and prevents me from missing great articles that I would have normally missed.

Please vote this up on DZone to get the word out and hopefully DZone will create an official one. If it gets voted up enough and makes it to the Top Links section, hopefully you won't get stuck in an infinite loop.
The HL7 v2 standard mandates the use of acknowledgments to ensure message delivery, critical in Healthcare. There are the “Original Mode” acknowledgements and “Enhanced Mode” acknowledgements. Within the enhanced mode acknowledgements there are “Accept Acknowledgements” and “Application Acknowledgements”.

This Note walks through development of two BPEL Module-based solutions that cooperate in generating and processing Enhanced Accept Acknowledgements using HL7 v2.3.1 messages. This discussion should apply to any v2.x, greater then v2.2, where the Enhanced Mode acknowledgements were introduced. In addition, the solutions are used to illustrate receiving HL7 BC ACK generation, when receiving an invalid HL7 message.

The Note, Processing_Explicit_HL7_AcceptAcks_v1.0.0.0.pdf, can be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/Processing_Explicit_HL7_AcceptAcks_v1.0.0.0.pdf/details.
The associated GlassFish ESB v2.2 Projects, HL7EA_Projects.zip, can be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/HL7EA_Projects.zip/details.

By popular demand, the sources of the Regular Expression Editor I discussed in a previous post, is now available on code.google.com.

image

A few months ago I got a request from Satadru Roy, one of the authors of the book "SOA with Java", to write a section on Open Source ESBs for this book.

This was a good opportunity to advertise OpenESB, so I eagerly said yes. Satadru suggested that a practical example should be the core of the chapter, so I sat down with two of my colleagues, Murali Pottlapelli and Sujit Biswas, to discuss how the example would look like.

The result is a 17 page chapter that gives an overview of OpenESB. The book is now available for review on Safari. This link will probably be invalidated when the review period ends, but perhaps the link to the book itself is more permanent (the book is also on Amazon).

GlassFish ESB v2.2 was released in late December/early January 2010. This release brings a number of design-time improvements in handling HL7 v2 messages. Some of these have been on my and other people’s wish lists for years.

HL7 v2 structure nodes use full names, rather then acronyms like MSH.1.
In BPEL, mapping can be performed at message, segment, component, subcomponent and field level.

These improvements are noteworthy enough to warrant a note, GFESBv22_HL7_Handling_Improvements.pdf, at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/GFESBv22_HL7_Handling_Improvements.pdf/details.

When working on the HA solutions discussed in my HA blog entry I realized that it will be difficult to work out whether messages are delivered in order, as was required, and whether any are missing. I got over the issue by ensuring that my test data was prepared in such a way that messages in each test file had increasing, contiguous sequence numbers embedded in the message. For HL7 v2, which is the messaging standard with which I dealt, I used MSH-10, Message Control ID field. I wrote processed messages and acknowledgments to files whose names embedded MSH-10 Message Control Id, with the sequence number, so breaks in sequence and out of order messages could be readily detected.

With multiple message files containing between 1 and 50,000 messages, adding a sequence number to each message by hand was clearly out of the question.

I put the GlassFish ESB to use. I constructed a file-to-file BPEL module project to read each test file and to prepend a sequence number to each message’s MSH-10 field. The only snag was how to get a sequence number that would start at 0 and increase by 1 for each message, such that each BPEL process instance would get the next sequence, and that messages would be written to the output file in order.

This note discusses how I went about accomplishing the task.

The complete note, GFESBv22_EphemeralSequenceGenerator_v1.0.0.0.pdf, is to be found at: http://mediacast.sun.com/users/Michael.Czapski-Sun/media/GFESBv22_EphemeralSequenceGenerator_v1.0.0.0.pdf/details

We had a busy December releasing Java EE 6 and GlassFish v3, but the good news doesn't have to stop with the beginning of a new year and so it was great to see that our SOA team recently released GlassFish ESB 2.2.

What is new you ask?  There are a host of updates and new features including support for newer versions of GlassFish and NetBeans and support for the latest operating systems, as well as some new components including the E-mail Binding Component (BC), REST BC, and POJO Service Engine (SE), but what is perhaps more interesting is the introduction of a couple of Packs.

The Healthcare Pack extends the functionality and features of GlassFish ESB to healthcare organizations who are focusing on  improving the exchange of electronic health care information.  It includes the HL7 Binding Component, Sun Master Index, and the PIX/PDQ Solution.

The Platinum Pack extends the base ESB with some additional components including the Worklist Manager Service Engine, the Intelligent Event Processor SE, the COBOL Copybook Encoder, the BPEL Monitor, and a new Event Management API.

All in all, some great capabilities have been added to an already outstanding integration platform. 

Interested in more info?  You can download the bits, see more on sun.com, visit the community, or attend a training course.

Enjoy! 

It seems frequently assumed that architecting and deploying Highly Available (HA) solutions requires Application Server and/or Operating System clustering. When it comes to SOA and Integration solutions this is not necessarily a correct assumption. Load Balanced (LB) and Highly Available HA) SOA and Integration solutions may not require that degree of complexity and sophistication. Frequently, protocol, binding component, JBI and architectural application design properties can be exploited to design highly available solutions. Testing LB and HA solutions requires infrastructure consisting of multiple hosts and the ability to “crash” hosts at will. With virtualization technologies available now it is far easier to use multiple virtual machines then to use physical machines. It is also easier and potentially less destructive to “crash” virtual machines then it is to do so with physical machines.

In this Note a heterogeneous, non-clustered collection of hosts will be used to implement and exercise three load balanced, highly available GlassFish ESB-based solutions. The environment consists of a number of independent “machines”, which are not a part of an Operating System Cluster. Each “machine” hosts a GlassFish Application Server. Application Servers are independent of one another and are not clustered. This is to demonstrate that load balanced, highly available, horizontally scalable solutions, based on the GlassFish ESB software alone, can be designed and implemented.

The specific class of solutions to which this discussion applies is the class of solutions which:
1.    are exposed as request/reply services
a.    HL7 messaging with explicit Application Acknowledgment
or
b.    Request/Reply Web Services
or
c.    JMS in Request/Reply mode
2.    implement business logic as short lived processes
3.    are
a.    atomic
or
b.    are idempotent
or
c.    tolerant of duplicate messages
Classes of solutions with characteristics different from these named above require different approaches to high availability and horizontal scalability, and are not discussed here.

In this Note only high availability and scalability of receiver solutions is addressed. This aspect is the focus because a failure to process a message by a receiver may result in message loss –generally a bad thing.

Paradoxical as it may sound; senders are special cases of receivers. Just as a receiver is triggered by arrival of a message so too is a sender. Making sure that the sender trigger message does not get lost is much the same as making sure the message a receiver receives does not get lost. This means that the same considerations apply to senders and to receivers.

This note discusses an exercise involving an example load balanced, highly available, horizontally scalable healthcare environment, processing HL7 v2 messages. Discussion includes customization of generic GlassFish ESB v2.2 VMware Virtual Appliances for a specific Load Balancing and High Availability exercise and deploying ready-made GlassFish ESB solutions. The exercise for HL7 BC-based, Web Service-based and JMS-based highly available, load balanced, and horizontally scalable receivers, processing HL7 v2.3.1 messages, will be conducted and discussed.

At the end of the Note we will have three GlassFish ESB VMware Appliances with GlassFish ESB v2.2 Runtime infrastructure, ready to use for further GlassFish ESB Load Balancing and High Availability exercises.

The reader will be convinced, one hopes, that for the applicable class of GlassFish ESB-based solutions, load balancing and dynamic failover without message loss work. For that class of solutions this provides for high availability and horizontal scalability without resorting to Application Server or Operating System clustering.

The complete Note is available as 03_Conducting_HL7_LB_and_HA_Exercise_v1.0.0.1.pdf at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/03_Conducting_HL7_LB_and_HA_Exercise_v1.0.0.1.pdf/details
It seems frequently assumed that architecting and deploying Highly Available (HA) solutions requires Application Server and/or Operating System clustering. When it comes to SOA and Integration solutions this is not necessarily a correct assumption. Load Balanced (LB) and Highly Available HA) SOA and Integration solutions may not require that degree of complexity and sophistication. Testing LB and HA solutions requires infrastructure consisting of multiple hosts and the ability to “crash” hosts at will. With virtualization technologies available now it is far easier to use multiple virtual machines then to use physical machines. It is also easier and potentially less destructive to “crash” virtual machines then it is to do so with physical machines.

This note walks through the process of installing a GlassFish ESB v2.2 runtime on the Base OpenSolaris-based VMware Virtual Appliance, discussed in the Blog Entry “GlassFish ESB v2.x Field Notes - Preparing Basic JeOS Appliance for GlassFish ESB LB and HA Testing” at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_x_field.

At the end of the Note we will have a GlassFish ESB VMware Appliance with GlassFish ESB Runtime infrastructure, ready to use for GlassFish ESB Load Balancing and High Availability testing, or any other purpose for which a GalssFish ESB runtime appliance might be appropriate.

The complete note is available as 02_Installing_GlassFishESB_on_JeOS_appliance_v1.0.0.1.pdf at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/02_Installing_GlassFishESB_on_JeOS_appliance_v1.0.0.1.pdf/details
It seems frequently assumed that architecting and deploying Highly Available (HA) solutions requires Application Server and/or Operating System clustering. When it comes to SOA and Integration solutions this is frequently a wrong assumption. Load Balanced (LB) and Highly Available HA) SOA and Integration solutions may not require that degree of complexity and sophistication. Testing  LB and HA solutions requires infrastructure consisting of multiple hosts and the ability to “crash” hosts at will. With virtualization technologies available now it is far easier to use multiple virtual machines then to use physical machines. It is also easier and potentially less destructive to “crash” virtual machines then it is to do so with physical machines.

This note walks through the process of building a Base OpenSolaris-based VMware Virtual Appliance, based on the JeOS Prototype. It will be used as the underlying infrastructure in future Notes discussing building GlassFish ESB, Java MQ, MySQL and other appliances used in LB and HA testing. The major advantage of this infrastructure is that, as well as being fully functional, if is free (as in free beer).

At the end of the Note we will have a basic VMware Appliance, running the minimal, headless OpenSolaris Operating System (based on June 2009 JeOS Prototype), configured to use NAT networking, and ready to use as the basis of GlassFish ESB and other infrastructure. To accomplish this we will download the JeOS Prototype, configure machine name and NAT networking and test network connectivity. We will also discuss the steps required to clone this appliance.

The complete walkthrough is available as 01_Preparing_baisc_JeOS_appliance_v1.0.0.3.pdf at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/01_Preparing_baisc_JeOS_appliance_v1.0.0.3.pdf/details.

Following up on the release of Java EE 6 and GlassFish v3, we held an online virtual conference last week and I'm pleased to share replays of all of the sessions are now available.  For those that weren't able to attend or missed a session or two, this is a great way to catch up and watch the sessions at your leisure.

The sessions available for replay are:

  • Java EE: The Foundation for Your Business
  • Java EE 6: An Overview
  • GlassFish v3 - Java EE 6 Reference Implementation & Beyond
  • Enterprise Java Beans (EJB) 3.1 Features
  • Jersey, JAX-RS and REST with GlassFish v3
  • Java Servlet 3.0
  • Java Persistence API (JPA) 2.0
  • Java Server Faces (JSF) 2.0
  • Web Services in GlassFish
  • Context Dependency and Injection (JSR 299)
  • OSGi in GlassFish v3
  • Dynamic Languages with GlassFish v3
  • Tools for GlassFish v3: NetBeans and Eclipse
  • Grizzly: NIO & Web Framework. Comet using GlassFish
  • Monitoring, Management in GlassFish v3
  • Java EE Connector Architecture 1.6

I hope some of you take advantage of the opportunity and a little free time over the break to tune in!

My colleagues and I have had a very difficult time trying to get IBM WebSphere 6.1 installed in CentOS 5.3. Thanks to the help of Matt White, we finally believe we have figured out a work around.

The Issue
The swing installer does not load after clicking on the Install link within the HTML Launch page. This issue is best documented in the Redhat and IBM communities.
Basically, we would perform a netinstall of CentOS 5.3, unpack was.cd.6100.wasdev.nocharge.linux.ia32.tar.gz into a subdirectory, and run ./launchpad.sh. Firefox would load the install page which contains a link to install WebSphere that brings up a Java Swing Application that performs the actual install. Problem is the Java Swing app never appears. After closing the browser, launchpad complains saying, "No supported Web browser was detected". Also we discovered an error in the following log file /tmp/niflogs/log.txt:

"Process, com.installshield.wizard.StandardWizardListener, err, could not initialize interface swing"

The Solution(s)
We actually never figured out how to solve this issue. We tried different JDKs, different browsers, 64 bit versions, etc. Nothing fixed the problem. Thanks to Matt White though, we did figure out a possible work around.

Open a new terminal and go to the websphere directory were you unpacked the installer. cd into the WAS directory and run: sudo java -jar setup.jar. The Java Swing install app appears and you are now able to install WebSphere. We have had mixed results with it automatically creating a default profile (AppSvr01), so if it does not create a default profile, you can manually create it by running the /opt/IBM/WebSphere/AppServer/bin/ProfileManagement/pmt.sh script.

The other possible solution is to install an older version of CentOS such as 5.1, install WebSphere 6.1, and then upgrade CentOS to 5.3. I tried doing this with 5.2 and the launchpad still failed, but we know of others that we think used 5.1 and it worked.

See the first round of articles I found gleaning the web on our launch last week of Java EE 6 and GlassFish v3, but here are more:

As you can imagine, there has been a lot of activity in the blogosphere resulting from our launch today of Java EE 6 and GlassFish v3.  A sampling:

  • Sun Releases Java EE 6, GlassFish v3, and NetBeans 6.8 - A nice DDJ article.  One highlight: "One development feature that I find particularly useful is Session Retention. With this, while debugging a problem in your web or enterprise application, as you make changes NetBeans and Glassfish save your session and application state so that you don't need to restore it each time you restart Glassfish."
  • Sun Ships GlassFish Enterprise Server v3 - eWeek article with a nice quote on a very important point.  "Developers can start with the Web Profile and grow to the entire platform as their needs grow."
  • Java EE 6, GlassFish v3 and NetBeans 6.8 Released - InfoQ story that includes a nice Q&A with Roberto, one of the Java EE 6 spec leads.
  • Sun releases Java EE 6 - Another summary story, this one from SDTimes.
  • GlassFish v3 - The First List of Firsts - A great list of items you may not be aware of.
  • First look at GlassFish v3 performance - Not completely scientific and tuned, but results show v3 is better than v2 (which itself set world record benchmarks in the past), and significantly better than JBoss and Tomcat.  In fact, JBoss and Tomcat failed to complete the scale test even with fewer users than GlassFish was able to support on the same hardware.

Today we released Java EE 6 and the Java EE 6 SDK.  In addition, we've also released GlassFish Enterprise Server v3, the first Java EE 6 compatible application server.

This is the culmination of over 3 years of work by many members of the JCP, community, and engineers at Sun and other companies that have contributed to the specifications and implementations of them, and interestingly comes nearly 10 years to the day since J2EE 1.2 was released in December of 1999.  My thanks go to all involved, particularly the members of my team that made this all possible.

Naturally, one might ask, why is this important?  You can see the Java EE 6 and GlassFish Enterprise Server v3 press releases for more details, but I'll highlight some of the important things here.

Java EE 6 is important for many reasons, not the least of which is that it continues the development, maturation, and innovation of the standard for enterprise Java development.  Past releases of Java EE have continued to add few features and capabilities from servlets, EJBs, and JMS in early releases, to rich Web services support and ease of development features like annotations and EJB 3.0 in Java EE 5 three years ago.  Java EE 6 continues to add new features like RESTful Web services, dependency injection, and annotation additions for Servlets further reducing the amount of code a developer must write, but also aims to provide a more extensible and more flexible platform through the introduction of profiles and pruning.

With the Web Profile, there is now a standard set of components defined as part of the specification that will allow compatible implementations optimized for modern Web applications where the full Java EE stack is not required.  This will result in lighter weight servers requiring fewer resources that start in a fraction of time past Java EE servers have required.

But a fantastic specification is of little use without a commercial product being available that customers can confidently deploy their applications to knowing that it is ready for such use and that has the backing of an organization ready to support it.  This is why GlassFish Enterprise Server v3 is so important, as it is available today, at the same time as the SDK.  And with the introduction of the GlassFish v3 Web Profile, developers and organizations can use a platform optimized for modern Web applications while at the same time knowing they are using a standard and product that will allow them to move up to full Java EE 6 at any time without requiring any changes or re-implementation.

While a straight forward implementation of Java EE 6 would be very valuable given the strides it has made, GlassFish Enterprise Server v3 goes much further in a number of areas.  These include a modular runtime based on OSGi providing for a faster startup and loading of only those components that are required, the ability to run containers for other languages like JRuby and Jython, an Update Center for updating components and adding new components through an easy to use console, and new iterative development features that enable and edit->save->refresh development cycle for Web applications where redeployment is not required and session state information is preserved.

But realizing the benefits of a great server is only enhanced when you have great tooling.  That is why the announcement of the release of NetBeans 6.8 is also very important, as just like GlassFish is providing a full commercial Java EE 6 implementation at the same time as the SDK is released, NetBeans is also providing full support for Java EE 6 with this new release.  For those that prefer Eclipse, there is also a new GlassFish Tools Bundle for Eclipse that has been enhanced to add support for Java EE 6.

I can only write so much in a blog entry, and those that have made it this far are probably interested in learning more, and so I'm also pleased to announce that there will be an on-line virtual conference next Tuesday December 15th.  Please visit the registration page to sign-up and prepare to participate in a number of sessions covering a summary of what is in Java EE 6 and GlassFish v3 as well as detailed sessions on EJB 3.1, JPA 2.0, JSF 2.0, OSGi, and much more.  The spec leads and other developers and experts will be on-line to answer your questions as well.

In summary, visit our Java EE 6, GlassFish v3, and NetBeans 6.8 sites to learn more and download the bits, and register for the conference to take advantage of the information and access that will provide you.  We are confident you will like what you see!

I was pleased to see that JSR-316, better known as Java EE 6, was approved by the JCP Executive Committee today.  You can see the voting results on the JCP web-site.

While I can't say I waited up until midnight to check the voting like Roberto Chinnici, the spec lead for Java EE 6, I was anxiously awaiting the results this morning.  Roberto has a nice write-up on his blog, but suffice it is to say this is a pretty big deal as there are numerous new features and updates in the areas of ease of development, extensibility, and right-sizing including:

  • Servlet 3.0 - Significantly reduces the amount of code/descriptors required
  • JPA 2.0 - Provides flexible modeling capabilities, expanded O/R mapping functionality, and more
  • Web Profile - A subset of the full spec optimized for Web applications

The Web Profile in particular is exciting because it provides a way for vendors to offer smaller footprint, faster starting, and just generally more nimble servers that will allow developers to rapidly build modern Web applications adhering to the Java EE spec allowing them to move up to the full spec whenever needed with virtually no changes.

Stay tuned for more news about Java EE 6 and GlassFish in the next few weeks, but if you are interested in learning more about Java EE 6, take a look at John and Harpreet's recent webinar

 

In some specific circumstances, for example when testing high availability and failover scenarios, it may be desirable to make a BPEL process wait for a random amount of time, not exceeding some maximum duration, before continuing.

This Note describes the JavaScript Codelet which, given a maximum duration in Milliseconds, will return a random time up to that maximum duration, as an ISO8601 Duration Literal, suitable for use in the BPEL Wait activity. An example process that uses this Codelet is also developed and discussed.

This Note relies on the material presented in the Blog Entry “GlassFish ESB v2.1 - Using JavaScript Codelets to Extend BPEL 2.0 Functionality”, at http://blogs.sun.com/javacapsfieldtech/entry/glassfish_esb_v2_1_using.

The document is to be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/BPEL_WaitRandomDuration_v1.0.1.pdf/details.

The example project is to be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/ISO8601DurWait.zip/details

The BPEL SE, featured in the GlassFish ESB, the OpenESB and the Java CAPS 6, has the ability to execute JavaScript (ECMAScript) code inline. Why would one do that, you may ask. The answer is: because BPEL, great as it is with XML all over the place and all, can not do everything, and invoking Web Services and POJOs from BPEL for small and simple code adds too much overhead.

Take a date conversion, for example. It takes about 4 lines of Java code to perform date conversion. Doing this in BPEL is too horrible to contemplate. Doing this in JavaScript is not too bad, given availability of ready-made JavaScript scripts that do the job.  The issue is that one cannot invoke Java from BPEL without resorting to a web service or a POJO. Invoking JavaScript, on the other hand, does not require either. Furthermore, JavaScript, in the Netscape days, acquired the ability to embed Java using technology known as LiveConnect.

In this Note we will explore the BPEL SE capability to execute JavaScript code inline. In passing we will also explored the ability of JavaScript to execute Java statements, and through these means to extend BPEL 2.0 with arbitrarily sophisticated functionality, without having to resort to invoking web services or POJOs.

We will introduce 2 Rules which must be followed, and 1 Rule which should be followed, for successful BPEL and  JavaScript integration. We will develop two complete examples of embedded JavaScript code that provides reasonably useful functionality not natively available through BPEL. While the two examples will be fairly trivial it will be clear that more sophisticated functionality can be added following the method introduced in this Note.

Writeup, BPEL_JavaScript_Java_GetProperty_v1.0.2.pdf, can be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/BPEL_JavaScript_Java_GetProperty_v1.0.2.pdf/details

 Projects, developed in the writeup, in the archive BPEL_JavaScript_Java_GetProperty_v1.0.2_code_bis.zip, are to be found at http://mediacast.sun.com/users/Michael.Czapski-Sun/media/BPEL_JavaScript_Java_GetProperty_v1.0.2_code_bis.zip/details

If you are a webpage author or use confidential information on the internet (credit card information, social security number, login credentials for paypal or banking), you might think twice the next time you log into your favorite website. I know I started paying more attention after listening to Steve Gibson's Security Now podcast titled "The Fundamentally Broken Browser Model". That title is a bit confusing, but the underlying issue is very serious. That is why I would like to further explain the issue by providing a simple example, then a real world example using facebook, and then discuss a simple solution.

First, what does Mr. Gibson mean by The Fundamentally Broken Browser Model? Well, at this years Black Hat conference, a hacker named Moxie Marlinspike gave a presentation where he talked about how he was able to capture sensitive information at a public WiFi hotspot using open tools he created. Specifically, during a 24-hour period, he intercepted 114 logins to yahoo, 50 logins to gmail, 42 to ticketmaster, 14 to rapidshare, 13 to hotmail, 9 to paypal, 9 to LinkedIn, and 3 to facebook. So how did Moxie do it? He took advantage of a common flaw of most login pages: the login pages themselves are not received by the client over SSL allowing man-in-the middle attacks to change the submit URL.

SSL (Secure Socket Layer) has been the common method for securing HTTP, but has been limited to only sensitive areas of a website for performance reasons. Sites have always protected a user's private information (usernames, passwords, credit card numbers, etc) using SSL, but to date no one has thought about actually securing the login page itself and this is a huge problem as most sites don't encrypt their login pages. Not encrypting login forms leaves it open to modification before it returns to the user.

This attack has 2 basic steps. First, the malicious user needs to be on the same network (LAN) and utilize ARP (Address Resolution Protocol) spoofing techniques to insert himself in-between connections (this is pretty scary considering how many times I have connected to restaurant, hotel, and airport WiFi hotspots). Second, a LAN user has to visit a login page that was received over a non-SSL connection.

Simple Example
To explain the issue better, let me use a simple example (let's leave ARP spoofing out for now). A user visits an e-commerce site http://www.eco.com. Like most sites, eco.com includes a Login link at the top. Clicking on this link takes the user to http://www.eco.com/login, which returns a simple login form in HTML.
<form method="POST" action="https://www.eco.com/login/authenticate">
Username: <input name="username" type="text">
Password: <input name="password" type="password">
<input value="Submit" type="submit">
</form>
The user types in their username and password, clicks the Submit button, and their private information is sent encrypted over SSL. It is sent over SSL because the form's action value is set to an SSL URL (https://www.eco.com/login/authenticate). But there is one big problem. The Login link the user click was non-SSL (http://www.eco.com/login), meaning the response back to client was sent over the network as clear-text and could easily be modified by man-in-the middle attacks using ARP spoofing. A malicious user could change the form's submit URL from https://www.eco.com/login/authenticate to http://www.eco.com/login/authenticate and the user would never know it happened. There are few default clues to indicate this is happening. So a malicious user, changes the submit URL to a non-SSL URL, a user clicks Submit, and their credentials are sent as clear-text over the network.

facebook example
Armed with this new information I wondered how some of my favorite sites handle this situation. No matter what I tried, it looked like gmail, ebay, and paypal where safe and used SSL for their login pages. So that gave me some peace of mind. However, facebook provides us with a perfect bad example.

If your like me, I type facebook in my browser and use the CRTL+ENT keyboard shortcut to fill in the rest. So I end up at http://www.facebook.com. If you are not currently logged into facebook, you are presented with the following home page that includes a form to register or login.


Again, this home page includes a login page that was sent over a non-SSL connection. As we expect, if you look at the source, you can see the HTML form does post securely to the URL https://login.facebook.com/login.php?login_attempt=1. So what do you do if you don't want to fill in a form that was received over a non-SSL connection? Fortunately, facebook also supports SSL for its home page (https://www.facebook.com), it just takes a little awareness and an extra step.

Solution
More sites need to use SSL for their login forms, and not just for when users post their credentials. At a minimum, like facebook, sites should also support SSL and ideally all login forms would automatically be requested over SSL. If you come across a site that initially does not use SSL for the login page, try and use https. If that fails then think about using a VPN solution or even a travellers router.