A Step-by-Step Guide to Migrating Java EE Applications to DC/OS

For more than five years, DC/OS has enabled some of the largest, most sophisticated enterprises in the world to achieve unparalleled levels of efficiency, reliability, and scalability from their IT infrastructure. But now it is time to pass the torch to a new generation of technology: the D2iQ Kubernetes Platform (DKP). Why? Kubernetes has now achieved a level of capability that only DC/OS could formerly provide and is now evolving and improving far faster (as is true of its supporting ecosystem). That’s why we have chosen to sunset DC/OS, with an end-of-life date of October 31, 2021. With DKP, our customers get the same benefits provided by DC/OS and more, as well as access to the most impressive pace of innovation the technology world has ever seen. This was not an easy decision to make, but we are dedicated to enabling our customers to accelerate their digital transformations, so they can increase the velocity and responsiveness of their organizations to an ever-more challenging future. And the best way to do that right now is with DKP.

Apr 12, 2018

Mark Johnson


In the prior blog post we discussed the benefits of migrating legacy Java EE applications to a modern platform such as Mesosphere DC/OS. This blog post presents a set of concrete steps to make this possible.

For our migration we have a legacy Java EE application running on Oracle's WebLogic. We don't have time to re-code the application (although our team has already requested resources for a complete re-write to Spark or Node) and the application is currently chewing up a lot of CPU and memory resources running in a virtual machine.Our goal is to migrate the app to a modern platform quickly and without changes. This tutorial walks you through the steps needed to accomplish this:


Java EE App Migration: Planning and Resource Availability

Before we start the application migration process, we need to do some up-front information gathering and planning to make sure the process goes smoothly. Our migration checklist includes:

.blog-table td{ padding:5px 7px;}


CheckDiscovered Value
App Deployment StyleWAR file
App ServerWebLogic 12c
App Path/benefits
 External properties or Jar filesNone (note: the approach described in this blog can be extended to support external properties and Jar files)
Total # Apps to Migrate100+
1st App to MigrateBenefits
Resources to Migrate for 1st AppBenefits.war

For your application migration process, update the discovered values with your own values. For our checklist, let's walk through a step by step migration of our first app, Benefits.


After collecting data, we can start the migration process. Our first step is to check the Dashboard page in DC/OS for available cluster resources. We only need to account for the application resource requirement, not for any virtual machine system overhead since DC/OS runs directly on the bare-metal machine. Assuming we only need one or two cores per app, with roughly 24 free CPU cores and just under 100 GB RAM available, we have plenty of room to migrate the first group of apps.

Mesosphere DC/OS Java EE Tutorial

Adding a Java EE App as a New Service in DC/OS

Now that we've confirmed we're good to go, let's add a new service by clicking the ‘+' icon at the top right side of the screen.

Mesosphere DC/OS Java EE Tutorial

Then select ‘Single Container' mode so we can begin defining our new Java EE service.

Mesosphere DC/OS Java EE Tutorial



  • This app is one of many assigned to the department ‘dept-a', one of many in the organization.
  • We need to deploy the application to Oracle WebLogic Server.
  • We must dynamically build and deploy our app. We have over 100 legacy apps and we don't want to manually manage and patch code in that many containers.
  • The application must be deployed in a manner to support scalability.

Mesosphere DC/OS supports the concept of Application Groups. For our migration, we will insert this application into an application group. To add our application to the ‘dept-a' application group we will specify the Service ID in the format of ‘/dept-a/weblogic-benefits-app'.

We review our app's past performance and see that the minimum requirements are 1 CPU core (the prior machine deployed with oversubscription had 4 cores allocated) and roughly 2GB of RAM. For most of the time, we will need only 1 instance, so let's specify 1 CPU, 1 Instance, and 2048 MB of RAM.

We have a choice of one of two container runtimes: the official Docker daemon runtime and the Mesos Universal Container Runtime (UCR). The choice is yours, but we'll select the Mesos UCR because it offers additional features, is fully compatible with Docker images, and anecdotally seems more reliable in our testing.

Do not to select the "Force Pull On Launch" option as this will degrade performance in production. Selecting this option favors flexibility over performance, causing DC/OS to re-pull the Docker image from the repository every time the app is restarted or re-scaled.

Instead, we can dynamically build and deploy our application using the DC/OS fetch capability while avoiding recurrent patching of hundreds of Docker images. The DC/OS fetcher downloads the resource specified in the ‘Artifact URI' into the container. For our migration, we can leverage this functionality by specifying the WAR file containing our application. In this manner we are only utilizing one ‘base' Docker image which in this case is ‘tkrausjr/1221-appdeploy:v2'. In this way, patching the OS or the WebLogic Application server requires modifying and updating only our base image.

We can enter any valid shell script command into the Command section. In this example, we enter env | sort && ls -lt /u01/oracle && pwd to provide us with debugging information relating to the active environment variables and the content of the directories of interest. The next part && mv /mnt/mesos/sandbox/benefits.war /u01/oracle/benefits.war of the command is where we move the benefits.war file which was fetched by the Artifact URI from the /mnt/mesos/sandbox directory into the /u01/oracle directory for the WebLogic WLST application's consumption.

Our next step is to run the WLST app-deploy script. This script takes some of the environmental variables (defined later) and deploys our benefits.war application into WebLogic using the command && wlst /u01/oracle/app-deploy.py. Assuming the app has properly deployed within WebLogic, we are ready to start WebLogic using the command && startWebLogic.sh

Mesosphere DC/OS Java EE Tutorial

Configuring Networking and Load Balancing

Our legacy Java EE app now needs its networking settings specified, making sure to avoid host server port conflicts. We also need to set up load balancing to scale our app on its new platform. Select ‘Networking' from the left command bar to display our list of options as shown below.

Mesosphere DC/OS Java EE Tutorial

Our application requires port 8001 and we want the flexibility for it to run on a private agent so we've specified ‘Bridge' networking and added a container port 8001 for mapping to the host. DC/OS will select the host port (the port running the actual server node for the cluster) in order to prevent contention.

Selecting ‘Enable Load Balance Service Address' allows us to support multiple application instances. This automatically creates a DNS address available to all permitted DC/OS services following the pattern of {Application name}.marathon.l4lb.thisdcos.directory:{load balance port number}. Now we can have services, jobs, and DC/OS tasks communicate with our migrated Java EE app without changing any code or worrying about which instance they are communicating with.

Configuring Health Checks for Java EE Apps in DC/OS

DC/OS offers a full suite of storage options, but as our application does not require storage at this time, the description of these storage options will have to wait for a future blog.  Instead our attention needs now to focus on the health check.

DC/OS health checks enable our ancient legacy application to enjoy the scalability and high-availability benefits of a modern platform. When an app is reported "healthy", DC/OS knows it can serve requests to it. When an app is reported "unhealthy", DC/OS knows that it needs to start up a new instance. If the server instance hosting the application fails, or undergoes any maintenance effort such as OS patching and restart, DC/OS will automatically restart the application on another server instance..

There are two types of DC/OS health checks: HTTP and Command. For our Java EE app, we choose the HTTP option because it is the simpler of the two and satisfies the app's availability requirements. Command allows for the use of sophisticated commands to fully validate the health of an application and should always be considered when high availability is required.

To enable the HTTP health check, select the HTTP option from the dropdown as shown in the image below:

Mesosphere DC/OS Java EE Tutorial

Our next step is to select the service endpoint we defined earlier (‘weblogic-management-server') from the drop-down list. Enter ‘/benefits' as the health check path as that's how the app was referenced on the prior platform.

Mesosphere DC/OS Java EE Tutorial

After entering our settings and accepting the other settings as their defaults, we see the following instructions defining our health check:

Mesosphere DC/OS Java EE Tutorial

Defining Environmental Variables and Managing Secrets for Java EE Apps in DC/OS

Our next step is to define the environmental variables required for the WebLogic application deployer and the WebLogic application server. This method also works for the other common Java EE application servers. DC/OS allows you to define environmental variables in one place as part of the application definition that is reference by all container instances of our migrated app. This not only simplifies application deployment, but also allows you to change the environmental variables in a single location, as needed, without having to restart or rebuild a container.

Mesosphere DC/OS Java EE Tutorial

At the bottom of the Environment screen are two interesting sections: Labels and Secrets. Labels is where we define meta information for the application. For example, specifying ‘HAPROXY_GROUP' with the value ‘external' relies on Marathon-lb to make your migrated Java EE app available outside the DC/OS cluster.

A major problem most legacy Java EE apps suffer from is a lack of security around the application server and database passwords. The people charged with maintaining the app need these passwords to fix problems as they come up and, because of the challenges associated with changing these passwords, they often go unchanged for years and even decades.

The DC/OS Secrets Manager solves the age-old problem of publicly known and static passwords. The DC/OS administrator can define any number of secrets containing the passwords to application servers, databases, LDAP servers, and any other secured resource.  The administrator then provides the application owner with the secret name and not the actual secret. The application owner then selects the secret for their application and a variable name, which in this case the WebLogic Application server will recognize.

We need the environmental variable "ADMIN_PASS' to provide the WLST application deploy script with sufficient permissions, and that password is contained in the secret ‘ADMIN_PASS'.

Mesosphere DC/OS Java EE Tutorial

Administrators can now change the app server and database passwords and, when the migrated Java EE application is restarted, those passwords will take effect.

Launching the Migrated Java EE App

Our migration definition steps are now complete. All that's left is to click ‘Review & Run' and then click ‘Run Service'.

Mesosphere DC/OS Java EE Tutorial

Once deployment commences, we can monitor our newly migrated Java EE app from the ‘Tasks' screen. As we see below, the deployment is currently ‘Staging', which means it is pulling down the Docker image. Staging takes a minute or so, a significant improvement over requesting a new server and installing it manually, because of the size of the WebLogic application server. The staging process can be decreased by removing unnecessary components from your base image.

Mesosphere DC/OS Java EE Tutorial

Our Java EE app is now up and running in a healthy state. We have deployed a single instance (for now) to the host server

Monitoring Java EE Apps in DC/OS

Mesosphere DC/OS Java EE Tutorial

We can quickly check the WebLogic logs by clicking the icon that has the ‘View logs' callout (as shown above) without having to SSH into individual servers.

Mesosphere DC/OS Java EE Tutorial

Once our application is running and healthy, it's time to check our Haproxy status page by opening the URL http://{public ip}:9090/haproxy?stats. Looking through the list, we see our app referenced in "dept-a_weblogic-benefits-app_10100". This tells us that the public port is "10100".

Mesosphere DC/OS Java EE Tutorial


Knowing that the public IP address is "", we can access our migrated Java EE app via, which provides the result as shown below. We have successfully migrated our legacy Java EE app to a modern platform with the ability to elastically scale and automatically recover from any form of application outage.

Mesosphere DC/OS Java EE Tutorial

In the next blog post in this series, we will take our migrated application and explore more benefits of running it on a modern application platform like DC/OS. Please join our Painless Modernization of Java EE Applications webinar for more information.

Ready to get started?