JBoss and Oracle XE

JBoss and Oracle XE (Express Edition) make for an interesting, and cost effective, J2EE stack for non-mission critical, small scale, software applications. Getting JBoss and Oracle XE to work together is really straight forward.

Resolve port conflicts
By default, JBoss and Oracle XE both use port 8080. So, when using JBoss and Oracle XE on the same machine, something has got to give. As one is most likely to be using and interacting with the container more, it might as well be the database that has to adapt. To change the default Oracle XE HTTP Listening port (8080) to 9090 do the following:

  1. Start sqlplus (Run SQL Command Line icon in windows)
  2. Enter ‘connect / sysdba’
  3. Enter ‘exec dbms_xdb.sethttpport(9090);’
  4. Stop and then Start the Oracle XE database

Note that this does not change the default TNS Listening port 1521, although the short cut (/app/oracle/product/10.2.0/server/Database_homepage.url) to launch the Database home page will need to be updated.

Setup DataSource
The Oracle XE installation comes with a sample HR database. A DataSource in JBoss can be defined for it, but first the Oracle JDBC library needs to be in the JBoss server classpath. Copy ojdbc14.jar from /app/oracle/product/10.2.0/server/jdbc/lib to /server/default/lib. Now the DataSource can be defined. DataSources are ‘deployed’ in JBoss. Their configuration information is in an XML file with a name that ends in ‘-ds’.

In /server/default/deploy create a file called oraclexe-ds.xml with the following content:









OracleXEDS

jdbc:oracle:thin:@127.0.0.1:1521:XE

oracle.jdbc.driver.OracleDriver
hr
hr

5
100


org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter


Remember that in Unlocking the Sample User Account step in Oracle XE Getting Started Guide, the HR account password is set to ‘hr’. The console for JBoss should display something like:


[ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=OracleXEDS' to JNDI name 'java:OracleXEDS'

Testing DataSource witha JDBC client
A simple JSP, in an expanded WebApp, can be used to test the DataSource. In /server/default/deploy create a directory called ‘jdbcclient.war’. In that directory create a file called ‘client.jsp’ and add the following content:

<%@page contentType="text/html"
import="java.util.*,javax.naming.*,javax.sql.DataSource,java.sql.*"
%>
<%

DataSource ds = null;
Connection con = null;
PreparedStatement pr = null;
InitialContext ic;
try {
ic = new InitialContext();
ds = (DataSource)ic.lookup( "java:/OracleXEDS" );
con = ds.getConnection();
pr = con.prepareStatement("SELECT EMPLOYEE_ID, LAST_NAME FROM EMPLOYEES");
ResultSet rs = pr.executeQuery();
while (rs.next()) {
out.println("
" +rs.getString("EMPLOYEE_ID") + " | " +rs.getString("LAST_NAME"));
}
rs.close();
pr.close();
}catch(Exception e){
out.println("Exception thrown " +e);
}finally{
if(con != null){
con.close();
}
}
%>

Open your browser and point it to http://localhost:8080/jdbcclient/client.jsp. A list of employee numbers and last names get displayed. This ‘jdbcclient’ approach is used in the JBoss DataSource tutorials.

Greater web service independence with JEE 5

One of the reasons I did the Dice web service example was to see if it really was possible to build a JEE 5 POJO web service (all be it a simple one) and deploy it in different JEE 5 containers without having to maintain separate deployment descriptors, or test classes, for the target platforms. The answer is a yes! Although it is a slightly qualified yes. More on that below, here are the target platforms first:

  • OC4J 11g Technology Preview (standalone version packaged in JDeveloper)
  • Glassfish v1 ur1 p01
  • JBoss 4.2.0 GA

The same WAR file built in JDeveloper 11g Technology Preview will deploy on all three containers without modification. To create the WAR file I followed the steps in the HelloService tutorial. However, I did have to change the project properties to set the output directory to public_html/WEB-INF/classes/ otherwise the classes would not be packaged in the WAR.

Deploying the web service on OC4J is covered in the tutorial. Deploying on the other platforms is just as easy, just take advantage of the auto deploy features by dropping the WAR file into the relavant directory of the running server:

  • Glassfish: glassfish/domains/domain1/autodeploy
  • JBoss: jboss-4.2.0.GA/server/default/deploy

It is worth taking a look at the WAR file as the only things in it are the classes (Dice and Die) and the web.xml which registers Dice as a servlet (DiceServicePort). It is the JAX-WS annotations on the Dice class that tell the container it is a web service and the container takes it from there generating WSDL, etc.

The service works on all three platforms without modification, which is good. However, there is difference in the WSDL files for each platform and that’s the qualification mentioned earlier. The end point structures are different. JBoss and OC4J keeping the servlet url-pattern and Glassfish opting for the service name (i.e. DiceService). This is only a slight difference as everything else remains the same. In fact you could generate a web service proxy client from one WSDL and use those proxy client classes for invoking the service on another platform. Just change the ENDPOINT_ADDRESS_PROPERTY. This is reassuring as the code and interface have not changed, only the platform. This is not a problem at all if test cases have the web service end point externalised.

One thing I need to point out here for those wanting to reproduce the excercise, I had to use JDeveloper 10.1.3.2 to generate the DiceServiceProxy classes because 11g Technology Preview version would treat the service ‘roll’ operation as a one way method and not return a response.

So there you have it. JEE 5 has brought us a step closer to build and test enterprise software components without the overhead of maintaining platform specific artefacts. Given more time I would try some more JEE 5 containers. Suggestions welcome.