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.