Lucee 6.2.3.35 and sun.security.pkcs (old java 11 jar)

Hi,

We are upgrading from Lucee 5.4 to Lucee 6.2 for out app that runs in a Docker container built from official Lucee Docker light Nginx images.

The pertinent lines from our Docker file are

FROM lucee/lucee:6.2.3.35-light-nginx
:
COPY lib/ezsign-4.1.2.jar /opt/lucee/web/context/ezsign-4.1.2.jar
:
:
ENV LUCEE_DESERIALIZEJSON_ALLOWEMPTY=true
ENV LUCEE_QUERY_ALLOWEMPTYASNULL=true
ENV LUCEE_MAPPING_FIRST=true
ENV LUCEE_STORE_EMPTY=true
ENV LUCEE_USE_LUCEE_SSL_TRUSTSTORE=/opt/java/openjdk/lib/security/cacerts
:
RUN /usr/local/tomcat/bin/prewarm.sh
:
COPY --chmod=755 bin/entrypoint_dev.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

and the pertinent lines of entrypoint.sh are:

#!/bin/bash

LUCEE_JAVA_OPTS="\
 -DLog4jContextSelector=org.apache.logging.log4j.core.selector.ClassLoaderContextSelector\
 -Djsch.server_host_key=ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ssh-dss\
 -XX:MaxRAMPercentage=${JAVA_OPT_MaxRAMPercentage}"

When the app tries to use the ezsign-4.1.2.jar file we get the following error:

class com.krestfield.ezsign.channels.KPkiChannel (in unnamed module @0x4af7f3bb) cannot access class sun.security.pkcs.PKCS9Attribute (in module java.base) because module java.base does not export sun.security.pkcs to unnamed module @0x4af7f3bb

We have been previously advised, on the Slack channel, to add the following as a workaround:

environment:
  - JAVA_OPTS=--add-opens java.base/sun.security.pkcs=ALL-UNNAMED

but no matter where we try to do this we get the same error.

FYI this issue doesn’t happen at all with either the 6.1.2.47-light-nginx-tomcat9.0-jre11-temurin-jammy or 6.0.4.10 images

Don’t forget to tell us about your stack!

Java Version: 21.0.8 2025-07-15 LTS
Lucee Version: 6.2.3.35

Ok, as i suggested on slack, here’s a native Lucee 7.0 version of that old jar, doesn’t quite work on 6.2 due to some java classloader stuff which only works properly in 7

you really should be trying to get off Java 11, it’s much slower than 21

EzSign.cfc (6.1 KB)

But let me check why the java opts aren’t working, try this in docker-compose

version: '3.8'

services:
  lucee:
    image: lucee/lucee:6.2.4.21-RC-nginx-tomcat11.0-jre21-temurin-noble

    ports:
      - "8888:8888"
    environment:
      LUCEE_JAVA_OPTS: "--add-opens java.base/sun.security.pkcs=ALL-UNNAMED -Xms64m -Xmx512m"
1 Like

If it’s any help - our contact at Krestfield (the makers of EzSign) claim all we should need to do is add:

--add-exports=jdk.crypto.cryptoki/sun.security.pkcs11.wrapper=ALL-UNNAMED

to the “JVM options” but we’ve tried that (multiple times) and it doesn’t work either

That docker compose gives the same error.

services:
  lucee:
    image: lucee/lucee:6.2.4.21-RC-nginx-tomcat11.0-jre21-temurin-noble
    ports:
      - "8180:80"
    environment:
      LUCEE_JAVA_OPTS: "--add-opens java.base/sun.security.pkcs=ALL-UNNAMED -Xms64m -Xmx512m"
    configs:
      - source: test-pkcs.cfm
        target: /var/www/test-pkcs.cfm

configs:
  test-pkcs.cfm:
    content: |
      <cfscript>
      try {
        pkcs9Class = createObject( "java", "sun.security.pkcs.PKCS9Attribute" );
        systemOutput( "SUCCESS: sun.security.pkcs.PKCS9Attribute is accessible", true );
        writeOutput( "SUCCESS: sun.security.pkcs.PKCS9Attribute is accessible" );
      } catch ( any e ) {
        systemOutput( "FAILED: " & e.message, true );
        writeOutput( "FAILED: " & e.message );
      }
      writeOutput( "<hr>JVM Args:<br>" );
      runtime = createObject( "java", "java.lang.management.ManagementFactory" ).getRuntimeMXBean();
      for ( arg in runtime.getInputArguments() ) {
        systemOutput( arg, true );
        writeOutput( arg & "<br>" );
      }
      </cfscript>
curl -s http://localhost:8180/test-pkcs.cfm

produces in the console


16-Dec-2025 14:45:17.930 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8888"]

16-Dec-2025 14:45:17.943 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [2296] milliseconds
SUCCESS: sun.security.pkcs.PKCS9Attribute is accessible
-Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.tls.ephemeralDHKeySize=2048
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
--add-opens=java.base/java.io=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED
--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
--enable-native-access=ALL-UNNAMED
--add-opens=java.base/sun.security.pkcs=ALL-UNNAMED
-Xms64m
-Xmx512m
-Djava.security.egd=file:/dev/./urandom
-Dcatalina.base=/usr/local/tomcat
-Dcatalina.home=/usr/local/tomcat
-Djava.io.tmpdir=/usr/local/tomcat/temp
1 Like

With that code, I get the “SUCCESS” message whether I set the env var or not.

The env var only appears if I add it where we are also setting LUCEE_JAVA_OPTS in the container’s entrypoint.sh file

One step forward and two steps back it seems.

I’ve made some progress on the issue but now get an error of:

Could not initialize class io.grpc.ManagedChannelProvider

which Krestfield say is in the realms of the Google Cloud library (which would tally up with our keys being in the Google KMS) and outside their remit

@Zackster I think I have found the problem.

Despite our docker file saying

COPY lib/ezsign-4.1.2.jar /opt/lucee/web/context/ezsign-4.1.2.jar

The application code also contains:

this.javaSettings = {
			LoadPaths = [
				ExpandPath("/lib"),
				ExpandPath("/plugins/Bacstel/EzSignServer/lib")
				],
			reloadOnChange = true
		}

this was causing multiple version of the ezSign JAR file to be visible to the application.

If I update the code so that Lucee can only see one, updated, version of the ezsign JAR file then everything works as expected even on 6.2.3.35-light-nginx

great!