Porting Weblogic to JBoss

We introduce with this article a small series of tutorials which are aimed at porting applications from weblogic server to JBoss. In thist tutorial we focus on some general architectural aspects and on the connection pool and startup classes porting.  

Architectural differences

The first semantic difference between Weblogic and JBoss is that Weblogic uses the
Domain concept while JBoss has just the definition of configured Servers.

A WebLogic Server domain is a logically related group of WebLogic Server resources. Domains include a special WebLogic Server instance called the Administration Server, which is the central point from which you configure and manage all resources in the domain. Usually, you configure a domain to include additional WebLogic Server instances called Managed Servers. You deploy Web applications, EJBs, Web services, and other resources onto the Managed Servers and use the Administration Server for configuration and management purposes only.

jboss weblogic

JBoss hasn’t got the concept of Domain, rather uses configured Servers which are a physical entity. All units which are found under $JBOSS_HOME\server are the available server configurations. In the following picture you can see a snapshot of JBoss server structure:

jboss weblogic

If you want to switch from one server to another, you have to provide the -c flag

ex. run.sh -c all  # Starts the “all” configuration which is the Cluster configuration

By default if no arguments are passed, the “default” configuration is started.

General configuration

The configuration of Weblogic server is centralized in the domain configuration file config.xml which contains details about all aspects related to the domain servers. The configuration is usually managed through the Administration console, so the file config.xml is seldom edited manually.

You can use however the config.xml file as reference for migrating services to JBoss.

 

<domain>
  <name>wl_server</name>
  <domain-version>10.3.0.0</domain-version>
  <jta>
    <name>wl_server</name>
    <timeout-seconds>500</timeout-seconds>
  </jta>
  <server>
    <name>examplesServer</name>
    <ssl>
      <name>examplesServer</name>
      <enabled>true</enabled>
      <listen-port>7002</listen-port>
    </ssl>
    <listen-address></listen-address>
  </server>
  <embedded-ldap>
    <name>wl_server</name>
    <credential-encrypted>{3DES}Pr9d/5UqhmPRhqUsksywzXLBiNjGyDRr0eDiQ4JSRyo=</credential-encrypted>
  </embedded-ldap>
  <configuration-version>10.3.0.0</configuration-version>
  <app-deployment>
    <name>mainWebApp</name>
    <target>examplesServer</target>
    <module-type>war</module-type>
    <source-path>/u02/oracle/wlserver_10.3/samples/server/examples/build/mainWebApp</source-path>
    <deployment-order>100</deployment-order>
    <security-dd-model>DDOnly</security-dd-model>
  </app-deployment>
 . . . .
 </domain>

In JBoss the configuration is largely pluggable. You can add and remove service by adding services in the “deploy” folder of your Server.

In the 4.x and earlier releases of JBoss Services are deployed as MBean Services which are pluggable JMX components. Each MBean service needs to follow the -service.xml file naming comvention and has a simple XML schema made up of MBean declaration, attribute list and (if any) dependancies with other Services.

  <mbean code="org.jboss.mail.MailService"
         name="jboss:service=Mail">
    <attribute name="JNDIName">java:/Mail</attribute>
    <attribute name="User">nobody</attribute>
    <attribute name="Password">password</attribute>
    <attribute name="Configuration">
      ........
    <depends>jboss:service=Naming</depends>
  </mbean>

From the 5.x release of JBoss some services are loaded using the Virtual file system framework and needs to follow the -jboss-beans.xml file naming convention:

<deployment xmlns="urn:jboss:bean-deployer:2.0">

   <!-- The provider for EJB2 UserTransactions -->
   <bean name="EJB2UserTransactionprovider" class="org.jboss.ejb.EJB2UserTransactionProvider">
      <constructor factoryClass="org.jboss.ejb.EJB2UserTransactionProvider" factoryMethod="getSingleton"/>
   </bean>

</deployment> 

Adding additional libraries to the Server

In Weblogic server the domain library directory is located at $DOMAIN_DIR/lib.

The jars located in this directory will be picked up and added dynamically to the end of the server classpath at server startup. The jars will be ordered lexically in the classpath. path.

It is possible to override the $DOMAIN_DIR/lib directory using the -Dweblogic.ext.dirs system property during startup. This property specifies a list of directories to pick up jars from and dynamically append to the end of the server classpath using java.io.File.pathSeparator as the delimiter between path entries.

In JBoss, if you want to add external libraries to the Server you need to copy the .jar files in the following directory:  

JBoss 4.x or earlier  JBoss_HOME/server/xxxx/lib
JBoss 5    JBoss_HOME/common/lib

Migrating Datasource configuration to JBoss

When you create a Datasource through the console, weblogic server keeps a reference to the Datasource in the config.xml file but stores in a separate file the details about the connection:

<jdbc-system-resource>
    <name>OracleDS</name>
    <target>examplesServer</target>
    <descriptor-file-name>jdbc/MyDatasource-jdbc.xml</descriptor-file-name>
</jdbc-system-resource>

Here is the file “MyDatasource-jdbc.xml”

<jdbc-data-source>
  <name>OracleDS</name>
  <jdbc-driver-params>
    <url>jdbc:bea:oracle://192.168.0.1:1521</url>
    <driver-name>weblogic.jdbc.oracle.OracleDriver</driver-name>
    <properties>
      <property>
        <name>user</name>
        <value>user</value>
      </property>
      <property>
        <name>portNumber</name>
        <value>1521</value>
      </property>
      <property>
        <name>SID</name>
        <value>MyDB</value>
      </property>
      <property>
        <name>serverName</name>
        <value>192.168.0.1</value>
      </property>
    </properties>
    <password-encrypted>{3DES}RohVNCrLGVWXH3zGrdMZPQ==</password-encrypted>
  </jdbc-driver-params>
  <jdbc-connection-pool-params>
    <test-table-name>SQL SELECT 1 FROM DUAL</test-table-name>
  </jdbc-connection-pool-params>
  <jdbc-data-source-params>
    <jndi-name>jdbc/MyDatasource</jndi-name>
    <global-transactions-protocol>None</global-transactions-protocol>
  </jdbc-data-source-params>
</jdbc-data-source>

In JBoss the Datasource is configured by simply adding a file xxx-ds.xml in the deploy
folder of your Server.

You can also deploy Datasource on an-application basis: see this tip:

http://www.mastertheboss.com/jboss-datasource/jboss-datasource-configuration

This is the corresponding JBoss datasource :

<datasources>
  <local-tx-datasource>
    <jndi-name>OracleDS</jndi-name>
    <connection-url>jdbc:oracle:thin:@192.168.0.1:1521:MyDB</connection-url>  
   <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>  
    <user-name>user</user-name>
    <password>password</password>
    
    <!--pooling parameters-->
    <min-pool-size>5</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <blocking-timeout-millis>5000</blocking-timeout-millis>
    <idle-timeout-minutes>15</idle-timeout-minutes>
      <metadata>  
         <type-mapping>Oracle9i</type-mapping>  
      </metadata> 

  </local-tx-datasource>

</datasources>

Using JBoss, take care to copy the Oracle drivers in the required folder (See previous point). With Weblogic Oracle drivers are already Included.

Porting Startup classes

Weblogic let you configure start-up classes which can be fired automatically when the server is started up.
jboss weblogic
Your startup class can be packaged in a .JAR an placed in the Server classpath.

In JBoss you don’t have the concept of start-up classes but you can emulate this behaviour by adding an MBean which performs the required action in the start(). The start method is recalled as soon as the MBean is deployed. Here’s a sample MBean:

public interface StartupMBean extends org.jboss.system.ServiceMBean
{
    public String getJndiName();
    public void setJndiName(String jndiName) throws NamingException;
} 

public class Startup extends org.jboss.system.ServiceMBeanSupport
    implements StartupMBean
{
    private String jndiName;
    
    
    public String getJndiName()
    {
        return jndiName;
    }

    public void setJndiName(String jndiName) 
        throws NamingException
    {
        
        this.jndiName = jndiName;
        
    }
    
    public void startService() throws Exception
    {
       // PLACE HERE YOUR STARTUP ACTIONS
    }

    public void stopService()
    {
        // PLACE HERE YOUR SHUTDOWN ACTIONS
    }
       
}

The MBeans, once compiled needs to be placed in an archive with the .SAR suffix.
This archive has a file descriptor in the META-INF folder which follows the XXX-service.xml pattern.

<server>
    <mbean code="com.sample.Startup" 
           name="com.sample:service=StartupClass">
        <attribute name="JndiName">jdbc/MyDatasource</attribute>
    </mbean>
</server> 

If you want to choose to order of Startup-up classes with JBoss you can use the “depends” element in the file descriptor. For example if you are going to add another Startup class “StartupClass2” to be executed after the one just added:

<server>
    <mbean code="com.sample.Startup2" 
           name="com.sample:service=StartupClass2">
        <attribute name="JndiName">jdbc/MyDatasource</attribute>
        <depends>jboss:service=StartupClass</depends>
    </mbean>
</server>