2
votes

When calling:

MQQueueConnectionFactory cf ...
cf.createConnection();

The com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.handshakeCompleted method begins:

public void handshakeCompleted(HandshakeCompletedEvent event) {
 X509Certificate[] peerCertificateChain = event.getPeerCertificateChain();
 ...

getPeerCertificateChain in javax.net.ssl.SSLSession:

default X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
    throw new UnsupportedOperationException("This method is deprecated and marked for removal. Use the getPeerCertificates() method instead.");
}

causing this exception:

Exception in thread "HandshakeCompletedNotify-Thread" java.lang.UnsupportedOperationException: This method is deprecated and marked for removal. Use the getPeerCertificates() method instead.
    at java.base/javax.net.ssl.SSLSession.getPeerCertificateChain(SSLSession.java:295)
    at java.base/javax.net.ssl.HandshakeCompletedEvent.getPeerCertificateChain(HandshakeCompletedEvent.java:173)
    at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.handshakeCompleted(RemoteTCPConnection.java:2448)
    at java.base/sun.security.ssl.TransportContext$NotifyHandshake$1.run(TransportContext.java:685)
    at java.base/sun.security.ssl.TransportContext$NotifyHandshake$1.run(TransportContext.java:682)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/sun.security.ssl.TransportContext$NotifyHandshake.run(TransportContext.java:682)
    at java.base/java.lang.Thread.run(Thread.java:832)

The project's only IBM MQ dependency is:

com.ibm.mq:com.ibm.mq.allclient:9.2.0.0

Why is javax.net.ssl.getPeerCertificateChain() calling that deprecated method? It looks like the problem is in the HandshakeCompletedEvent class, not MQ.

Edit: This issue started with Java 15.

3
What version of Java are you using?Morag Hughson
Have you tried to turn on ssl debug? Do you have the correct certs in your trust store?JoshMc
I thought I had been testing with different java versions but I wasn't because gradle was picking up multiple org.gradle.java.home settings. I now see that this problem occurs starting in Java 15. I can go back to 14 for now, but still... it's a problemAndrew
For what it's worth, it's not uncommon for libraries to need updates in order to run on later versions of Java. Does IBM advertise that com.ibm.mq:com.ibm.mq.allclient:9.2.0.0 should work on Java 15?Justin Bertram
Nope, I haven't seen any comments from IBM but I suspect an update will be coming eventually.Andrew

3 Answers

2
votes

In your question you mention that this was failing with Java 15 and you posted a self answer to use Java 14 or earlier.


According to the "Supported Software" tab of the IBM MQ 9.2 Detailed System Requirements page IBM only supports MQ v9.2 on various versions of Java 8 and Java 11.

I am listing below the versions that show up on that page today (September 25 2020), but I would suggest always referring back to the IBM page above for current results:

  • AdoptOpenJDK with OpenJ9 JVM: 11 and future fix packs
  • Developer Kit for Java: V8R0 and future fix packs
  • IBM Runtime Environment, Java Technology Edition: 8 and future fix packs
  • IBM Runtime Environment, Java Technology Edition: 8.0.1 and future fix packs
  • IBM Runtime Environment, Java Technology Edition: 8.0.4.1 and future fix packs
  • IBM Runtime Environment, Java Technology Edition: 8.0.5.0 and future fix packs
  • IBM Runtime Environment, Java Technology Edition: 8.0.6.0 and future fix packs
  • Oracle Java SDK/JRE/JDK: 8.0 and future fix packs
  • Oracle Java SDK/JRE/JDK: 11.0.1 and future fix packs

Using any version of Java not listed on IBM's official MQ v9.2 System Requirements page would be at your own risk. If you were using Java 14 and had an issue that you needed to get support from IBM on, they would likely tell you that it is not supported at that version and to reproduce the problem at a supported version.

1
votes

Solution: Use Java 14 or earlier.

0
votes

I created a library that may work around the problem if you have programmatic access to the MQConnectionFactory . legacy-compatibility-ssl-socket-factory gives you a SSLSession that implements getPeerCertificateChain() by delegating to getPeerCertificates() of a different SSLSocketFactory .

mqConnectionFactory.setSSLSocketFactory(new LegacyCompatibilitySSLSocketFactory());