Application Modernization - Exercise 1
Migrate a Java EE app that requires no code changes
This exercise shows how to handle a “no code changes required” modernization of an existing traditional WebSphere Application Server Network Deployment (WebSphere ND) application to WebSphere Liberty running in a Docker container.
This exercise assumes the following:
- You are using a Developer Environment that has already been installed.
- Cloud Pak for Applications has already been installed in the environment.
- You have Docker Desktop running on your laptop (one of the prerequisites).
This exercise consists of the following sections:
- Scan the existing application
- Analyze the scan results
- Migrate to WebSphere Liberty
- Run the application on Liberty
This WebSphere Application Server customer finds itself in a common situation: They have a bunch of legacy monolithic applications running in WebSphere Application Server Network Deployment (WebSphere ND) on traditional IT. This was state-of-the-art back when the applications were first deployed, but the runtime requires periodic maintenance and constant administration. Now the customer would like to host the application in a cloud environment, but they have no desire to make any code changes to move the apps. While it might be beneficial for the customer to invest money in rethinking and redesigning their entire portfolio of applications to move off of traditional WebSphere, in reality this is overkill for applications that still provide the proper business functionality just fine. For these legacy monoliths, we can reduce the maintenance overhead by moving to WebSphere Liberty and running on Red Hat OpenShift. We can also reduce the administrative overhead by implementing a common CI/CD and SRE practices.
In this exercise, you will learn the skills to be able to demonstrate how some applications can be moved to Liberty in a Docker container without the need to make code changes. This approach known as runtime modernization, which doesn’t address the technical debt in the application but does remove the technical debt created by the WebSphere Application Server runtime. This approach can also be used to migrate applications running in other Java EE servers like Oracle WebLogic Server or Apache Tomcat. We will migrate the application using IBM Cloud Transformation Advisor. This approach is one strategy for the overall modernization of a legacy Java application portfolio and an important skill to have.
Here’s the hill statement describing the desired outcome of this migration:
Who: Operations teams are tasked with moving existing Java applications from traditional WebSphere ND to “the Cloud” and don’t have access to developers for the majority of the legacy Java portfolio.
What: This is an application that users still need. They consider it good enough as-is: While bug fixes and new features might be desirable, the aren’t worth the expense. Or step 1 for making the app more maintainable is moving it to the cloud where it’ll be easier to improve it using modern development techniques like continuous deployment. The operations team needs to move to “the Cloud” and wants to standardize on Docker containers that they can run anywhere.
Wow: With a few simple steps, you can move an application and the associated configuration to a Liberty runtime in a Docker container without changing code. This is something that can be repeated over and over on many apps in the portfolio in a factory type engagement.
PlantsByWebSphere is a simple legacy monolith that runs in WebSphere Application Server with a backend database (DB2). The diagram below shows a typical customer environment with IBM HTTP Server and WebSphere Application Server Network Deployment (WebSphere ND) running on traditional IT along with the application database.
The target for the runtime modernization is shown below with the containerized application running on Liberty on OpenShift Container Platform and the application database remaining on traditional IT.
For the purposes of this lab exercise, you will run a simulation of the WebSphere ND environment on your laptop using a Docker container that contains PlantsByWebSphere, WebSphere Application Server, and a data collector. You will then use IBM Cloud Transformation Advisor—part of the Cloud Pak for Applications installed in your team’s Developer Environment—to analyze the WebSphere ND environment and create the artifacts you need to run the same PlantsByWebSphere application on Liberty in a Docker container on your laptop.
This modernization exercise has the following requirements:
- No code changes — You don’t even have access to source code
- The target is to get the application running on Liberty in a Docker container on your laptop
- The DB2 database will remain in its current location — It is deployed in a container in the MOOC4 environment, exposed with a NodePort
This exercise has the following steps:
- Run a pre-configured instance of traditional WebSphere in a Docker container on your laptop to simulate the existing customer environment
- Use the data collector in Transformation Advisor to scan the WebSphere runtime and the PlantsByWebSphere application
- Load the scan results in to Transformation Advisor running in your MOOC environment’s Red Hat OpenShift cluster
- Review the Transformation Advisor analysis
- Use the accelerators to build a Docker image with Liberty and the application
- Run the newly created Docker image with application on Liberty on your laptop to demonstrate success
We need to first have the application installed and running so that we can scan it.
In order to simulate a real traditional WebSphere ND customer environment on your laptop, we have provided you with a Dockerfile that creates a Docker image that you can run locally. This image will contain traditional WebSphere, the PlantsByWebSphere application, and the data collector in Transformation Advisor. The end result will be a container running the application which accesses the shared database.
Clone the repository to your machinegit clone https://github.com/ibm-cloud-architecture/icp-dev-workshop.gitcd icp-dev-workshop/lab4/CreatePreConfiguredtWASContainer
Review the Dockerfile, see that the Docker image will contain:
- The DB2 JDBC drivers
- wsadmin scripts — Used to configure the WebSphere application server for the PlantsByWebSphere application
- Compiled application EAR files
- The data collector in Transformation Advisor — This was split in to 50mb chunks so it could easily be stored in GIT
This file is used to ensure that the data collector scans all of the files in the application. By default, the data collector ignores Java classes in the
com.ibm.webspherepackages, as well as packages that are typically used by open-source JARs such as
orgpackages. These packages are ignored because they typically contain code that the client doesn’t own, so any issues found by Transformation Advisor would be false positives. This becomes a problem when the client’s code is in a package such as
orgbecause the scanner will ignore their Java code.evaluation=--evaluate --excludePackages=com.informix,com.microsoft,com.sybase,com.sun,java,javax,net,org,oracle,sqlj,_ibmjsp --includePackages=com.ibmmigration_liberty=--analyze --sourceAppServer=was855 --targetAppServer=liberty --targetCloud=dockerIBMCloud --includePackages=com.ibm --excludePackages=com.informix,com.microsoft,com.sybase,com.sun,java,javax,net,org,oracle,sqlj,_ibmjspmigration_was=--analyze --sourceAppServer=was855 --targetAppServer=was90 --targetCloud=vmIBMCloud --includePackages=com.ibm --excludePackages=com.informix,com.microsoft,com.sybase,com.sun,java,javax,net,org,oracle,sqlj,_ibmjsp#inventory=--inventory --excludeFiles=".*/directory/LargeXMLFileName.xml"#featureList=--featureList --excludeFiles=".*/directory/LargeXMLFileName.xml"#java_opt=-Xmx2g
- Ensure that the
portfor the DataSources match the values of your DB2 database (above)
- Ensure that the
Build the Docker imagedocker build -t twas-plantsbywebsphere .
Review the Docker image for traditional WebSphere Application Server$ docker images | grep websphereREPOSITORY TAG IMAGE ID CREATED SIZEibmcom/websphere-traditional profile 67b52a4c08ad 12 months ago 1.75GBibmcom/websphere-liberty webProfile7-ubi-min-amd64 34544a83c068 3 weeks ago 446MB
websphere-libertyimage is shown here for comparison. You may not see it in your registry (yet).)
You may be wondering: If traditional WebSphere runs in a Docker container, then why are we moving to Liberty?
One reason: 1.75GB!! (The Liberty image is 446MB, one-quarter the size.)
Another reason: Having to hardcode configuration values in configuration files (like in the previous step) because traditional WebSphere can’t read configuration from environment variables
Start an instance of the Docker imagedocker run -d -p 9080:9080 -p 9443:9443 -p 9060:9060 -p 9043:9043 -v "$(pwd)":/data --name twas-plantsbywebsphere twas-plantsbywebsphere:latest
Tail the logs for the Docker container and wait for the message shown below:$ docker logs -f twas-plantsbywebsphere...*** CERTIFICATES THAT ARE EXPIRED OR BEYOND THE EXPIRATION THRESHOLD AND HAVE BEEN REPLACED ***;CWPKI0645I: Personal certificate alias "default" in KeyStore "NodeDefaultKeyStore((cell):DefaultCell01:(node):DefaultNode01)" was REPLACED.CWPKI0645I: Personal certificate alias "default" in KeyStore "NodeRSATokenKeyStore((cell):DefaultCell01:(node):DefaultNode01)" was REPLACED.
This message is expected because this version of the traditional WebSphere Docker image is over 12 months old and the SSL certificates have expired.
Restart the container to refresh these SSL certificatesdocker stop twas-plantsbywebspheredocker start twas-plantsbywebsphere
Tail the logs for the Docker container and wait for the message shown below:$ docker logs -f twas-plantsbywebsphere...WSVR0001I: Server server1 open for e-business
Log in to the Administrative Console
NOTE: The console requires secure HTTP. Chrome and Safari block https://localhost and recently don’t allow exceptions. You may need to use Firefox to log in to the console. Firefox blocks, but gives you the option to proceed anyways.
Applications --> Application Types --> WebSphere enterprise applicationsand verify that you see
Resources --> JDBC --> DataSourcesand verify that you see
PlantsByWebSphereDataSourceNONJTA. These are the two DataSources that will be detected by the data collector.
Log out of the Administrative Console
Access PlantsByWebSphere using http://localhost:9080/PlantsByWebSphere
Click on one of the Specials such as the “Bonsai Tree”. If the screen shown below is displayed, the connection to the Database is working correctly.
Run the data collector
Now that you have validated that the PlantsByWebSphere application is running in the Docker container, it is time to run the data collector.
Enter the twas-plantsbywebsphere Docker containerdocker exec -it twas-plantsbywebsphere bash
Navigate to the data collector directorycd /demo/transformationadvisor-2.0.1
Execute the data collector./bin/transformationadvisor -w /opt/IBM/WebSphere/AppServer -p AppSrv01 wsadmin passw0rd
When prompted, accept the License agreement
After a few minutes, you will either see a “Thank you for uploading your data. You can proceed to the application UI for doing further analysis.” message or an error related to “unable to upload the data” which will occur if the data collector can’t access the Transformation Advisor UI which is running in Red Hat OpenShift.
Verify that the results zip file has been created$ ls -la AppSrv01.zip-rw-r--r-- 1 was was 340860 Nov 22 15:32 AppSrv01.zip
Use CTRL+D to exit from the Docker container
AppSrv01.zipfile from within the Docker container to your local diskdocker cp twas-plantsbywebsphere:/demo/transformationadvisor-2.0.1/AppSrv01.zip .
Stop and remove the Docker containerdocker stop twas-plantsbywebspheredocker rm twas-plantsbywebsphere
In this section, you will upload the results from the data collector to the Transformation Advisor UI and analyze the findings.
Use the Developer Dashboard to open the Transformation Advisor dashboard
- The browser may display the message “Authentication endpoint is broken at the moment.” To solve the problem, open the URL in a new incognito browser tab.
Add a new workspace named
Add a new collection named
Upload dataand specify the
AppSrv01.zipfile you created from scanning the app
After a few moments, the UI will display the Results page.
Review the results
Take a moment to review the results. Transformation Advisor has determined this application is “simple” to move to Liberty on Private Cloud.
What happens if you change the Preferred migration target to Liberty on Public Cloud? Why did the complexity change?
Hold your mouse over the “Complex” box. Why does Transformation Advisor think you need a VPN?
Click on the the
PlantsByWebSphere8.earand read the Public Cloud to Private Cloud Network Connection result.
Scroll down and note the External Dependencies that have been detected to be required by this application. Remember the DB2 database? Transformation Advisor detected that the application uses the database. It is telling you that either you will need to move the database to the public cloud or the application in the pubic cloud will need a network connection—probably a VPN—to the database in the private data center.
- Click the
<-- Recommendationslink at the top of the page to return to the Recommendations page, then set the Preferred migration target to Liberty on Private Cloud once again
Review the reports
Take a moment to review the reports. Make sure the Transformation Advisor UI is displaying the Results page and that the Preferred migration target is set to Liberty on Private Cloud.
Click on the the
PlantsByWebSphere8.earagain and review the Technology Issues section
Scroll to the bottom of the page and review the Technology Report, Inventory Report, and Analysis Report
Note that at the top of each report, the command line parameters are shown. This helps to validate that your settings in
customCmd.properties have been detected.
Review each of the reports:
Lists the Java EE features used by the application
Maps these features to the capabilities of the various WebSphere editions
This is a useful first step to determining whether this application will run on Liberty.
Lists the Java EE components in the application
This helps give an idea of the size of the monolith and identify the number of EJBs and web services.
Shows the application structure
This shows which JARs are included in the application, which helps identify technical debt such as old versions of Struts, Spring, and Hibernate, and whether the application packages IBM or JEE JARs that can cause classloading issues later.
Lists the Utility JAR files
This shows which packages are in each JAR, which is especially useful if the client doesn’t know which Java packages to scan. If you find this part of the report lists client code in packages that the scanner ignored such as
net, you will need to update the
customCmd.propertiesfile to include these packages and re-run the scan.
Lists the issues found during the scan of the application
Review the Severe and Warning results using the
show rule helpand
show resultslinks. Note that the one severe result for this application is related to the user of
sendRedirect; if problems are encountered during testing, the solution is to set a JVM property.
Close the open report tabs and return to the Recommendations page
Let’s go ahead and move this application to Liberty.
Transformation Advisor creates some accelerators to speed up the process of migrating an application. These files are a starting point for most modernization journeys and require modification. In this section, you will modify those files for PlantsByWebSphere.
From the main recommendations page, click the
...link on the right for the
PlantsByWebSphere8.earand select View migration plan
The migration plan shows the files that Transformation Advisor has generated:
- server.xml - Transformation Advisor extracts most of the configuration from traditional WebSphere and generates a server.xml for Liberty to use
- Dockerfile - Used to create the Docker image, which includes the application and configuration for Liberty
- Operator resources - Used in Red Hat OpenShift to deploy the application using the Open Liberty operator
- pom.xml - Used for Maven builds, particularly useful if the application does not already employ build scripts
We need to download these files and put them in the correct directory structure.
lab4folder, create a
libertysubdirectorycd ..mkdir libertycd liberty
Dockerfilefrom Transformation Advisor and place them in
- If Dockerfile gets renamed to
Dockerfile.txtduring the download, rename it to
- If Dockerfile gets renamed to
The original application is in the directory
lab4/binary. We will copy the Ear file and DB2 driver files from the original application to the new Liberty application. Notice that we simply copy the Ear file, that we don’t make any changes to the Java code or otherwise recompile the Ear. Also notice that Liberty uses the same DB2 drivers that WebSphere Application Server does.
lab4/binary/applicationand place it in
lab4/binary/liband place them in
Now let’s make sure we have all of the right files in all of the right directories.
Issue the command
ls -laRin the
libertyfolder and validate your structure is as shown below:
Ideally, Transformation Advisor could figure out enough from the original application so that the generated files contain exactly what’s needed and we could use these files as-is. Unfortunately, there are some details Transformation Advisor cannot discern, so we’ll need to add those into the files manually.
server.xmlfile using your favorite editor to make the following changes:
In the dataSources, for the jdbcDriverRefs
DB2_Universal_JDBC_Driver_Provider_(XA), change the DB2 driver locations to be
/config/lib/db2jcc_licence_cu.jar. (THERE ARE TWO SETS OF FILE NAMES THAT MUST BE CHANGED)
PlantsByWebSphereDataSourceNONJTAdatasource, in the
user="db2inst1" password="db2Pa2359w0rd123" transactional="false"
PlantsByWebSphereDataSourcedatasource, in the
user="db2inst1" password="db2Pa2359w0rd123" transactional="true"
location="plantsbywebsphere8-1.0.0.war" name="PlantsByWebSphere8" type="war"/>to
location="plantsbywebsphere8.ear" name="PlantsByWebSphere8" type="ear"/>
Save your changes
server.xml should look like this:
<?xml version="1.0" encoding="UTF-8"?><!--Generated by IBM TransformationAdvisorThu Nov 21 20:49:39 GMT 2019--><server><!--These elements have been identified from this application's configuration.--><featureManager><feature>beanValidation-1.1</feature><feature>cdi-1.2</feature><feature>ejbLite-3.2</feature><feature>el-3.0</feature><feature>javaMail-1.5</feature>
Since we want the migrated application to run in a Docker container, we need a script that creates the Docker image.
Review the generated Dockerfile,
Note that this Dockerfile expects the Maven build to be triggered as part of this Docker build and then the generated War is copied to the Liberty runtime. This is NOT how we want to build the application.
Replace the entire contents of the Dockerfile with this:FROM ibmcom/websphere-liberty:webProfile7-ubi-min-amd64ARG SSL=trueARG MP_MONITORING=trueARG HTTP_ENDPOINT=falseCOPY ./server.xml /configCOPY ./binary/application/* /config/apps/
Now that we’ve configured Liberty and the application, let’s run it.
Now you are ready to build and run the Docker image that contains WebSphere Liberty and the PlantsByWebSphere application.
Build the Docker imagedocker build -t plantsbyliberty .
Check the size of the newly created image
Note that it is much smaller (one-quarter size) than the traditional WebSphere image and therefore more cloud ready.$ docker images | grep plantsbyREPOSITORY TAG IMAGE ID CREATED SIZEplantsbyliberty latest b26439433e5a 2 days ago 609MBtwas-plantsbywebsphere latest 12705d97f4b4 12 days ago 2.44GB
Run an instance of the new containerdocker run -d -p 9080:9080 -p 9443:9443 --name plantsbyliberty plantsbyliberty
Tail the logs for the Docker container
- Wait for the message
CWWKT0016I: Web application available (default_host): http://0c59e31137ff:9080/PlantsByWebSphere/to be displayed
- Wait for the message
Test the app
Open browser to http://localhost:9080/PlantsByWebSphere
Confirm the app is working as expected with the DB2 data by clicking the
Bonsai Treelink in the
Specialssection and validating that the photo is correctly displayed
Stop the Docker container and remove itdocker stop plantsbylibertydocker rm plantsbyliberty
That’s it. You now have this application running on Liberty in a Docker container which is sufficient for this exercise.
Deployment to OpenShift is out of scope for this exercise. In a real MVP, here’s the tasks you would perform to deploy the app using the Docker image:
Automate the build process for the application code. This would require you to load the source code in to Git and configure a build tool such as Maven to compile the application and create the EAR/WAR file. The steps to achieve this are documented in Modernizing the build process of existing Java EE applications with Maven.
Externalize configuration parameters such as the database IP, port, and username/password to enable the same image to be deployed in different environments. Refer to the list of minimum changes in What are the minimum changes I should make to my WebSphere application before deploying to Kubernetes?
Configure a CI/CD pipeline to automate the build, test, and deployment process for the application.
You have now completed the first of two AppMod exercises. This exercise demonstrated a simple runtime modernization scenario.