So we are migrating from jdk8 to jdk17 (openJDK) and from Tomcat8 to Tomcat 10.0.20 and when running the code we get following error:

class [Ljava.lang.Object; cannot be cast to class [Ljava.security.cert.Certificate; ([Ljava.lang.Object; and [Ljava.security.cert.Certificate; are in module java.base of loader 'bootstrap')

Seems it has todo with acalling BouncyCastle method. We are using following BC jar files:

bcmail-jdk18on-171.jar bcpkix-jdk18on-171.jar bcprov-jdk18on-171.jar bcutil-jdk18on-171.jar

Note the codebase is compiled on jdk8.

Seems following return code generates the error:

    public Certificate[] getCertificates() {
    // Be sure the Signing Certificate is the first 
    // If found as last,we shuffle all certificates to the SigninCert is first
    Certificate[] c = (X509Certificate[]) certs.toArray(new X509Certificate[certs.size()]);
    if (this.signCert != null) {
        if (this.signCert.getSerialNumber() != ((X509Certificate) c[0]).getSerialNumber()) {
            List list = Arrays.asList(c);
            Collections.reverse(list);    
            return (Certificate[]) list.toArray();
        }
    }

    return c;

}

So in JDK 8:

return (Certificate[]) list.toArray();

is OK but this generates the mentioned Exception in JDK17

I changed to:

return list.toArray(new X509Certificate[list.size()]);

but gives me the error:

incompatible types: Object[] cannot be converted to Certificate[]

So what should it be ?

See also this stackoverflow question

Update: To solve my own question, below the code change to make it work in jdk17:

    public Certificate[] getCertificates() {
    // Be sure the Signing Certificate is the first 
    // If found as last,we shuffle all certificates to the SigninCert is first
    Certificate[] c = (X509Certificate[]) certs.toArray(new X509Certificate[certs.size()]);
    if (this.signCert != null) {
        if (this.signCert.getSerialNumber() != ((X509Certificate) c[0]).getSerialNumber()) {
            List<Certificate> list =Arrays.asList(c); 
            Collections.reverse(list);
            return list.toArray(new Certificate[c.length]);
       
         //Exception jdk17   return (Certificate[]) list.toArray();
        }
    }

    return c;
} 

So the question remains is this a compatibility break in JDK11 (or later) or why does the code work in jkd8 ? Or has this been mentioned somewhere ?

Quit distubring as this is only detected at run time and not at compile time.

0

There are 0 best solutions below