IBM MQ 在 SSL 握手时抛出 java.lang.UnsupportedOperationException

Posted

技术标签:

【中文标题】IBM MQ 在 SSL 握手时抛出 java.lang.UnsupportedOperationException【英文标题】:IBM MQ throws java.lang.UnsupportedOperationException on SSL handshake 【发布时间】:2021-01-11 09:16:01 【问题描述】:

调用时:

MQQueueConnectionFactory cf ...
cf.createConnection();

com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.handshakeCompleted 方法开始:

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

javax.net.ssl.SSLSession 中的getPeerCertificateChain:

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

导致此异常:

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)

项目唯一的 IBM MQ 依赖是:

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

为什么 javax.net.ssl.getPeerCertificateChain() 调用该已弃用的方法?看起来问题出在 HandshakeCompletedEvent 类中,而不是 MQ。

编辑:此问题始于 Java 15。

【问题讨论】:

您使用的是什么版本的 Java? 你试过开启ssl调试吗?您的信任库中有正确的证书吗? 我以为我一直在使用不同的 java 版本进行测试,但我不是因为 gradle 正在获取多个 org.gradle.java.home 设置。我现在看到这个问题从 Java 15 开始出现。我现在可以回到 14,但仍然......这是一个问题 不管怎样,库需要更新才能在更高版本的 Java 上运行的情况并不少见。 IBM 是否宣传 com.ibm.mq:com.ibm.mq.allclient:9.2.0.0 应该适用于 Java 15? 不,我没有看到任何来自 IBM 的 cmets,但我怀疑最终会发布更新。 【参考方案1】:

解决方案:使用 Java 14 或更早版本。

【讨论】:

IBM 系统要求显示 9.2 仅受 Java 8 和 11 支持。任何其他可能工作的版本都将由您自担风险,因为如果您有 IBM 可能会告诉您使用受支持的版本一个问题。【参考方案2】:

在您的问题中,您提到 Java 15 失败,并且您发布了使用 Java 14 或更早版本的自我回答。


根据IBM MQ 9.2 Detailed System Requirements 页面的“支持的软件”选项卡,IBM 仅在 Java 8 和 Java 11 的各种版本上支持 MQ v9.2。

我在下面列出了今天(2020 年 9 月 25 日)显示在该页面上的版本,但我建议始终参考上面的 IBM 页面以了解当前结果:

采用带有 OpenJ9 JVM 的 OpenJDK:11 和未来的修复包 Java 开发工具包:V8R0 和未来的修复包 IBM Runtime Environment,Java Technology Edition:8 和未来的修订包 IBM Runtime Environment,Java 技术版:8.0.1 和未来的修订包 IBM Runtime Environment,Java 技术版:8.0.4.1 和未来的修订包 IBM Runtime Environment,Java 技术版:8.0.5.0 和未来的修订包 IBM Runtime Environment,Java 技术版:8.0.6.0 和未来的修订包 Oracle Java SDK/JRE/JDK:8.0 和未来的修订包 Oracle Java SDK/JRE/JDK:11.0.1 和未来的修复包

使用 IBM 官方 MQ v9.2 系统要求页面上未列出的任何 Java 版本将由您自担风险。如果您使用的是 Java 14,并且遇到需要从 IBM 获得支持的问题,他们可能会告诉您该版本不支持该版本并在受支持的版本中重现该问题。

【讨论】:

【参考方案3】:

如果您对MQConnectionFactory 具有编程访问权限,我创建了一个可以解决该问题的库。 legacy-compatibility-ssl-socket-factory 为您提供了一个 SSLSession,它通过将不同的 SSLSocketFactory 委托给 getPeerCertificates() 来实现 getPeerCertificateChain()

mqConnectionFactory.setSSLSocketFactory(new LegacyCompatibilitySSLSocketFactory());

【讨论】:

【参考方案4】:

在最新版本中,它们显然提供了 JAVA 17 支持。

来源:

https://www.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/8/899/ENUSLP21-0278/index.html https://search.maven.org/artifact/com.ibm.mq/com.ibm.mq.allclient/9.2.4.0/jar

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review【参考方案5】:

IBM MQ 客户端 9.2.4.0 支持 Java 17

https://www.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/8/899/ENUSLP21-0278/index.html

MQ 9.2.4

通过更新统一集群实现智能工作负载再平衡 基于 MQ 中现有强大的安全机制的安全增强功能,旨在确保您的关键任务 业务数据受到保护 MQ 客户端支持新的 Java™ 11 运行时 MQ 客户端支持 Java 17 运行时

https://www.ibm.com/docs/en/ibm-mq/9.2?topic=wnim9-whats-new-in-mq-924-multiplatforms-base-advanced-entitlement#mq924_new_multibaseadv__java17support

Java 17 对 IBM MQ 客户端的支持

IBM MQ 9.2.4 增加了 Java 17 对用于 Java 的 IBM MQ 类和用于 JMS for Oracle 和 Oracle 和 Adoptium 的 IBM MQ 类的支持。

如果使用 maven,您可以通过以下方式修复

<dependency>
    <groupId>com.ibm.mq</groupId>
    <artifactId>com.ibm.mq.allclient</artifactId>
    <version>9.2.4.0</version>
</dependency>

【讨论】:

以上是关于IBM MQ 在 SSL 握手时抛出 java.lang.UnsupportedOperationException的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Spring Boot 连接到具有多个 SSL 证书的多个 IBM MQ 通道

IBM MQ runmqckm常用命令和通道SSL加密示例

JMS 的 Spring 配置(Websphere MQ - SSL、Tomcat、JNDI、非 IBM JRE)

PouchDB 复制在复制时抛出错误

AVAudioPlayer 在使用 M4A 文件初始化时抛出。 (OSStatus 错误 2003334207。)

SSL 握手问题