Migrating 9.1 JSP stores to Commerce+ Transaction Server

Migrate custom downstream CRS extension repositories to Java 21, Spring 6, and Open Liberty 26+. Update Enterprise APIs to Jakarta EE and modernize your build toolchain.

Before you begin

Ensure that you have the following requirements:
  • JDK 21 installed and available on your PATH environment variable.
  • Access to your organization internal Maven repository URL to configure plugin and dependency resolution.
  • Open Liberty 26+ base Docker image reference (the full image tag for your registry).
Create a branch or back up your code before beginning. This migration modifies build files, Java sources, JSPs, XML descriptors, Dockerfiles, and server configuration files.

About this task

This task describes the complete migration process for downstream CRS extension repositories, including custom modules, configurations, and deployment scripts built on the base CRS framework. The migration affects all layers of the stack:
  • Language level: Java 8 to JDK 21
  • Enterprise APIs: javax.servlet / javax.ejb to jakarta.servlet / jakarta.ejb
  • Spring Framework: 5.x to 6.x
  • Application server: WebSphere Liberty to Open Liberty 26+
  • Build toolchain: Maven dependency and plugin modernization
    Remember: This guide documents the standard migration path and might not cover custom configurations specific to individual instances. Always validate changes against your target environment.
An automated agent skill is available to perform these steps at .agents/skills/migrate-crs-consumer-to-jdk21-spring6/SKILL.md. If your IDE or toolchain supports agent skills, you can invoke it to perform these steps automatically. The sections below describe the same transformations in human-readable form for manual execution or review.

Procedure

  1. Migrate to the Jakarta EE namespace.
    The javax enterprise packages have been moved to the jakarta namespace.
    Important: Do not replace base JDK packages such as javax.crypto, javax.net.ssl, and javax.xml.
    1. Update Java source imports in .java files:
      • Change import javax.servlet.* to
        import
                    jakarta.servlet.*
      • Change import javax.ejb.* to
        import
                jakarta.ejb.*
      • Change javax.servlet.http.Cookie to jakarta.servlet.http.Cookie
      • Change javax.servlet.http.HttpServlet to jakarta.servlet.http.HttpServlet
    2. Update string literals referencing servlet constants (For example, change "javax.servlet.forward.request_uri" to "jakarta.servlet.forward.request_uri")
    3. Update JSP and JSPF files to reference Jakarta packages.
    4. Update XML deployment descriptors (web.xml and application.xml) to Jakarta EE 10 schemas.
    5. Add deprecation metadata to Java 21 overrides:
      @Deprecated(forRemoval = true)
      @SuppressWarnings("removal")
      protected void finalize() throws Throwable { ... }
  2. Update Spring Framework 6 APIs.
    1. Update classes extending HandlerInterceptorAdapter to implement HandlerInterceptor.
    2. Update import paths to org.springframework.web.servlet.HandlerInterceptor.
    3. Remove superclass calls to interceptor methods (super.preHandle() , super.postHandle(), super.afterCompletion()).
    4. Update status code method calls for HttpStatusCode compatibility. Replace responseEntity.getStatusCode().name() with HttpStatus.valueOf(responseEntity.getStatusCode().value()).name().
  3. Remap runtime paths and container configurations.
    Update legacy WebSphere Liberty references (/opt/WebSphere/Liberty) to Open Liberty paths (/opt/ol/wlp).
    1. Update Dockerfile base images and packaging commands. Replace yum or dnf with
      microdnf install -y <package> && microdnf clean
          all
    2. Update feature lists in server.xml for Open Liberty 26+ (For example, change servlet-3.1 to servlet-6.0 and jsp-2.2 to pages-3.1).
    3. Migrate JKS keystores to PKCS12 format.
    4. Externalize server ports using bootstrap.properties.
    5. Configure JDK 21 JVM module access flags in jvm.options.
  4. Update WebSphere Cache API references. If code imports internal WebSphere caching classes directly, replace direct imports with reflection-based access.
    If your code directly imports internal WebSphere caching classes (com.ibm.ws.cache.servlet.CacheProxyResponse, CacheProxyWriter, FragmentComposer), these are not available on public Maven repositories and must be accessed via reflection at runtime.

    Replace direct imports with a reflection-based pattern:

    private static final Class<?> CACHE_PROXY_RESPONSE_CLASS;
    private static final Method GET_FRAGMENT_COMPOSER_METHOD;
    
    static {
        Class<?> cprClass = null;
        Method gfcMethod = null;
        try {
            cprClass = Class.forName("com.ibm.ws.cache.servlet.CacheProxyResponse");
            gfcMethod = cprClass.getMethod("getFragmentComposer");
        } catch (Exception e) {
            // Fallback or logging logic here
        }
        CACHE_PROXY_RESPONSE_CLASS = cprClass;
        GET_FRAGMENT_COMPOSER_METHOD = gfcMethod;
    }
  5. Update project facets and classpath configurations.
    .classpath : Change JavaSE-1.8 container entries to JavaSE-21.
    .settings/org.eclipse.wst.common.project.facet.core.xmlUpdate the Java facet:
    <installed facet="jst.java" version="21"/>
  6. Verify the migration.
    Verification checklist: Run search checks across the project root to ensure zero legacy references remain, then perform a complete project build.
    What to check Command
    Legacy enterprise API imports rg "import javax\.(servlet|ejb)" --glob "*.java"
    Old XML namespaces (java.sun.com) rg "java\.sun\.com/xml/ns/javaee" --glob "*.xml"
    Old XML namespaces (xmlns.jcp.org) rg "xmlns\.jcp\.org/xml/ns/javaee" --glob "*.xml"
    Legacy servlet references in JSPs rg "javax\.servlet" --glob "*.jsp" --glob "*.jspf"
    Old deployment paths rg "/opt/WebSphere/Liberty"
    Removed Spring utilities rg "HandlerInterceptorAdapter|getRawStatusCode" --glob "*.java"
    Old JRE facet rg "JavaSE-1\.8" --glob ".classpath"
    Build and compile the project: Once all verification checks pass, run your build compiler (such as Maven). If compilation fails, check the error log for unmapped javax references or Spring 6 API changes, resolve the issues, and rebuild the project.
  7. Automate the migration using the agent skill.
    You can run an agent skill to automate this migration process. The skill is located at .agents/skills/migrate-crs-consumer-to-jdk21-spring6/SKILL.md. The skill executes the same transformations described in this guide when invoked by an IDE or toolchain that supports agent skills. Before executing, the skill prompts you for environment-specific values, such as your Maven repository URL and Docker base image tag.