Tomcat to WildFly migration guidelines

Tomcat to WildFly / JBoss EAP migration is a typical scenario when you Web application requires some additional services (like JMS or transactions) which are available when using an application server. In this tutorial we will show some of the common pitfalls you can encounter when upgrading from Tomcat to WildFly / JBoss EAP

There are mainly three areas which you should consider in the migration path:

  • Common libraries
  • Data source configuration
  • JNDI bindings
  • Web context path
  • Core server configuration
  • JVM Options

Let’s see them all:

Common libraries migration

 Apache Tomcat stores the common libraries into the CATALINE_HOME/lib folder.

 The lib directory is the direct replacement for both common/lib and common/classes sub directories used in Apache Tomcat 5.x releases: it accepts both JARs and exploded class hierarchies.

When moving to WildFly you should place the common libraries in the following location:

JBoss / WildFly release Path for common libs
4.x JBOSS_HOME/server/[server-name]/lib
5.x – 6.x JBOSS_HOME/common/lib
7.x / WildFly JBOSS_HOME/modules

Check this tutorial if you want to learn how to install some libraries as modules into WildFly / JBoss EAP:

How to install a module on WildFly / JBoss EAP

JDBC configuration migration

A Datasource is configured in the context.xml file of Tomcat:

<Resource name="jdbc/oracledb"
    auth="Container"
    type="javax.sql.DataSource"
    username="scott"
    password="tiger"
    driverClassName="oracle.jdbc.driver.OracleDriver"
    url="jdbc:oracle:thin:@localhost:1521:XE"
    maxActive="10"
    maxIdle="2"
    removeAbandoned="true"
    removeAbandonedTimeout="30"
    maxWait="5000"
    logAbandoned="true"
    accessToUnderlyingConnectionAllowed="true"/>

Then, you should add your JDBC driver into CATALINA_HOME/lib folder

On the WildFly side, this is configured:

JBoss / WildFly Path for data source
4.x – 5.x – 6.x datasource-ds.xml file into JBOSS_HOME/server/[server-name]/deploy
7.x / WildFly server XML configuration file (e.g. standalone.xml) or datasource-ds.xml file into JBOSS_HOME/standalone/deployments or

More details about Datasource configuration here:

How to configure a Datasource with JBoss / WildFly

JNDI Bindings migration

A common source of problems is that each platform stores Objects under different locations of the JNDI tree. For example, here’s how you would retrieve the data source you have just configured in Tomcat:

DataSource ds = (DataSource)initContext.lookup("java:comp/env/jdbc/oracledb");

Don’t be surprised that this won’t work in WildFly. In particular, when using WildFly you have to choose a JNDI location like java:/ or java:/jboss for your datasources in order to be accepted. So, how’s a portable way to write a code that works in both environments ? The portable approach for defining data sources is to use a resource reference.

Resource references enable you to define the JNDI name for your data source, relative to your application naming context (java:comp/env), and then map that logical reference to the physical resource defined in the application server, whose JNDI name is proprietary to the application server. This approach enables your code and assembly to be portable to any compliant application server.

In our example, we need to define into your web.xml for your connection pool:

  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/oracledb</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>

Alternatively, starting in Java EE 5 (Servlet 2.5), this can be done even easier within your code using the @Resource annotation. Example:

@Resource(name = "jdbc/oracledb")
private DataSource dataSource;

Then, on add in your jboss-web.xml

<jboss-web>
 <resource-ref>
 <res-ref-name>jdbc/oracledb</res-ref-name>
 <jndi-name>java:jboss/datasources/jdbc/oracledb</jndi-name>
 </resource-ref>
</jboss-web>

Fine, now your JNDI lookup will work in either environment, without changing one line of code!

Web Context path

In Tomcat there are mainly two ways to define a context explicitly:

  • Create an XML file in the Tomcat conf/Catalina/localhost directory
<Context docBase="/path/to/web/app/myapp" reloadable="true" />
  • Or add a context element to the Tomcat conf/server.xml file
<Host name="localhost" appBase="webapp" autoDeploy="true">
    <Context path="/myapp" 
             docBase="/path/to/web/app/myapp"
             reloadable="true" />
</Host>

On the WildFly side, you can configure the Web context path within the jboss-web.xml file. Example:

<jboss-web>
    <context-root>/myapp</context-root>
</jboss-web>

Core Server configuration

As last option you should check if you have any customization in your apache tomcat’s server.xml. Although by default both Tomcat and WildFly are delivering http applications on port 8080, chances are that you might need configuring the http port. Here’s tomcat’s server.xml

<Connector port="32080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

If you are using JBoss AS 4/5/6 you can easily merge your server.xml configuration into jboss-web.sar/server.xml file.  If you are using WildFly, then you should either use one of the management interfaces (Web /CLI)

tomcat to jboss migration

You can also change it directly into standalone.xml/domain.xml file:

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
    <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
    <socket-binding name="http" port="${jboss.http.port:8080}"/>
    <socket-binding name="https" port="${jboss.https.port:8443}"/>
    <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
    <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
    <socket-binding name="txn-recovery-environment" port="4712"/>
    <socket-binding name="txn-status-manager" port="4713"/>
    <outbound-socket-binding name="mail-smtp">
        <remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
    </outbound-socket-binding>
</socket-binding-group>

If you want a complete article about Port configuration, check the following one: JBoss port configuration

JVM Options

Tomcat users typically set it in the JVM options in setenv.sh (for Linux/Mac) or setenv.bat (for windows)

export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxPermSize=256m"

WildFly users typically use the standalone.conf file for standalone servers:

if [ "x$JBOSS_JAVA_SIZING" = "x" ]; then
   JBOSS_JAVA_SIZING="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m"
fi

If you are running WildFly in domain mode, we recommend checking the following article:

Configuring JVM Settings in a WildFly / JBoss Domain

through the JAVA_OPTS variable in [path to tomcat]/bin/catalina.sh. Under windows there is a console where you can set it up or you use the catalina.bat.

from tomcat to jboss wildfly Suggested reading: From Tomcat to WildFly in one day.

A 100 pages long practical guide that will help you to get into WildFly configuration and deploy applications on it for users with a Tomcat background.

Covering all key aspects of software migration including core server configuration and its services, Tomcat application migration, porting Security and Clustering services to WildFly.

Found the article helpful? if so please follow us on Socials