adobe-experience-manager-and-jdk-11.jpg

Adobe Experience Manager 6.5 and JDK11

Jul 1st, 2021 | Mihir Mange

We recently switched to Java 11 with Adobe Experience Manager 6.5 for some of our customers and ran into several issues especially with environment stability. This post outlines some of the items you need to be aware of and address when using Java 11 with Adobe Experience Manager.

I’ve organized this post into a short version and a long version. If you’ve already done all the work of updating your pom, dependencies, compiler, plugins, to work with Java 11 but, having environment issues only, the Short version below outlines quick steps that you can take to ensure your Adobe Experience Manager instance is stable after builds and deploys.

The Longer version in this article walks through all the things you need to take care of when using Java 11 with Adobe Experience Manager in more detail.



The Short Version

The short answer to get these JDK11 and Adobe Experience Manager issues resolved to ensure a stable enviroment – make the following changes:

  1. Update sling.properties

    Go to /crx-quickstart/conf/sling.properties and update the extra packages & boot delegation to below
    org.osgi.framework.system.packages.extra=org.apache.sling.launchpad.api;version=1.2.0,
    com.sun.org.apache.xpath.internal;version="{dollar}{felix.detect.java.version}" ${org.apache.sling.launcher.system.packages}
      
    org.osgi.framework.bootdelegation=sun.*,com.sun.*,jdk.internal.reflect,jdk.internal.reflect.*,
    com.yourkit.*${org.apache.sling.launcher.bootdelegation}
    
    
  2. Update your AEM Startup script to include following JVM options

    -XX:+UseParallelGC
    -Dnashorn.args=--no-deprecation-warning
    --add-opens=java.desktop/com.sun.imageio.plugins.jpeg=ALL-UNNAMED
    --add-opens=java.base/sun.net.www.protocol.jrt=ALL-UNNAMED
    --add-opens=java.naming/javax.naming.spi=ALL-UNNAMED
    --add-opens=java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED
    --add-opens=java.base/java.lang=ALL-UNNAMED
    --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
    --add-opens=java.base/java.net=ALL-UNNAMED
    

The Long Version

With the introduction of JDK11 you need to account for a few things outlined below

  1. Update your compiler, to make sure you are compiling for Java 11

    This can potentially be done by simply updating your properties in your maven pom.xmls

    <properties>
            <java.version>11</java.version>
            <maven.compiler.source>${java.version}</maven.compiler.source>
            <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>
    
  2. Update Maven Enforcer plugin

    Update your enforcer plugin – ensure it’s using the correct properties / java version

    <plugin>
                       <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-enforcer-plugin</artifactId>
                        <version>1.4.1</version>
                        <executions>
                            <execution>
                                <id>enforce-maven</id>
                                <goals>
                                    <goal>enforce</goal>
                                </goals>
                                <configuration>
                                    <rules>
                                        <requireMavenVersion>
                                            <version>[3.3.1,)</version>
                                        </requireMavenVersion>
                                        <requireJavaVersion>
                                            <message>Project must be compiled with Java ${aem.java.version} or higher</message>
                                            <version>1.${aem.java.version}</version>
                                            <message>Project must be compiled with Java ${java.version} or higher</message>
                                            <version>${java.version}</version>
                                        </requireJavaVersion>
                                   </rules>
                                </configuration>
                           </execution>
                        </executions>
                    </plugin>
    
  3. Handle Common Annotations

    The Java Common Annotations module was removed from Java 11, so you need to add javax.annotation-api as a dependency

    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.3.2</version>
        <scope>provided</scope>
    </dependency>
    

    Alternatively, you might also find the geronimo-atinject_1.0_spec in your pom dependencies, and you can replace that with geronimo-annotation_1.3_spec (or use dependency finder to find the correct version based on your Adobe Experience Manager.

    <!-- javax.inject 1 -->
    <dependency>
        <artifactId>geronimo-annotation_1.3_spec</artifactId>
        <version>1.0</version>
        <groupId>org.apache.geronimo.specs</groupId>
        <scope>provided</scope>
    </dependency>
    
  4. Solve for NoClassDefFoundError

    If you are seeing blank pages after deploying or bundle install on Adobe Experience Manager it’s possible it’s happening due to FELIX-6184

    You might see following error in the logs as well

    java.lang.NoClassDefFoundError: jdk/internal/reflect/ConstructorAccessorImpl
    

    There is an adobe article as well talking about this issue.https://helpx.adobe.com/experience-manager/kb/jdk-11-causes-noclassdeffounderror—aem-6-5.html

    You can resolve this by editing to /crx-quickstart/conf/sling.properties and update

    org.osgi.framework.bootdelegation=sun.*,com.sun.*,jdk.internal.reflect,jdk.internal.reflect.*,
    com.yourkit.*${org.apache.sling.launcher.bootdelegation}
    
  5. Make Reflection Work

    Since Java 9 Modules to make reflection work you need to allow it explicitly with –add-opens JVM option. Without it you may get errors like the following:

    Caused by: java.lang.reflect.InaccessibleObjectException:
    Unable to make ClassLoader.defineClass accessible:
    module java.base does not "opens java.lang" to unnamed module
    

    You can address this by adding some of the commonly accessed packages by adding following to your Adobe Experience Manager start script’s JVM options

    --add-opens=java.desktop/com.sun.imageio.plugins.jpeg=ALL-UNNAMED
    --add-opens=java.base/sun.net.www.protocol.jrt=ALL-UNNAMED
    --add-opens=java.naming/javax.naming.spi=ALL-UNNAMED
    --add-opens=java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED
    --add-opens=java.base/java.lang=ALL-UNNAMED
    --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED
    --add-opens=java.base/java.net=ALL-UNNAMED
    
  6. Use Parallel Garbage Collection (performance optimization)

    There were significant improvements in Java 11 around Garbage Collection and you can turn on Parallel Garbage Collection by adding -XX:+UseParallelGC to your JVM Options

    Reference: https://docs.oracle.com/en/java/javase/11/gctuning/parallel-collector1.html#GUID-DCDD6E46-0406-41D1-AB49-FB96A50EB9CE


  7. Hide Nashorn Deprecation warnings

    This is an optional step but, if you’d like to avoid filling your logs with Nashorn deprecation warnings add the following to your JVM OPTs in startup script

    -Dnashorn.args=--no-deprecation-warning
    
At Initialyze, we have deep expertise in upgrading and migrating to Adobe Experience Manager. Are you looking for support or guidance with your Adobe Experience Manager Implementation? Contact, Call or email us now to schedule a demo and learn how we can help.

About Initialyze

Founded in 2015 in San Francisco, Initialyze specializes in providing software solutions and services to help worlds leading brands deliver transformation digital brand experiences. Our expertise includes Digital Strategy, Technology Implementation, Analytics and Marketing. We strive to form strong partnerships with our clients to envision, design and build innovative digital experiences efficiently and simply. Using an optimized implementation process and a suite of ready to use Initialyzers, we deliver on complex requirements quickly and cost effectively without sacrificing on quality.