azure-notificationhubs-java-backend
azure-notificationhubs-java-backend copied to clipboard
[BUG] Notification Hubs incompatible with Spring? java.lang.RuntimeException: org.apache.hc.core5.http.ParseException: Invalid protocol version; error at offset 0: <[0x2e][0x2f][0x30][0x31][0x32][0x33][0x34][0x35][0x36][0x37][0x38][0x39][0x3a][0x3b][0x3c][0x3d][0x3e]>
Describe the bug When attempting to send a simple notification using com.windowsazure:Notification-Hubs-java-sdk:1.0.3 using a brand new, empty project that does nothing else, it appears that if Spring is also a dependency in the build file, this exception occurs when we attempt to send the notification.
Exception or Stack Trace java.lang.RuntimeException: org.apache.hc.core5.http.ParseException: Invalid protocol version; error at offset 0: <[0x2e][0x2f][0x30][0x31][0x32][0x33][0x34][0x35][0x36][0x37][0x38][0x39][0x3a][0x3b][0x3c][0x3d][0x3e]> at com.windowsazure.messaging.SyncCallback.failed(SyncCallback.java:53) at com.windowsazure.messaging.NotificationHubsService$1.failed(NotificationHubsService.java:78) at org.apache.hc.core5.concurrent.BasicFuture.failed(BasicFuture.java:138) at org.apache.hc.core5.concurrent.ComplexFuture.failed(ComplexFuture.java:86) at org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient$1$3.failed(InternalAbstractHttpAsyncClient.java:345) at org.apache.hc.client5.http.impl.async.AsyncRedirectExec$1.failed(AsyncRedirectExec.java:246) at org.apache.hc.client5.http.impl.async.AsyncHttpRequestRetryExec$1.failed(AsyncHttpRequestRetryExec.java:167) at org.apache.hc.client5.http.impl.async.AsyncProtocolExec$1.failed(AsyncProtocolExec.java:281) at org.apache.hc.client5.http.impl.async.HttpAsyncMainClientExec$1.failed(HttpAsyncMainClientExec.java:124) at org.apache.hc.core5.http.impl.nio.ClientHttp1StreamHandler.failed(ClientHttp1StreamHandler.java:295) at org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexer.terminate(ClientHttp1StreamDuplexer.java:193) at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.shutdownSession(AbstractHttp1StreamDuplexer.java:164) at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.onException(AbstractHttp1StreamDuplexer.java:404) at org.apache.hc.core5.http.impl.nio.AbstractHttp1IOEventHandler.inputReady(AbstractHttp1IOEventHandler.java:66) at org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler.inputReady(ClientHttp1IOEventHandler.java:41) at org.apache.hc.core5.reactor.ssl.SSLIOSession.decryptData(SSLIOSession.java:575) at org.apache.hc.core5.reactor.ssl.SSLIOSession.access$400(SSLIOSession.java:72) at org.apache.hc.core5.reactor.ssl.SSLIOSession$1.inputReady(SSLIOSession.java:172) at org.apache.hc.core5.reactor.InternalDataChannel.onIOEvent(InternalDataChannel.java:133) at org.apache.hc.core5.reactor.InternalChannel.handleIOEvent(InternalChannel.java:51) at org.apache.hc.core5.reactor.SingleCoreIOReactor.processEvents(SingleCoreIOReactor.java:178) at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:127) at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:85) at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: org.apache.hc.core5.http.ParseException: Invalid protocol version; error at offset 0: <[0x2e][0x2f][0x30][0x31][0x32][0x33][0x34][0x35][0x36][0x37][0x38][0x39][0x3a][0x3b][0x3c][0x3d][0x3e]> at org.apache.hc.core5.http.message.BasicLineParser.parseProtocolVersion(BasicLineParser.java:110) at org.apache.hc.core5.http.message.BasicLineParser.parseStatusLine(BasicLineParser.java:181) at org.apache.hc.core5.http.impl.nio.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:83) at org.apache.hc.core5.http.impl.nio.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:44) at org.apache.hc.core5.http.impl.nio.AbstractMessageParser.parseHeadLine(AbstractMessageParser.java:115) at org.apache.hc.core5.http.impl.nio.AbstractMessageParser.parse(AbstractMessageParser.java:167) at org.apache.hc.core5.http.impl.nio.AbstractMessageParser.parse(AbstractMessageParser.java:51) at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.parseMessageHead(AbstractHttp1StreamDuplexer.java:256) at org.apache.hc.core5.http.impl.nio.AbstractHttp1StreamDuplexer.onInput(AbstractHttp1StreamDuplexer.java:287) at org.apache.hc.core5.http.impl.nio.AbstractHttp1IOEventHandler.inputReady(AbstractHttp1IOEventHandler.java:64) ... 11 more
To Reproduce
- Create a simple Spring project with no content
- Add the following to the build.gradle file:
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.1'
id 'io.spring.dependency-management' version '1.1.0'
}
sourceCompatibility = '17'
repositories {
mavenCentral()
google()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'junit:junit:4.13.2'
// Azure Notification Hub
implementation 'com.windowsazure:Notification-Hubs-java-sdk:1.0.3'
testImplementation 'com.windowsazure:Notification-Hubs-java-sdk:1.0.3'
}
tasks.named('test') {
useJUnitPlatform()
}
// if you omit this you will get the following exception:
// java.lang.IllegalArgumentException: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.SimpleLoggerFactory loaded from ...PATH...). If you are using WebLogic you will need to add 'org.slf4j' to prefer-application-packages in WEB-INF/weblogic.xml: org.slf4j.impl.SimpleLoggerFactory
configurations {
all {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
}
- Create a simple unit test to confirm the project can run, e.g.
@Test
void testCanIRun() {
assertEquals(4,2+2);
}
This test should run and pass.
- Now create a simple unit test to send a simple notification (see snippet below)
Code Snippet
package com.foo.bar;
import com.windowsazure.messaging.Notification;
import com.windowsazure.messaging.NotificationHub;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.Assert.assertEquals;
@SpringBootTest
public class PushnotificationsApplicationTests {
private static final String ARBITRARY_TOKEN = "TOKENGOESHERE";
String SANDBOX_CONNECTION_STRING = "CONNSTRINGGOESHERE";
String SANDBOX_HUB = "HUBGOESHERE";
private final Logger log = LoggerFactory.getLogger(PushnotificationsApplicationTests.class);
String prodConnectionString;
String prodHubName;
String sandboxConnectionString;
String sandboxHubName;
@Test
void contextLoads() {
}
@Test
void testCanIRun() {
assertEquals(4,2+2);
}
@Test
public void testSendASimpleNotification() {
try {
setSandBoxHubName(SANDBOX_HUB);
setSandboxConnectionString(SANDBOX_CONNECTION_STRING);
boolean useSandbox = true;
boolean result = sendSingleNotification("notification content", ARBITRARY_TOKEN, useSandbox);
assert(result);
} catch (Exception e) {
log.error("Azure Push Notification failed.", e);
}
}
// HELPER METHODS
public boolean sendSingleNotification(String content, String token, boolean isSandbox) throws Exception {
try {
String message = "{\"notification\":{\"title\":\"This is the title\", \"body\": \"this is the body\"}, \"data\": {\"property1\": \"foo\", \"property2\": 42}}";
NotificationHub hub = getNotificatonHub(isSandbox);
Notification notification = getNotification(message);
hub.sendDirectNotification(notification, token);
return true;
} catch (Exception e) {
log.error("Azure Push Notification failed.", e);
}
return false;
}
private NotificationHub getNotificatonHub(boolean isSandbox) {
return new NotificationHub(
isSandbox ? sandboxConnectionString : prodConnectionString,
isSandbox ? sandboxHubName : prodHubName);
}
private Notification getNotification(String content) {
return Notification.createFcmNotification(content);
}
public void setSandBoxHubName(String s) {
sandboxHubName = s;
}
public void setSandboxConnectionString(String s) {
sandboxConnectionString = s;
}
}
Expected behavior Expected a notification to be sent to the device whose token corresponds with ARBITRARY_TOKEN
Screenshots If applicable, add screenshots to help explain your problem.
Setup (please complete the following information):
- OS: Windows 10
- IDE : IntelliJ IDEA 2021.3.3
- Version of the Library used:
- Azure Notification Hub: 1.0.3
- Spring: 3.0.1 (this has also been tested with versions down below 2.6.0 and Java versions to version 11. All combinations fail)
Additional context This was also tried with a simple Android app project and simple notifications succeeded, suggesting that classes involved in the Android gradle plugin(s) or dependencies are possibly superseding the classes that are causing the Invalid Protocol Error in the non-android app.
Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issue as an incomplete report. Please do not provide any private information in this bug report.
- [X ] Bug Description Added
- [X ] Repro Steps Added
- [X ] Setup information Added