james david low

live / work / play / worship

iPhone Push Notifications with JavaPNS on Google App Engine

There have been several issues with getting JavaPNS working on Google App Engine. These included:
1) GAE didn’t support sockets or SSL
2) GAE doesn’t support signed jars, the BouncyCastle cryptography library is signed
3) GAE is transitioning to Java 7, and Java 7 has issues reading .p12 certificates

These instructions are for JavaPNS 2.2 and GAE 1.7.7, things may change on both fronts to make things either easier or harder.

1) GAE didn’t support sockets or SSL

With the arrival of GAE 1.7.7 sockets and SSL are now fully supported:
http://googleappengine.blogspot.com/2013/04/app-engine-177-released.html

2) GAE doesn’t support signed jars

Remove META-INF/MANIFEST.MF from the latest BouncyCastle jar or download my modified jar of BouncyCastle 1.48

3) Java 7 has issues reading .p12 certificates

a) Generate your .p12 certificate as per Apple’s instructions

b) Install Java 6 JDK

c) Use Java 6’s keytool to convert the .p12 to a .jks

keytool -importkeystore -destkeystore CERTIFICATES.jks -srckeystore CERTIFICATES.p12 -srcstoretype PKCS12

d) Configure JavaPNS to use the .jks format instead of .p12

boolean production = false;
String device = "DEVICE_ID";
String keystore = "CERTIFICATES.jks";
String password = "PASSWORD";
String message = "Hello JKS";

AppleNotificationServer jksServer = new AppleNotificationServerBasicImpl(keystore, password, ConnectionToAppleServer.KEYSTORE_TYPE_JKS, production);
PushNotificationPayload payload = PushNotificationPayload.alert(message);
PushNotificationManager pushManager = new PushNotificationManager();
pushManager.initializeConnection(jksServer);
List<PushedNotification> notifications = pushManager.sendNotifications(payload, Devices.asDevices(device));

Thanks to Palomino Labs Blog for the hints about Java and .p12 files:
http://blog.palominolabs.com/2011/10/18/java-2-way-tlsssl-client-certificates-and-pkcs12-vs-jks-keystores/


If you found any of the software useful, please consider supporting its further developement by donating.

3 Comments

    Hii..I am currently developing an app on GAE and got new requirement to include APNS functionality in it…I am currently using GAE 1.8 version so my question is using JavaPNS 2.2 and GAE 1.8 can we make end to end working APNS functionality and are both compatible with each other(GAE 1.8 and JavaPNS 2.2) and if it is not possible then will step 2 work in my case

    8:30pm / Jul 5th / 13 Mayuresh

    Thanks for your tutorial. Worked well for me.

    A simpler solution is

    Convert .p12 into .jks with Java6 keytool as you discribed.
    But then simply use Java7 keytool to convert the .jks back into .p12 format with this command:
    keytool -importkeystore -srckeystore CERTIFICATES.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore CERTIFICATES.p12

    The new .p12 Keystore works with Java7 and Java6 and you don’t have to change the JavaPNS codebase.

    Cheers!

    7:04pm / Nov 18th / 13 Thomas Püttmann

    not need to use jks. in jdk 1.7+, the passwd length of p12 file should be greater than or equal 6, javapns works well. otherwise, error happens as follows:
    [[1] not transmitted to token 595d8..725bf javapns.communication.exceptions.InvalidCertificateChainException: Invalid certificate chain (Received fatal alert: certificate_unknown)! Verify that the keystore you provided was produced according to specs…]

    1:21am / Jan 19th / 14 Chris