Reducing start up times in WebSphere

If you work in an IBM shop you might be cursing at the fact you have to use WebSphere. The start up and publish times are ridiculous which add to your over all developer cycle time. Publish, wait, restart, get distracted - where was I? Back from coffee... this is in itself should cause just about every developer to go insane and force folks to write unit tests.

Start up times get worse in containers that support servlet 3.0 due the way containers scan and process annotations. Per the servlet 3.0 spec, "In servlet 3.0 metadata-complete affects scanning of all annotations and webfragments at deployment time." So each time you deploy or publish the container will scan your entire class path looking for annotations. What this means is the more jars and classes your application is dependent on, the longer it will take to fire up. In turn this will add to the overall application server ready time and if your WebSphere infrastructure team monitors this, they will come knocking. Noting the metadata-complete attribute, a standard web.xml it might look like:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0" metadata-complete="false">
    <display-name>Servlet 3.0 Web Application</display-name>
</web-app>

What might not be apparent is when you are using a spring boot application under the covers it leverages SpringServletContainerInitializer which is bootstrapped automatically by any Servlet 3.0 container so the metadata-complete="false" is hidden. Then to compound the start up times spring applications typically have lots of dependencies for the container to scan.

How to reduce application start up times?

You can reduce the annotations searched during application deployment within WebSphere by adding one of two properties to the META-INF/MANIFEST.MF entry:

  • Ignore-Scanning-Archives
  • Ignore-Scanning-Packages

Your MANIFEST would look something like this:

Manifest-Version: 1.0
Built-By: Justin Musgrove
Build-Jdk: 1.7.0
Class-Path:
Created-By: Maven Integration for Eclipse
Ignore-Scanning-Archives: jar1, jar2, jar3...
Ignore-Scanning-Packages: package1, package2...

Unfortunately no wildcard or regular expressions are permitted and values are case-sensitive.

Using maven

If you are using maven, you can automate it a bit by updating the maven-war-plugin with the manifestEntries property and manually adding your packages or archives to ignore:

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-war-plugin</artifactId>
   <configuration>
       <archive>
          <manifestEntries>
              <Ignore-Scanning-Archives>jar1, jar2, jar3, etc</Ignore-Scanning-Archives>
              <Ignore-Scanning-Packages>package1, package2, etc.</Ignore-Scanning-Packages>
          </manifestEntries>
       </archive>
   </configuration>
</plugin>

Configure WebSphere application server

If your WebSphere admins are open to it there is a way to configure it at the server level by placing a m.filter.properties file in the profile_root/properties directory. In addition you could also supply system properties by setting com.ibm.ws.amm.scan.context.filter.archives for Ignore-Scanning-Archives and com.ibm.ws.amm.scan.context.filter.packages Ignore-Scanning-Packages.

If you don't add or update your dependencies often this might work or you could choose to write a custom maven plugin to read application dependencies. The steps outlined above offer a solution but I am always hesitant adding another step for developers to remember. Also, if you are using tomcat it too has similar ways to speed up application start up times. If you have other thoughts on how to solve this, I would be interested to hear them.