Migrate WebSphere applications to JBoss EAP on Azure App Service

This guide describes what you should be aware of when you want to migrate an existing WebSphere application to run on Azure App Service using JBoss EAP.

Pre-migration

To ensure a successful migration, before you start, complete the assessment and inventory steps described in the following sections.

Inventory server capacity

Document the hardware (memory, CPU, disk) of the current production server(s) and the average and peak request counts and resource utilization. You'll need this information regardless of the migration path you choose. It's useful, for example, to help guide selection of the App Service Plan.

The list of available App Service Plan tiers shows the memory, CPU cores, storage, and pricing information. Note that JBoss EAP on App Service is only available on the Premium V3 and Isolated V2 App Service Plan tiers.

Inventory all secrets

Check all properties and configuration files on the production server or servers for any secrets and passwords. Be sure to check ibm-web-bnd.xml in your WARs. Configuration files that contain passwords or credentials may also be found inside your application. These files may include, for Spring Boot applications, the application.properties or application.yml files.

Inventory all certificates

Document all the certificates used for public SSL endpoints. You can view all certificates on the production server(s) by running the following command:

keytool -list -v -keystore <path to keystore>

Validate that the supported Java version works correctly

JBoss EAP on Azure App Service supports Java 8 and 11. Therefore, you'll need to validate that your application is able to run correctly using that supported version. This validation is especially important if your current server is using a supported JDK (such as Oracle JDK or IBM OpenJ9).

To obtain your current Java version, sign in to your production server and run the following command:

java -version

Inventory JNDI resources

Inventory all JNDI resources. Some resources, such as JMS message brokers, may require migration or reconfiguration.

Inside your application

Inspect the WEB-INF/ibm-web-bnd.xml file and/or the WEB-INF/web.xml file.

Determine whether databases are used

If your application uses any databases, you need to capture the following information:

  • The datasource name.
  • The connection pool configuration.
  • The location of the JDBC driver JAR file.

Determine whether and how the file system is used

Any usage of the file system on the application server will require reconfiguration or, in rare cases, architectural changes. File system may be used by WebSphere shared modules or by your application code. You may identify some or all of the following scenarios.

Read-only static content

If your application currently serves static content, you'll need an alternate location for it. You may wish to consider moving static content to Azure Blob Storage and adding Azure CDN for lightning-fast downloads globally. For more information, see Static website hosting in Azure Storage and Quickstart: Integrate an Azure storage account with Azure CDN.

Dynamically published static content

If your application allows for static content that is uploaded/produced by your application but is immutable after its creation, you can use Azure Blob Storage and Azure CDN as described above, with an Azure Function to handle uploads and CDN refresh. We've provided a sample implementation for your use at Uploading and CDN-preloading static content with Azure Functions.

Dynamic or internal content

For files that are frequently written and read by your application (such as temporary data files), or static files that are visible only to your application, you can mount Azure Storage into your App Service file system. For more information, see Mount Azure Storage as a local share in App Service.

Determine whether your application relies on scheduled jobs

Scheduled jobs, such as Quartz Scheduler tasks or Unix cron jobs, should NOT be used with Azure App Service. Azure App Service will not prevent you from deploying an application containing scheduled tasks internally. However, if your application is scaled out, the same scheduled job may run more than once per scheduled period. This situation can lead to unintended consequences.

To execute scheduled jobs on Azure, consider using Azure Functions with a Timer Trigger. For more information, see Timer trigger for Azure Functions. You don't need to migrate the job code itself into a function. The function can simply invoke a URL in your application to trigger the job.

Note

To prevent malicious use, you'll likely need to ensure that the job invocation endpoint requires credentials. In this case, the trigger function will need to provide the credentials.

Determine whether a connection to on-premises is needed

If your application needs to access any of your on-premises services, you'll need to provision one of Azure's connectivity services. For more information, see Connect an on-premises network to Azure. Alternatively, you'll need to refactor your application to use publicly available APIs that your on-premises resources expose.

Determine whether Java Message Service (JMS) Queues or Topics are in use

If your application is using JMS Queues or Topics, you'll need to migrate them to an externally hosted JMS server. Azure Service Bus and the Advanced Message Queuing Protocol (AMQP) can be a great migration strategy for those using JMS. For more information, see Use Java Message Service 1.1 with Azure Service Bus standard and AMQP 1.0.

If JMS persistent stores have been configured, you must capture their configuration and apply it after the migration.

Determine whether your application uses WebSphere-specific APIs

If your application uses WebSphere-specific APIs, you'll need to refactor your application to NOT use them. The Red Hat Migration Toolkit for Apps can assist with removing and refactoring these dependencies.

Determine whether your application uses Entity Beans or EJB 2.x-style CMP Beans

If your application uses Entity Beans or EJB 2.x style CMP beans, you'll need to refactor your application to remove these dependencies.

Determine whether the JavaEE Application Client feature is used

If you have client applications that connect to your (server) application using the JavaEE Application Client feature, you'll need to refactor both your client applications and your (server) application to use HTTP APIs.

Determine whether your application contains OS-specific code

If your application contains any code with dependencies on the host OS, then you need to refactor it to remove those dependencies. For example, you may need to replace any use of / or \ in file system paths with File.Separator or Paths.get if your application is running on Windows.

Determine whether EJB timers are in use

If your application uses EJB timers, you'll need to validate that the EJB timer code can be triggered by each JBoss EAP instance independently. This validation is needed because when your App Service is scaled our horizontally, each EJB timer will be triggered on its own JBoss EAP instance.

Determine whether JCA connectors are in use

If your application uses JCA connectors, you'll need to validate that the JCA connector can be used on JBoss EAP. If the JCA implementation is tied to WebSphere, you'll need to refactor your application remove the dependency on the JCA connector. If the JCA connector can be used, then you'll need to add the JARs to the server classpath. You'll also need to put the necessary configuration files in the correct location in the JBoss EAP server directories for it to be available.

Determine whether JAAS is in use

If your application uses JAAS, you'll need to capture how JAAS is configured. If it's using a database, you can convert it to a JAAS domain on JBoss EAP. If it's a custom implementation, you'll need to validate that it can be used on JBoss EAP.

Determine whether your application uses a Resource Adapter

If your application needs a Resource Adapter (RA), it needs to be compatible with JBoss EAP. Determine whether the RA works fine on a standalone instance of JBoss EAP by deploying it to the server and properly configuring it. If the RA works properly, you'll need to add the JARs to the server classpath of the App Service instance and put the necessary configuration files in the correct location in the JBoss EAP server directories for it to be available.

Determine whether your application is composed of multiple WARs

If your application is composed of multiple WARs, you should treat each of those WARs as separate applications and go through this guide for each of them.

Determine whether your application is packaged as an EAR

If your application is packaged as an EAR file, be sure to examine the application.xml and ibm-application-bnd.xml files and capture their configurations.

Identify all outside processes and daemons running on the production servers

If you have any processes running outside the application server, such as monitoring daemons, you'll need to eliminate them or migrate them elsewhere.

Migration

Red Hat Migration Toolkit for Apps

The Red Hat Migration Toolkit for Applications is a free extension for Visual Studio Code. This extension analyzes your application code and configuration to provide recommendations for migrating your Jakarta EE applications to JBoss EAP from other app servers, such as removing dependencies on proprietary APIs. The extension will also provide recommendations if you're migrating to the cloud from on-premises. For more information, see Migration Toolkit for Applications overview.

The contents of this guide will help you address the other components of the migration journey, such as choosing the correct App Service Plan type, externalizing your session state, and using Azure to manage your EAP instances instead of the JBoss Management interface.

Provision an App Service plan

From the list of available service plans, select the plan whose specifications meet or exceed the specifications of the current production hardware.

Note

If you plan to run staging/canary deployments or use deployment slots, the App Service plan must include that additional capacity. We recommend using Premium or higher plans for Java applications.

Create that app service plan.

Create and deploy web app(s)

You'll need to create a Web App on your App Service Plan for every WAR file deployed to your JBoss EAP server.

Note

While it's possible to deploy multiple WAR files to a single web app, this is highly undesirable. Deploying multiple WAR files to a single web app prevents each application from scaling according to its own usage demands. It also adds complexity to subsequent deployment pipelines. If multiple applications need to be available on a single URL, consider using a routing solution such as Azure Application Gateway.

Maven applications

If your application is built from a Maven POM file, use the Webapp plugin for Maven to create the Web App and deploy your application. For more information, see the Configure the Maven plugin section of Quickstart: Create a Java app on Azure App Service.

Non-Maven applications

If you can't use the Maven plugin, you'll need to provision the Web App through other mechanisms, such as:

After you've created the web app, use one of the available deployment mechanisms to deploy your application. For more information, see Deploy files to App Service.

Migrate JVM runtime options

If your application requires specific runtime options, use the most appropriate mechanism to specify them. For more information, see the Set Java runtime options section of Deploy and configure a Tomcat, JBoss, or Java SE app in Azure App Service.

Populate secrets

Use Application Settings to store any secrets specific to your application. If you intend to use the same secret or secrets among multiple applications, or you require fine-grained access policies and audit capabilities, use Azure Key Vault references instead. For more information, see Use Key Vault references as app settings in Azure App Service and Azure Functions.

Configure custom domain and SSL

If your application will be visible on a custom domain, you'll need to map your web application to it. For more information, see Tutorial: Map an existing custom DNS name to Azure App Service.

You'll then need to bind the TLS/SSL certificate for that domain to your App Service Web App. For more information, see Secure a custom DNS name with a TLS/SSL binding in Azure App Service.

Migrate data sources, libraries, and JNDI resources

To migrate data sources, follow the steps in the Configure data sources for a Tomcat, JBoss, or Java SE app in Azure App Service.

Migrate any additional server-level classpath dependencies. For more information, see Configure data sources for a Tomcat, JBoss, or Java SE app in Azure App Service.

Migrate any additional shared server-level JDNI resources. For more information, see Configure data sources for a Tomcat, JBoss, or Java SE app in Azure App Service.

Note

If you're following the recommended architecture of one WAR per application, consider migrating server-level classpath libraries and JNDI resources into your application. Doing so will significantly simplify component governance and change management. If you want to deploy more than one WAR per application, you should review one of our companion guides mentioned at the beginning of this guide.

Migrate scheduled jobs

At a minimum, you should move your scheduled jobs to an Azure VM so they're no longer part of your application. Alternately, you can opt to modernize them into event driven Java using Azure services such as Azure Functions, SQL Database, and Event Hubs.

Restart and smoke-test

Finally, you'll need to restart your Web App to apply all configuration changes. Upon completion of the restart, verify that your application is running correctly.

Post-migration

Now that you've migrated your application to Azure App Service, you should verify that it works as you expect. Once you've done that, we have some recommendations for you that can make your application more Cloud native.

Recommendations