首页 > 解决方案 > Pushy APNS http2 协议 - io.netty.util.concurrent.PromiseCombiner 错误中没有初始化方法

问题描述

使用库时遇到以下运行时错误

我在我的项目中使用了以下依赖项

           <dependency>
    <groupId>com.eatthepath</groupId>
    <artifactId>pushy</artifactId>
    <version>0.14.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.48.Final</version>
</dependency>

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.0</version>
</dependency>

<dependency>
    <groupId>com.eatthepath</groupId>
    <artifactId>fast-uuid</artifactId>
    <version>0.1</version>
</dependency>

按照https://github.com/jchambers/pushy中的自述文件,我的代码实现非常简单

        final ApnsClient client = new ApnsClientBuilder()
                .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST)
                .setClientCredentials(new File(certPath), apnsPassword)
                .build();

for (String deviceToken : deviceTokensList) {
final ApnsPayloadBuilder payloadBuilder = new SimpleApnsPayloadBuilder();
                payloadBuilder.setAlertBody(notificationMessage);

            final String payload = payloadBuilder.build();
            final String token = TokenUtil.sanitizeTokenString(deviceToken);

            final SimpleApnsPushNotification pushNotification = new SimpleApnsPushNotification(token, #invalid_app_bundle#, payload);
            
            final PushNotificationFuture<SimpleApnsPushNotification, PushNotificationResponse<SimpleApnsPushNotification>>
            sendNotificationFuture = client.sendNotification(pushNotification);
              
            try {
                sendNotificationFuture.whenComplete((response, cause) -> {
                    if (response != null) {
                        ConsoleLog.print(isDebug, deviceToken + ", Handle the push notification response as before from here.");
                        insertIntoAPNSThirdPartyServiceLogs(new AppleNotificationEntity(deviceToken, true, source, "Success."));
                    } else {
                        String error = deviceToken + ", " + cause;
                        ConsoleLog.print(isDebug, error);
                        insertIntoAPNSThirdPartyServiceLogs(new AppleNotificationEntity(deviceToken, false, source, error));
                        cause.printStackTrace();
                    }
                });
            } catch (final Exception e) {
                String error = "Failed to send push notification, reason: " + e.getMessage();
                ConsoleLog.print(isDebug, error);
                e.printStackTrace();
                insertIntoAPNSThirdPartyServiceLogs(new AppleNotificationEntity(deviceToken, false, source, error));
            } 
       } // close for loop
       client.close();

错误日志:

2021-03-26 16:18:31.933 WARN 27557 --- [ntLoopGroup-2-1] io.netty.util.concurrent.DefaultPromise : An exception was thrown by com.eatthepath.pushy.apns.ApnsChannelPool$$Lambda$2619/595971378.operationComplete()
java.lang.NoSuchMethodError: io.netty.util.concurrent.PromiseCombiner.<init>(Lio/netty/util/concurrent/EventExecutor;)V
at com.eatthepath.pushy.apns.ApnsChannelPool.lambda$close$6(ApnsChannelPool.java:247) ~[pushy-0.14.2.jar:na]
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at io.netty.util.concurrent.DefaultPromise.access$000(DefaultPromise.java:33) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at io.netty.util.concurrent.DefaultPromise$1.run(DefaultPromise.java:435) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463) [netty-all-4.1.23.Final.jar:4.1.23.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.23.Final.jar:4.1.23.Final]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]
**java.lang.NoSuchMethodError: io.netty.util.concurrent.PromiseCombiner.<init>(Lio/netty/util/concurrent/EventExecutor;)V**
at com.eatthepath.pushy.apns.ApnsClientHandler.writePushNotification(ApnsClientHandler.java:217)
at com.eatthepath.pushy.apns.ApnsClientHandler.write(ApnsClientHandler.java:175)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:801)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:831)
at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1071)
at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:300)
at com.eatthepath.pushy.apns.ApnsClient.lambda$sendNotification$1(ApnsClient.java:205)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424)
at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:103)
at com.eatthepath.pushy.apns.ApnsChannelPool.lambda$acquireWithinEventExecutor$2(ApnsChannelPool.java:156)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511)
at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:504)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:483)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424)
at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:103)
at com.eatthepath.pushy.apns.ApnsClientHandler.onSettingsRead(ApnsClientHandler.java:396)
at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder$FrameReadListener.onSettingsRead(DefaultHttp2ConnectionDecoder.java:423)
at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder$PrefaceFrameListener.onSettingsRead(DefaultHttp2ConnectionDecoder.java:635)
at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readSettingsFrame(DefaultHttp2FrameReader.java:542)
at io.netty.handler.codec.http2.DefaultHttp2FrameReader.processPayloadState(DefaultHttp2FrameReader.java:263)
at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readFrame(DefaultHttp2FrameReader.java:160)
at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder.decodeFrame(DefaultHttp2ConnectionDecoder.java:118)
at io.netty.handler.codec.http2.Http2ConnectionHandler$FrameDecoder.decode(Http2ConnectionHandler.java:390)
at io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:254)
at io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:450)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.flush.FlushConsolidationHandler.channelRead(FlushConsolidationHandler.java:147)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1407)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1177)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1221)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)

在 whenComplete 方法中产生了这个问题,并返回具有上述原因的空响应

sendNotificationFuture.whenComplete((response, cause) -> {
if (response != null) {
} else {
// here
}
}

标签: spring-bootapple-push-notificationsnettynosuchmethoderrorpushy

解决方案


检查 netty-common 版本后,我注意到 netty 版本不是 4.1.48.Final 而我使用的是 Spring 版本 2.0.1.RELEASE,它在包含 Jar 文件的主项目中需要 4.1.23.Final netty 版本包含 Pushy 库。

所以我添加了以下依赖项,修复了覆盖现有 netty 版本的主项目中的问题


    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-common</artifactId>
        <version>4.1.48.Final</version>
    </dependency>

Github 门票


推荐阅读