Sunday, October 20, 2013

Migrating applications to JBOSS AS7 or JBOSS 7 or JBOSS EAP6

Migrating applications to JBOSS AS7 or JBOSS 7

  • Migrate to JBOSS7
  • Migrate to Jboss 7
  • Migrating to JBOSS EAP6
  • Migrating applications from Websphere to JBOSS AS 7
  • JBOSS 7 Migration guide
I recently had a task to migrate all of java based web applications, EJB’s and Webservices from Webspshere to JBOSS AS 7 or JBOSS EAP 6. This article is applicable for anyone migrating there java based applications to JBOSS & EAP6 and is not specific to Websphere.

There are several aspects that are different in JBOSS 7 like
  • The way you load resources from classpath (Its not the usual java way weird J)
  • The classloading problem can be dealt easily with the jboss-deployment-structure.xml (Its awesome !!)
  • The speed at which jboss starts and stop’s is nowhere close Websphere . Jboss is superfast.
Let see how to set up data source, namespace bindings and configure Queues on JBOSS 7 (aka EAP 6)
In Jboss you use standalone mode if you have single instance of a server in cases where you have multiple servers you use domain mode. In standalone mode Jboss server uses standalone.xml and in domain mode we end using domain.xml.

Assuming you have jboss deployed under C:\jboss-eap-6.0. Before you can declare a data source you need to install a driver.

Installing oracle database driver in JBOSS 7 or EAP 6:
  • Download ojdbc6.jar
  • On your local go to C:\jboss-eap-6.0\modules
  • Create a directory structure C:\jboss-eap-6.0\modules\com\oracle\ojdbc6\main
  • Add the jar “ojdbc6.jar” in to C:\jboss-eap-6.0\modules\com\oracle\ojdbc6\main
  • Create file called module.xml and add the following contents to it


<?xml version="1.0" encoding="UTF-8"?>
     The module name, "", should match the directory 
     structure for this module.
<module xmlns="urn:jboss:module:1.0" name="">
      <resource-root path="ojdbc6.jar" />
      <module name="javax.api" />

Installing Microsoft SQL server database driver in JBOSS 7 or EAP 6:
  • Download sqljdbc.jar
  • On your local go to C:\jboss-eap-6.0\modules
  • Create a directory structure C:\jboss-eap-6.0\modules\com\microsoft\sqlserver\main
  • Add the jar “sqljdbc.jar” in to C:\jboss-eap-6.0\modules\com\microsoft\sqlserver\main
  • Create file called module.xml and add the following contents to it
C:\jboss-eap-6.0\modules\com\microsoft\sqlserver\main \module.xml

<?xml version="1.0" encoding="UTF-8"?>
   The module name, "", 
   matches the directory structure for this module.
<module xmlns="urn:jboss:module:1.0" name="">
      <resource-root path="sqljdbc.jar" />
      <module name="javax.api" />
      <module name="javax.transaction.api" />

Sweet we now have installed the drivers and we can now reference these drivers in standalone.xml (or domain.xml if its domain mode) which is the file that Jboss reads to load your data sources, Queues, connection factories, name space bindings….etc

Adding a Datasource in JBOSS 7 or EAP 6 :

In your standalone.xml or domain.xml (eg: C:\jboss-eap-.0\standalone\configuration\standalone.xml) go the following section “<subsystem xmlns="urn:jboss:domain:datasources:1.1">“
(This part of the section from standalone.xml)

<subsystem xmlns="urn:jboss:domain:datasources:1.1">
<datasources> <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true"> <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url> <driver>h2</driver> <security> <user-name>sa</user-name> <password>sa</password> </security> </datasource> <datasource jta="true" jndi-name="java:/jdbc/RAMA_TST_DB" pool-name="TSTDBPoolName" enabled="true" use-java-context="true"> <connection-url>jdbc:oracle:thin:@rama-local:2111:MYSCHEMA</connection-url> <driver-class>oracle.jdbc.driver.OracleDriver</driver-class> <driver>ojdbc6.jar</driver> <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation> <security> <user-name>scott</user-name> <password>tiger</password> </security> </datasource> <drivers> <driver name="h2" module="com.h2database.h2"> <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class> </driver> <driver name="ojdbc6.jar" module="" /> </drivers> </datasources>
Please note that in the above snippet
  1.  We referenced the name of the driver we installed under <drivers> section <driver name="ojdbc6.jar" module=""/>
  2. The name "ojdbc6.jar" can be anything I just used the name of the jar for simplicity.
  3.  Now reference the name that you gave this driver in the data source section along with database credentials and connection String.
  4. The property use-java-context="true" will bind the data source java:/ if you set it to false the pre qualifier java will be omitted and your data source will be just jdbc/RAMA_TST_DB
Now if you start the server you should see that the data source will be bound to java:/jdbc/RAMA_TST_DB

In your Spring code you can access this data source as shown below

<bean id="testDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value=" java:/jdbc/RAMA_TST_DB " />

Adding Name Space bindings in JBOSS 7 or EAP 6:
In standalone.xml look for the section that says “<subsystem xmlns="urn:jboss:domain:naming:1.2">”
<?xml version="1.0" encoding="UTF-8"?>
<subsystem xmlns="urn:jboss:domain:naming:1.2">
      <simple name="java:/tstapp/keyStorePassword" value="abc" />
      <simple name="java:/tstapp/signingKeyCertPassword" value="xyz " />
      <simple name="java:/tstapp/encrytpionKeyCertPassword" value="test " />
      <simple name="java:/tstapp/maxretries" value="10" />
      <simple name="java:/tstapp/adminemail" value="" />
   <remote-naming />
You can refer the namespace using spring as shown below

<bean id="envType" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value=" java:/tstapp/keyStorePassword " />

Adding resources to Class Path in JBOSS7 or EAP 6:
To add resources to class path you need to create a module and drop all the files that you want to read in classpath under this module.

  1. The module can be created anywhere in which case you need to inform JBOSS server by Windows:
  2. set JBOSS_MODULEPATH=%JBOSS_HOME%/modules;/path/to/my/modules
  3. If you are on mac or unix, use export and colons. i.e 
  4. export JBOSS_MODULPATH=$JBOSS_HOME/modules:/path/to/my/modules
  5. In case you created the module under C:\jboss-eap-6.0\modules\ Then we don’t need to export as this path is already present by default.
  This is how you create the module.

  • Create a folder called “custom_properties” (This name can be anything. I just choose this)
  • Create a subfolder called main ie. “custom_properties\main
  • In main add module.xml with following contents.
  • <?xml version="1.0" encoding="UTF-8"?>
    <module xmlns="urn:jboss:module:1.1" name="custom_properties">
          <resource-root path="." />

  • Add your property file for your application under a folder called “main/TST” within main.
  • Your folder structure should look like these

  • How to write the jboss-deployment-structure.xml?

    Now in your web/ejb/ear application you can reference these modules using jboss-deployment-structure.xml as shown below.
    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure xmlns:p="urn:jboss:deployment-structure:1.0" xmlns:xsi="">
             <!-- load  Custom Properties module.
    By saying true we are telling that this module is available for any war file or ejb jar
    Files if this xml is part of ear file
             <module name="custom_properties" export="true" />

    Where to add jboss-deployment-structure.xml?

    As mentioned earlier you can copy the jboss-deployments-structure.xml to META-INF folder if it’s a EAR project or EJB project or in WEB-INF folder if it’s a war file.

    This file has several other tags.
    The XSD give more insight

    How to exclude or include jars in classpath for Jboss 7 or EAP 6 ?

    We can influence class loading in Jboss server by including or excluding any modules that Jboss loads on start up. You can add this xml at EAR or level or at WAR level depending on whether you have to influence entire EAR project or localize to just WAR project

    Eg: Say you are running a JSF 1.2 based application and you want to exclude JSF2.0 jars that JBOSS loads by default you do this.


    <?xml version="1.0" encoding="UTF-8"?>
             <!-- Name of module that points to custom properties -->
             <module name="custom_properties" export="true" />
            1.Excludes JSF 2.x  which is one of the default modules in JBOSS.
            The property slot refers to version.
             <module name="javax.faces.api" slot="main" />
             <module name="com.sun.jsf-impl" slot="main" />
    So you may wonder how we got these values
    name="javax.faces.api" slot="main" 
    and      name="com.sun.jsf-impl" slot="main"

    Well these are the values from module.xml for jsf 2.0 jars in JBOSS which is at

    More info on default modules in JBOSS 7 at

    I will show you another example of jboss-deployment-structure.xml.
    We were deploying Openam as web application and we started seeing the below errors
    1. "Caused by: java.lang.IllegalArgumentException: JBAS015533: Web Service endpoint with
     URL pattern /Coordinator is already registered. Web service endpoint
     is requesting the same URL pattern."  

    2.  [OpenAM] java.lang.ClassCastException: cannot be cast to

     All we had to do was exclude the default web service modules that jboss was supplying and also to wanted to exclude com/sun/org/apache/xml/internal/security/transforms/implementations provided by sun jdk module which JBOSS 7 loads.
    Also by default the sun.jdk module in Jboss doesn’t load the following
    <path name="sun/security/x509" />
    <path name="sun/net/www/protocol/http" />
    <path name="com/sun/net/ssl/internal/ssl" />

    (Shows how to redefine an existing jboss module by excluding some default classes)

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
             <!-- All this trouble just to exclude  com/sun/org/apache/xml/internal/security/transforms/implementations" -->
             <module name="sun.jdk" />
             <module name="sun.jdk">
                      <!-- (start new dependencies) -->
                      <path name="sun/security/x509" />
                      <path name="sun/net/www/protocol/http" />
                      <path name="com/sun/net/ssl/internal/ssl" />
                      <!-- (end new dependencies) -->
                      <path name="com/sun/script/javascript" />
                      <path name="com/sun/image/codec/jpeg" />
                      <path name="com/sun/jndi/dns" />
                      <path name="com/sun/jndi/ldap" />
                      <path name="com/sun/jndi/url" />
                      <path name="com/sun/jndi/url/dns" />
                      <path name="sun/print" />
                      <path name="sun/print/resources" />
                      <!-- (suppressed unwanted dependencies; see exclude-set below) -->
                      <!-- <path name="com/sun/org/apache/xml/internal/security/transforms/implementations"/> -->
                      <path name="com/sun/security/auth" />
                      <path name="com/sun/security/auth/login" />
                      <path name="com/sun/security/auth/module" />
                      <path name="sun/font" />
                      <path name="sun/misc" />
                      <path name="sun/io" />
                      <path name="sun/nio" />
                      <path name="sun/nio/ch" />
                      <path name="sun/security" />
                      <path name="sun/security/krb5" />
                      <path name="sun/util" />
                      <path name="sun/util/calendar" />
                      <path name="sun/util/locale" />
                      <path name="sun/util/resources" />
                      <path name="sun/security/provider" />
                      <path name="sun/text" />
                      <path name="META-INF/services" />
                      <path name="com/sun/org/apache/xml/internal/security/transforms/implementations" />
             <subsystem name="jaxrs" />
             <subsystem name="webservices" />

    How to troubleshoot “startup failed due to previous errors” in JBOSS 7?

    Whenever you see your ear deployment failing with the error “Startup failed due to previous error” and with no other exception in the server.log its very annoying. By default Jboss doesn’t show you all the errors when one of the modules with ear fails which is weird?
    Why would anyone hide the exceptions and just say “Something went wrong”
    Well there is way we can tell JBOSS to spill the beans (I mean to show exception for each failed module within the ear)
    If you want errors to show for individual artifacts (like war or ejb-jar within ear)
    Add the following entry ""

    You can add this in to your servers start up script or if you are using some IDE like eclipse
    -    Double click on the server
    -   Once the server pane opens click one “Edit launch configuration”

    Go to Arguments tab and within that go to “VM arguments “ and add ""

    How To enable logging of JBOSS class loading  ?
    How to explore which classes are loaded from which JARs?
    How to find which jars and in what order are loaded by a classloader?

    In case you want to troubleshoot JBOSS Classloading issue and see which class is being loaded from which jar and you don’t want to change any code  ( I will show a trick how to find the jar file name a class belongs to in case you can change the code )

    In your standalone.xml or domain.xml (or standalone-ha.xml or standalone-full-ha.xml depending on which file you are using) go to the below section as shown here
            <subsystem xmlns="urn:jboss:domain:logging:1.1">
                <console-handler name="CONSOLE">
                    <level name="DEBUG"/>   =รจ default will be INFO

    Also to JAVA_OPTS add    "-verbose:class"  this is parameter to java command don’t use –D.
    Either you can edit standalone.conf.bat  or add this param using eclipse by opening the launch configuration.

    NOTE: This option generates too much information of every class that is being loaded and should only be used for troubleshooting.

    However if you can change the code and want to see a specific classes and where they are being loaded from here is the trick.
    Use this line of code on your object or class and you should see the jar file name in most cases.
    I tried it on JBOSS 7 and it worked and on other hand the same line of code did not work in Websphere 7.
    e.g.: I wanted to from where I was loading the FOPFactory from
    FopFactory fopFactory = FopFactory.newInstance();
    System.out.println("fopFactory was loaded from :"+ fopFactory.getClass().getProtectionDomain().getCodeSource());
    fopFactory was loaded from :(file:/C:/ workspace/TESTXSLFO/lib/fop-0.95-1.jar <no signer certificates>)
    How to enable session replication in JBOSS 7 or EAP 6?
    Assuming you have setup clustering and you app is being deployed on more than one server,
    In your web application all we need to do is include the tag <distributable/>

    <web-app xm lns=" /xm l/ns/j2ee"
    xm lns:xsi= a-instance xsi:schem aLocation= /xm l/ns/j2ee /xm l/ns/j2ee/webapp_2_4.xsd version="2.4">

    In addition if you need to make any more changes you can modify the following properties which are in jboss-web.xml (This file is part of your web application)

    NOTE: By default these are the values that JBOSS uses. You don’t need mention these values are this entire section <replication-config>  to </replication-config>  unless you have strong reason to change the values. When I tested I did not include this section in my jboss-web.xml

    <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 5.0//EN" "">
    <replication-config> <cache-name>custom -session-cache</cache-name> <replication-trigger>SET</replication-trigger> <replication-granularity>ATTRIBUTE</replication-granularity> <replication-field-batch-mode>true</replication-field-batch-mode> <use-jk>false</use-jk> <max-unreplicated-interval>30</max-unreplicated-interval> <snapshot-mode>INSTANT</snapshot-mode> <snapshot-interval>1000</snapshot-interval> <session-notificationpolicy>com .exam ple.Custom SessionNotificationPolicy</session-notificationpolicy> </replication-config> </jboss-web>

    My jboss-web.xml looked like below without any overrides for default values: (Because I just used defaults)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 5.0//EN" "">
     Sample JSP page to test session replication:
    Copy paste the below few lines into jsp page and let’s call it as SessionInfo.jsp. Now if you have two nodes just start one node and use your application generic url and you will see say session id : abc  and server name : server1 and later start node 2 and shutdown node1 and refresh the page you will see that the server name on the jsp page will change to server2 but session id will remain same. Proving the session migrated from server1 to server 2.

    <%@ page import=""%>
    <html> <head> <title>Session Details</title> </head> <body topmargin="0" leftmargin="0" marginheight="0" marginwidth="0" > <div id="sessiondetails"> <h1>Your Session Details</h1> <p class="simpleText"> Your Remote Host: <%= request.getRemoteHost() %> </p> <p class="simpleText"> Your Server Name: <%= request.getServerName() %> </p> <p class="simpleText"> Your Server Port: <%= request.getServerPort() %> </p> <p class="simpleText"> Your Host name : <%= InetAddress.getLocalHost().getHostName() %></p> <p class="simpleText"> Your Session ID: <%= request.getSession().getId() %> </p> <p class="simpleText"> Creation time: <%= request.getSession().getCreationTime() %></p> <p class="simpleText"> LastAccessedTime time: <%= request.getSession().getLastAccessedTime() %></p> <p class="simpleText"> MaxInactiveInterval time: <%= request.getSession().getMaxInactiveInterval() %></p> </div> </body> </html>

    Before you test there is one last change on server side we need to make to specify the cache mode and number of owners.  Based on what I read here it looks like DIST mode is better and number of owners should be set to “2”

    1. Go to command prompt in windows or shell prompt in unix/linux.
    2. cd JBOSS_HOME/bin
    3. ./     (In case you change the host name from localhost to some other name you may need to update the following in <host>localhost</host> in jboss-cli.xml   )
    5. You will get a prompt like [disconnected /]
    6. Now type the command "connect" (Without quotes)
    7. And now copy past the following line.

    NOTE: The above command is for profile by name “full-ha” in case you are using default profile then you can remove the profile name.

    Owners:  The owner’s parameter controls how many cluster nodes hold replicated copies of the session. The default is 2.
    Re start the servers and test it out
    NOTE: In fact you can use jboss-cli (jobs command line interface) for setting data sources, queues, check data pool statistics etc
    Here is on example of how

    Monitor datasource connection pool on Jboss using jboss cli:
    Connect to Jboss server using jboss-cli.bat or (Please see the previous steps to connect to jboss in detail using cli)
    If you don’t have profile for your server use this: (i.e you jboss server is using default profile)


    If you have profile and the name of profile is full-ha use this (If different profile please change accordingly)


    Here we are assuming your data source name is TST_DS. Replace the name to match yours.

    [standalone@localhost:9999 /] /subsystem=datasources/data-source=TST_DS/statistics=pool:read-reso
        "outcome" => "success",
        "result" => {
    "ActiveCount" => "0",
    "AvailableCount" => "20",
    "AverageBlockingTime" => "0",
    "AverageCreationTime" => "0",
    "CreatedCount" => "0",
    "DestroyedCount" => "0",
    "MaxCreationTime" => "0",
    "MaxUsedCount" => "0",
    "MaxWaitTime" => "0",
    "TimedOut" => "0",
    "TotalBlockingTime" => "0",
    "TotalCreationTime" => "0"
     Migrating JSF Web applications to JBOSS 7 or EAP 6:

    JBOSS EAP 6 by default comes with both JSF 1.2 and JSF 2.0 jars. If you want to force your web application to load the JSF jar that’s in your web-inf/lib folder you need to exclude the JBOSS version of JSF jars.

    Add jboss-deployment-structure.xml with the following contents to WEB-INF if its war  or META-INF if its ear file. I added it to my EAR file

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure xmlns:p="urn:jboss:deployment-structure:1.0" xmlns:xsi="">
             <!-- Custom Properties was my won module to load some property files -->
             <module name="custom_properties" export="true" />
       <sub-deployment name="yourwarFileName.war">
             <module name="javax.faces.api" slot="main" />
             <module name="com.sun.jsf-impl" slot="main" />
             <module name="javax.faces.api" slot="1.2" />
             <module name="com.sun.jsf-impl" slot="1.2" />
    NOTE: In case you add this file to war file then you don’t need sub-deployment tag.

    Since we were jsf 1.2 myfaces it started complaining with the below exception
    As result my faces started complaining with the below error.

    Caused by: java.lang.InstantiationException: org.ajax4jsf.framework.DebugLifecycleFactory
                at java.lang.Class.newInstance( [rt.jar:1.7.0_25]

    Add the following to web.xml. This tells my faces to use the JSF jar that we are bundling with war file.


    For all Ajax calls I was getting this error.

    java.lang.IllegalStateException: Parameters processing failed.
     at org.apache.tomcat.util.http.Parameters.processParameters( [jbossweb-7.0.16.Final-redhat-1.jar:]

                Root Cause:EAP 6.0.0.BETA used JBoss Web 7.0.10.FINAL and as such some changes were made between the BETA and the GA. Included in these changes was some refactoring of code to improve performance and this included a flag to register parsing errors. If an improper http parameter was received it throws an IllegalStateException. In the BETA this error was just logged as it was not critical. Now this change is breaking existing applications using certain browsers.

    FIX IT:
    This is what we need to do :
    1.  Download from
    2. Go to JBOSS_EAP_6_HOME\modules\org\jboss\as\web\main
    3. Remove jbossweb-7.0.16.Final-redhat-1.jar , jbossweb-7.0.16.Final-redhat-1.jar.index and module.xml
    4. Copy jbossweb-7.0.16.Final-redhat-1-JBPAPP-9500.jar and module.xml from to JBOSS_EAP_6_HOME\modules\org\jboss\as\web\main

    NOTE: Once we re-start “jbossweb-7.0.16.Final-redhat-1-JBPAPP-9500.jar.index” will get generated.

    Next Exception I got was
    Caused by: java.lang.NoClassDefFoundError: com/sun/rowset/CachedRowSetImpl

    FIX: Added this in jboss-deployment-structure.xml and copy the xml to YOUREAR/META-INF or if no ear copy to WEB-INF folder in war file.
    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure xmlns:p="urn:jboss:deployment-structure:1.0" xmlns:xsi="">
             <!-- Custom Properties -->
             <module name="custom_properties" export="true" />
             <system export="true">
                   <path name="com/sun/rowset" />
                   <path name="com/sun/rowset/internal" />
                   <path name="com/sun/rowset/providers" />
    JBOSS Transaction manager

    In my spring application.xml I changed the transaction manager to below values.

    Jboss should work with this alone.
    The default name space is not java:comp/UserTransaction
    <bean id="OracleTxManager" class="org.springframework.transaction.jta.JtaTransactionManager">
                <property name="transactionManagerName" value="java:jboss/TransactionManager"/>

    In my hibernate.cfg.xml I changed the manager lookup class to

    <prop key="hibernate.transaction.manager_lookup_class">

    Migrating Webservices to Jboss:
    There is not much you need to do to migrate web services from other servers to JBOSS as long you are using annotations. Since our applications are deployed on multiples servers we have one generic url for webservice. We use mod cluster to load balance the traffic to individual servers. However the rendered WSDL was returning us the ip address and port number of individual servers instead of the generic Webservice URL

    How to set JBOSS Webservice endpoint to have the address that client requested?

    This is what we have to do to get the correct end point address in WSDL. In your Standlaone.xml or domain.xml  set wsdl-host to

    <subsystem xmlns="urn:jboss:domain:webservices:1.1">

    Read more at :

    I  will add some notes on migrating EJB's to JBOSS shortly to this article.