6

Trying to get Apple push notifications to work with my Spring Boot project.

I'm using this apns-http2 for sending push notification. From their GitGub page:

Note: Ensure that you have Jetty's ALPN JAR (OkHttp requires it) in your boot classpath. See here for more information. This is required until Java 9 is released, as Java 8 does not have native support for HTTP/2.

So I added the vm option

Xbootclasspath/p:/Users/sarath/.m2/repository/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720//alpn-boot-8.1.9.v20160720.jar

in Intellij run configuration and everything works. I'm getting the push notification.

But when I deploy the war to tomcat and try to send the push notifications, I'm getting error:

20-Apr-2019 13:08:33.400 INFO [OkHttp https://api.development.push.apple.com/3/device/A704797F6E1E284FB081630184A26755B59593715E1CD543483C2136CE24D4FD] okhttp3.internal.Platform$JdkWithJettyBootPlatform.getSelectedProtocol ALPN callback dropped: SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?
20-Apr-2019 13:08:34.935 INFO [OkHttp https://api.development.push.apple.com/3/device/A704797F6E1E284FB081630184A26755B59593715E1CD543483C2136CE24D4FD] okhttp3.internal.Platform$JdkWithJettyBootPlatform.getSelectedProtocol ALPN callback dropped: SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?
20-Apr-2019 13:08:36.588 INFO [OkHttp https://api.development.push.apple.com/3/device/A704797F6E1E284FB081630184A26755B59593715E1CD543483C2136CE24D4FD] okhttp3.internal.Platform$JdkWithJettyBootPlatform.getSelectedProtocol ALPN callback dropped: SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?
20-Apr-2019 13:08:38.109 INFO [OkHttp https://api.development.push.apple.com/3/device/A704797F6E1E284FB081630184A26755B59593715E1CD543483C2136CE24D4FD] okhttp3.internal.Platform$JdkWithJettyBootPlatform.getSelectedProtocol ALPN callback dropped: SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?
failure: NotificationResponse{error=null, httpStatusCode=-1, responseBody='null', cause=java.io.IOException: unexpected end of stream on okhttp3.Address@d60ab6f0}

I'm not sure how to set alpn-boot on the boot class path. I tried executing

java -Xbootclasspath/p:/Users/sarath/.m2/repository/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720/alpn-boot-8.1.9.v20160720.jar

from command prompt. But this only shows some Java help commands. I don't know whether the jar is actually added to the boot class path.

I also tried using maven-surefire-plugin like it says here. But still getting the same error.

Here's my pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.cinch</groupId>
        <artifactId>gch</artifactId>
        <version>2.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <groupId>com.cinch.gch</groupId>
    <artifactId>apn</artifactId>
    <version>1.0.0</version>
    <packaging>war</packaging>
    <name>apn</name>
    <description>Contains push notification services</description>

    <properties>
        <java.version>1.8</java.version>
        <alpn-boot-version>8.1.9.v20160720</alpn-boot-version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>

        <dependency>
            <groupId>com.cinch.gch</groupId>
            <artifactId>core</artifactId>
            <version>1.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.cinch</groupId>
            <artifactId>gch-cache</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mortbay.jetty.alpn</groupId>
            <artifactId>alpn-boot</artifactId>
            <version>${alpn-boot-version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.clevertap.apns</groupId>
            <artifactId>apns-http2</artifactId>
            <version>1.0.3</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <argLine>
                        -Xbootclasspath/p:/Users/sarath/.m2/repository/org/mortbay/jetty/alpn/alpn-boot/${alpn-boot-version}/alpn-boot-${alpn-boot-version}.jar
                    </argLine>
                </configuration>
            </plugin>

        </plugins>
        <finalName>gch-apn</finalName>
    </build>

</project>

I tried many other things and nothing seems to work.

halfer
  • 19,824
  • 17
  • 99
  • 186
Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104
  • 1
    You could add the alpn-boot to Tomcat's lib folder or modify the `catalina.properties` file to include the jar file. Checkout Tomcats docs on their classloader hierarchy at https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html – ug_ Apr 23 '19 at 16:33
  • Just curious - if you are using `SpringBoot` then why do you build `war` and deploy to `Tomcat`? SpringBoot allows to bundle everything into fat jar (i.e. Tomcat will be bundled) and run `java -jar your_fat.jar` – Alexander Pavlov Apr 23 '19 at 16:37
  • @ug_ I did try that already. Not working. It's showing the same unexpected end of stream message – Drunken Daddy Apr 23 '19 at 16:48
  • @AlexanderPavlov we've tomcat server in production and all the applications are deployed there. – Drunken Daddy Apr 23 '19 at 16:56
  • 1
    If it must be on bootpath then you have to put it somewhere and add `-Xbootclasspath` option to java command-line arguments in `catalina.bat/.sh` – Alexander Pavlov Apr 23 '19 at 17:19
  • @HeisenBerg Can you tell us what version of the JRE and Tomcat you are running? Looks like theres some requirements on versions for HTTP/2. I am looking at http://tomcat.apache.org/whichversion.html under 8.x and 9.x. My guess here is that the log message you are getting is misleading and it should be using a different provider for ALPN. – ug_ Apr 23 '19 at 20:17
  • java version "1.8.0_102". I tried on both Tomcat 8.5.16 and 9.0.19. – Drunken Daddy Apr 24 '19 at 04:23
  • @AlexanderPavlov I got it to work following your last comment. I added a file setenv.sh in `tomcat_home/bin/ ` and its content is `export CATALINA_OPTS="-Xbootclasspath/p:/Users/sarath/.m2/repository/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720//alpn-boot-8.1.9.v20160720.jar" ` If you will post an answer, I'll accept it. – Drunken Daddy Apr 24 '19 at 05:04
  • :) I do not feel I answered this question, I just pointed to where to start looking. SO policy allows to answer own questions. – Alexander Pavlov Apr 24 '19 at 13:11
  • Over the below post, I could observe that http2 is meant only to push the resources like image,js,css and not for serving any other stuffs like a JSON response. https://stackoverflow.com/questions/14605273/http-2-will-support-server-push-what-does-this-mean Please can anyone throw some light on this. It seems UBER used its predecessor SPDY for push notification – raghav prakasam Aug 06 '19 at 05:39

1 Answers1

3

As pointed out by AlexanderPavlov in the comments.

If it must be on bootpath then you have to put it somewhere and add -Xbootclasspath option to java command-line arguments in catalina.bat/.sh

I created a file called setenv.sh inside Tomcat_Home/bin/

setenv.sh

export CATALINA_OPTS="-Xbootclasspath/p:/Users/sarath/.m2/repository/org/mortbay/jetty/alpn/alpn-boot/8.1.9.v20160720//alpn-boot-8.1.9.v20160720.jar"

catalina.bat/.sh will automatically read setenv.sh if it is present.

Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104