Git Product home page Git Product logo

java-apns's People

Contributors

arashthearcher avatar chupakabr avatar civanyp avatar derauk avatar emonti avatar flozano avatar froh42 avatar holmis83 avatar jakewharton avatar jcourtney1 avatar joekarl avatar jplock avatar kpiwko avatar l0s avatar lholmquist avatar matzew avatar mzachar avatar n3utrino avatar notnoop avatar ozgunawesome avatar pforhan avatar spark404 avatar srinivasannanduri avatar swankjesse avatar tmurakam avatar vijaygos avatar zdila avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-apns's Issues

Unhandled exception when sandbox is unavailable

I was doing some testing and it seems that sandbox doesn't respond anymore right now because I'm getting the following exception when I try to push a message:

org.apache.mina.core.RuntimeIoException: Failed to get the session.
at org.apache.mina.core.future.DefaultConnectFuture.getSession(DefaultConnectFuture.java:60)
at com.notnoop.apns.internal.MinaAdaptor.push(MinaAdaptor.java:48)
at org.epseelon.conferenceguide.MessageService$_sendMessageToDevices_closure2.doCall(MessageService.groovy:52)
at org.epseelon.conferenceguide.MessageService.sendMessageToDevices(MessageService.groovy:40)
at org.epseelon.conferenceguide.MessageService$$FastClassByCGLIB$$faaef4dd.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.epseelon.conferenceguide.MessageService$$EnhancerByCGLIB$$43987da7.sendMessageToDevices()
at org.epseelon.conferenceguide.SessionController$_closure6.doCall(SessionController.groovy:73)
at org.epseelon.conferenceguide.SessionController$_closure6.doCall(SessionController.groovy)
Caused by: java.net.ConnectException: Connection refused
at org.apache.mina.transport.socket.nio.NioSocketConnector.finishConnect(NioSocketConnector.java:223)
at org.apache.mina.transport.socket.nio.NioSocketConnector.finishConnect(NioSocketConnector.java:45)
at org.apache.mina.core.polling.AbstractPollingIoConnector.processConnections(AbstractPollingIoConnector.java:431)
at org.apache.mina.core.polling.AbstractPollingIoConnector.access$500(AbstractPollingIoConnector.java:63)
at org.apache.mina.core.polling.AbstractPollingIoConnector$Connector.run(AbstractPollingIoConnector.java:480)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:637)

Does it ring a bell? Maybe you could catch this exception inside ApnsService.push() and turn it into a more understandable exception. What do you think?

Socks Proxy support does not work in POOL mode

When using a socks proxy, the pool mode won't work.
In fact the instanciation of the ApnsSockets always use null as the proxy object passed to the constructor even if the proxy is setted in the ApnsConnectionImpl.

There is a simple fix to do in the copy() method to get it work as needed.

Tell me if you need a patch for this.

All exceptions wrapped in RuntimeException makes error handling difficult

All exceptions thrown from the lib are wrapped in RuntimeException, I guess to avoid having to handle them however it makes it much more complicated to use and present errors to the user of the application. In some cases (for feedback service) the actual cause of the problem gets wrapped in two RuntimeExceptions.

I would much prefer having to handle the "real" exceptions and be confident that my code is rubust and error prune instead of having to browse the source to the lib to actually know when to expect exceptions, which leads to a maintenance problem at the end.

Just a suggestion to an improvement to a really good lib

Problem in Installation

Hi

Am using MAC 10.5.8. I am unable to install this tool using the installation guide given in this blog. I downloaded and trying through "apns-0.1.2-jar-with-dependencies.jar". Can someone please help me how to install this?

Why not just return response in push()?

Is there a reason you chose to use the delegate methods on a separate thread to return the status event from the push()? It makes life much more difficult for the caller of push() because they have no clue when that async event will come in.

Also it seems you are returning the error code in connectionClosed() which seems misleading to me? Shouldn't that be the failed message send?

Detect invalid device tokens

From Stackoverflow 1759101: Multiple iPhone APN messages, single connection

Apple will silently drop your connection if it receives an invalid device token or a message that's too long. The next couple of messages after that will fail because they're just sent into the ether, essentially - the connection is closed, but the TCP window isn't exhausted.

At Urban Airship, where I work, we have a debug mode to use when people test their applications with push on our service. This will pause for a little bit after sending a message to ensure that this wasn't the issue - if the connection drops, we know it's an issue with the device token and report an error as such. A similar method might be a good way for you to check that this is, or is not, what's going on. Obviously this kills throughput and so we don't recommend it for a production environment.

call start twice using QueuedApnsService

I created an ApnsService using the "asQueued" parameter in the builder. While debugging other problems I thought I might have to call "start" on the service so I added that line in not realizing that the "build" method of the builder called start for me. Looking at the code, it looks like calling start twice is intended to be handled (restart?) because it stops it before re-starting. However, I think there is a problem with the logic. It correctly recreates the thread but it leaves the member variable "started" as false because on line 66 of QueuedApnsService it sets it as true, but the stop method sets it as false.

I think the solution is to move lines 66 and lines 67 below the call to stop on line 69.

Response error after sending messages with push(Collection<String> tokens, String payload)

Hi notoop,

first thank you very much for your great work on the java-apns lib. The lib was really helpful for me to understand how Apple Push Notifications work. I just have one issue which i couldn't resolve right now (using version 1.6:

If i send a single message to a Collection of Receivers(via their token) i get the following log:

15:55:42.187 [main] DEBUG c.n.apns.internal.ApnsConnectionImpl - Made a new connection to APNS
15:55:42.909 [main] DEBUG c.n.apns.internal.ApnsConnectionImpl - Message "com.notnoop.apns.EnhancedApnsNotification@1063a555" sent
15:55:42.909 [main] DEBUG c.n.apns.internal.ApnsConnectionImpl - Message "com.notnoop.apns.EnhancedApnsNotification@1063a574" sent
15:55:42.910 [main] DEBUG c.n.apns.internal.ApnsConnectionImpl - Message "com.notnoop.apns.EnhancedApnsNotification@107944a6" sent

Error: INVALID_TOKEN
Identifier: 1

The error code is delivered to my ApnsDelegate where connectionClosed is called.
All tokens which were sent are fake tokens, because right now the iPhone App is still in development so we don't receive any real tokens yet.

So my question is, why is there only one error message after sending? What happens with
the other messages? I have no feedback if they were accepted (they are not because of the
fake tokens) but i will never know this because i can't receive them. Is this a limitation of the Apple Push Notifications or just of the lib?

Thank you very much for your help!

Classloading problems on Glassfish

Hi,

unfortunately your jar is not usable in Glassfish 2.1 because it needs a newer version of Jackson than the one which comes bundled with Glassfish. Because of the classloading delegation the older version which is in $GLASSFISH/lib is loaded first. This leads to the following error:

javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:3903)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3803)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3605)
at com.sun.ejb.containers.WebServiceInvocationHandler.invoke(WebServiceInvocationHandler.java:201)
at $Proxy148.push(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.webservice.InvokerImpl.invoke(InvokerImpl.java:78)
at com.sun.enterprise.webservice.EjbInvokerImpl.invoke(EjbInvokerImpl.java:82)
at com.sun.xml.ws.server.InvokerTube$2.invoke(InvokerTube.java:146)
at com.sun.xml.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:257)
at com.sun.xml.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:93)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
at com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl.process(AbstractTubeImpl.java:106)
at com.sun.enterprise.webservice.MonitoringPipe.process(MonitoringPipe.java:147)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:115)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
at com.sun.xml.ws.api.pipe.helper.AbstractTubeImpl.process(AbstractTubeImpl.java:106)
at com.sun.xml.ws.tx.service.TxServerPipe.process(TxServerPipe.java:317)
at com.sun.enterprise.webservice.CommonServerSecurityPipe.processRequest(CommonServerSecurityPipe.java:222)
at com.sun.enterprise.webservice.CommonServerSecurityPipe.process(CommonServerSecurityPipe.java:133)
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:115)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436)
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:243)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:444)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:244)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:135)
at com.sun.enterprise.webservice.Ejb3MessageDispatcher.handlePost(Ejb3MessageDispatcher.java:113)
at com.sun.enterprise.webservice.Ejb3MessageDispatcher.invoke(Ejb3MessageDispatcher.java:87)
at com.sun.enterprise.webservice.EjbWebServiceServlet.dispatchToEjbEndpoint(EjbWebServiceServlet.java:231)
at com.sun.enterprise.webservice.EjbWebServiceServlet.service(EjbWebServiceServlet.java:157)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at com.sun.enterprise.web.AdHocContextValve.invoke(AdHocContextValve.java:114)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:87)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1093)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1093)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:291)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:666)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:597)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:872)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
at com.sun.enterprise.web.connector.grizzly.ssl.SSLReadTask.process(SSLReadTask.java:444)
at com.sun.enterprise.web.connector.grizzly.ssl.SSLReadTask.doTask(SSLReadTask.java:230)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:264)
at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.notnoop.apns.PayloadBuilder
at com.notnoop.apns.APNS.newPayload(APNS.java:48)
at com.service2media.m2active.m2push.Push.push(Push.java:162)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011)
at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175)
at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2929)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4020)
at com.sun.ejb.containers.WebServiceInvocationHandler.invoke(WebServiceInvocationHandler.java:190)
... 63 more

Does anyone see a potential solution?

Regards,
Herman Meerlo

java.lang.VerifyError on APNS.newPayload()

I am using java-apns in my push notification server. The process is run as an Apache Commons daemon using jsvc. I have a thread that runs every 'N' seconds and checks for new notifications. If it finds any it attempts to send them out. From the stack trace below, the error happens on line 80 of my NotificationManager class. The code I have on that line is:

String payload = APNS.newPayload().alertBody(notification.getMessage()).
                    badge(0).sound("default").build();

And this raises the exception below:

Exception in thread "Timer-0" java.lang.VerifyError: Cannot inherit from final class
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at com.notnoop.apns.PayloadBuilder.<clinit>(PayloadBuilder.java:47)
at ca.site.mobile.apns.service.NotificationManager.sendNotification(NotificationManager.java:80)
at ca.site.mobile.apns.service.NotificationManager.purgeNotifications(NotificationManager.java:64)
at ca.site.mobile.apns.service.NotificationChecker$1.checkForNotifications(NotificationChecker.java:46)
at ca.site.mobile.apns.service.NotificationChecker$1.run(NotificationChecker.java:41)
at ca.site.mobile.apns.scheduling.Scheduler$SchedulerTimerTask.run(Scheduler.java:18)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)

I've tried this on both Mac OSX and Linux running Java 1.6 with the same result. I am able to run that same line of code in a standalone java application (not using jsvc) without error but when run from within the daemon I get that error. I think it might have to do with running this as part of a daemon. Any ideas?
Thanks.

Add a method to APNS.newPayload().customFieldMap(Map map) to permit multiple custom fields to be added

Hi,
I can't see how to add multiple Map entries to a payload using the builder pattern. Say I have a Map of custom fields I want to add to APNS.newPayload().addCustomField(key, value) today I would have to do something awful like this -

if (map.size == 1)
{
.... get the key1 value1 out of the map
APNS.newPayload().addCustomField(key1, value1)....
}

if (map.size == 2)
{
.... get the key1 value1, key2, value2 out of the map
APNS.newPayload().addCustomField(key1, value1).addCustomField(key2, value2)....
}
if (map.size == 3)
{
......

It would be much handier to have
APNS.newPayload().addCustomFieldMap(Map map).....

Unless I am missing something obvious of course.

Thanks
Lindsay

Socket Timeout configuration

There is no parameter to set the Socket timeout, so in case of network failure, the system will wait very long time before it receives an error and report it to the delegate.

Enhanced notification identifier not available

The library auto-generates the identifier for use with the enhanced notification format (in AbstractApnsService.java). If there is a problem with a particular push, Apple returns the identifier associated with the problematic push, and the library wraps it up in a DeliveryError object that is returned from the ApnsDelegate's connectionClosed() callback.

However, there is no way to retrieve the identifier that is generated at the time the push is sent. So we cannot associate the identifier we receive in connectionClosed() with the token or message that caused the problem.

problem with client authentication (handshake failure)

I am getting a handshake failure at the begining of the conversation between my code and the sandbox/feedback servers of Apple. In my code, i construct an input stream, pointing to a p12 file that contains the original CSR (and thus my private key) and the certificate received from Apple using this CSR. After debugging, i noticed that my code does not send a certificate to the Apple's servers. After enabling the debug output for ssl, i also noticed that Apple's servers, at the end of ServerHello message they request a client certificate but do not provide an array of Cert Authorities as it is expected, as you can see from the following output:

Thread-7, READ: TLSv1 Handshake, length = 14
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Cert Authorities:
*** ServerHelloDone

Has anybody else faced such an issue? Am i doing something wrong? Any answer will be greatly appreciated.

Exception while waiting for error code

Whenever I push notifications and stop the service I see this error message.

[ApnsConnectionImpl] Exception while waiting for error code
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:755)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at java.io.InputStream.read(InputStream.java:85)
at com.notnoop.apns.internal.ApnsConnectionImpl$1MonitoringThread.run(ApnsConnectionImpl.java:102)

It looks to me like the problem is that the Monitoring thread reads the socket even though the socket has been closed by the stop method. My code is basically just this:

ApnsService service = null;
try{
service = APNS.newService()
.withCert(SSL_CERTIFICATE_FILE, SSL_CERTIFICATE_PASSWORD)
.withGatewayDestination(APPLE_APN_HOST, APPLE_APN_PORT)
.withFeedbackDestination(APPLE_APN_FEEDBACK_HOST, APPLE_APN_FEEDBACK_PORT)
.withReconnectPolicy(ReconnectPolicy.Provided.NEVER)
.build();
service.push(destination, payload);
finally{
service.stop();
}

Please add support for Newsstand notification

For the Newsstand notification, the payload will need to contain the following:
{
‘aps’:{
‘content-available’:1
}
}

Can this support be added to the PayloadBuilder class? Or maybe at least make "aps" a public or protected member the caller can write to directly. The customField() function cannot be used since it writes to the "root" element and not to the "aps" element.

Please see this video for more details about Newsstand support.

https://developer.apple.com/videos/wwdc/2011/?regToken=ZupF49WbcggW%252Bm15GZvMZMNgkdCsE3oHQyfpvDLrnvxgXxAcS9ZDZeosayfihFItTAGFzeirS4ta%250D%250AtZboD4%252BpyWLtp6AS1Owd0rntpYGZQwg%253D%250D%250A

the connectionClosed of ApnsDelegate couldn't be called.

I'm using this library to send notifications and it's great. I want to get the error-response after pushed the message, and I created my implementation of ApnsDelegate. however the method 'connectionClosed' never been called in my program. I debugged and found it's blocked at ApnsConnectionImpl.monitorSocket, it tried to read the response from socket, but nothing returned and it's blocked.

any idea for this?

Notification Not Delivered

I've a webapp sending out notification to the sandbox and another standalone test app sending notification to the sand box as well with the same cert and the same set of devices. In my webapp, the notification is not being delivered; but it delivers fine from my simple test app. There is no exception in the case when the notification is not delivered. I stepped into the code at ApnsConnectionImpl.sendMessage(), and compared the difference. I found the socket is at connectionState = 1 and the ssl session is still with SSL_NULL_WITH_NULL_NULL cipher suite. In the successful case, the ssl session is with SSL_RSA_WITH_RC4_128_MD5 cipher suite.

Do you have any idea what would be the problem?

Thanks.
kc

Notifications are sometimes not sent using pooled connections combined with EveryHalfHour reconnect policy

When running in pooled connection mode, one connection is initially created in the build method as well as one ReconnectPolicy instance. Once the threads in the pool starts to become used a copy (clone) of the initial connection is created and placed in the pool (using ThreadLocal). The problem occurs when running with the EveryHalfHour reconnect policy and the reason is that only one instance is ever created of this class and because it contains state (lastRunning) we have trouble. All threads in the pool share the same instance, and therefore when one connection has been reconnected, then all connections are defined as being reconnected which they are not. After some time Apple hangs up the connection silently, and this is not identified by the socket which therefore just believes it is connected. This results in the java-apns lib behaiving like everything is OK, but actually most of the notifications being sent never go trough.

I have locally corrected the problem by adding a copy method to the ReconnectPolicy interface as well as implementations and then call this whenever the connection object is being copied (cloned). This ensures that each connection has it's own reconnectpolicy and therefore that all connections are renewed every half hour.

Btw. is there a good reason why the connection is always reconnected when it has existed 30 minutes - typically it should only be necessary when it has been idle for 30 min or more?

Anyway I can send you my solution if you like, but it takes 3 min to impl. (o;

Detect Common starters errors

It'll be great if the library has a debug mode to detect common beginners errors. Needless to say the error messages should be quite meaningful to the audience.

Sample:

  1. Programmers mistake the UUID with the push notification device token.
    For now, this requires a simple length check probably.
  2. Passing a non-json representation string to ApnsService.
    This may require introducing new datatypes (e.g. Payload) or having ApnsService accept PayloadBuilder as an argument.

Multiple Messages

Hi,

I'm investigating using your library to send push notifications. I was wondering is it possible to send multiple messages via a single service i.e.

String payload = APNS.newPayload()
.badge(3)
.customField("secret", "what do you think?");
.localizedKey("GAME_PLAY_REQUEST_FORMAT")
.localizedArguments("Jenna", "Frank")
.actionKey("Play").build();

service.push(token1, payload1);
service.push(token2, payload2);

or do you have to build the service object for each individual push call? I can't tell from the documentation.

Look forward to hearing from you.

Important changes to Apple Push Notification certificates

Any updates needed to support this requirement from Apple?

On December 22, 2010, the production Apple Push Notification service will begin to use a 2048-bit TLS/SSL certificate that provides a more secure connection between your provider server and the Apple Push Notification service.
To ensure you can continue to validate your server's connection to the Apple Push Notification service, you will need to update your push notification server with a copy of the 2048-bit root certificate from Entrust's website. This will not require a change to your iOS apps -- this update only applies to provider servers.

Provide test-jar, javadoc-jar, source-jar

Hi,

It would be great to deploy a test jar. Some utility classes are very useful.
It would be also great to deploy javadoc & source jars.

Here are some configuration to add to pom project:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>test-jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>2.5</version>
            <executions>
                <execution>
                    <goals>
                        <goal>jar</goal>
                        <goal>javadoc</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.0.4</version>
            <executions>
                <execution>
                    <id>bind-sources</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>true</downloadJavadocs>
            </configuration>
        </plugin>

sound not emmited

Despite using the 'default' sound no sound is emmited:

PayloadBuilder apnsPayLoad = APNS.newPayload();
apnsPayLoad.alertBody(textMessage);
apnsPayLoad.sound("default");

thanks for your Help,

Restore connection on INVALID_TOKEN error

When we try to send a notification to an inactive device, Apple drops our connection and further messages are not sent.
I know that I can trace this with using a delegate with connectionClosed method.

The question is, how can we restore the connection afterwards, any idea?

Looping if no connection to APN Server or host is unknown

If the connection to the APN Server is not available for some reason (firewall, apple service down, network down etc) or if DNS is unavailable making it impossible to lookup the apple server, then the socket() method in the ApnsConnectionImpl will loop forever (or at least until a connection is established) it should retry in the same way as the sendMessage method below, perhaps with some more delay I don't know, but it should have a limit.

resizeAlertBody() is not multibyte-safe

PayloadBuilder.resizeAlertBody() does not handle multi-byte characters. First, the postfix size in bytes can be larger than its string length, resulting in an oversize payload. Second, it chops off a number of characters, when actually only the calculates number of bytes are needed.

The tricky thing is how to truncate a UTF-8 encoded byte array correctly, so we don't split characters in the middle. I have Groovy code to do this, which I can contribute if you like (can be trivially translated to Java).

Feedback did not return any information .

Where I try to run my code to get feedback information, nothing return . Why ? Can some advice be given ? My code is shown bellow .

ApnsService apn = APNS.newService().withCert("_dev_key.p12", "_")
.withFeedbackDestination("feedback.sandbox.push.apple.com",2196).withSandboxDestination().build();
apn.start();
Map a= apn.getInactiveDevices();
System.out.println ( a.size() );

Thanks .

sockets are recreated and aren't closing after push

I'm running into an issue which is causing the number of sockets to increase over time as I perform more service.push()'s. The lsof -p of the process shows these increasing:

java    13741 root  386u  sock        0,4      0t0 2475108674 can't identify protocol

Eventually my process hits the open file limit and craps out after trying to open a new socket (which happens to be to the DB).

I'm not using any special configuration for reconnect policy and such:

ApnsService service = APNS.newService()
    .withCert( cert, pass )
    .withSandboxDestination()
    .build();

Any ideas?

Feedback service missing socks proxy socket

The method com.notnoop.apns.internal.ApnsConnectionImpl.socket() can connect to a socks proxy and then use that socket to connect to Apple's push service. Although com.notnoop.apns.internal.ApnsFeedbackConnection.getInactiveDevicesImpl() only can connect directly to Apple's feedback service. Can you please add the missing socks proxy functionality into the ApnsFeedbackConnection class?

Stephen

Error detection with connection pool

Hi,
I'm trying to make a connections pool with error detection (with no success...). I've found in the ApnsConnectionImpl class code that the copy() method, wich is called by ApnsPooledConnection, doesn't take the errorDetection field value.
Is it an implementation choice or an oversight ?

Thanks

Please explain tags and release JARs

I notice that the Downloads only has release JARs up to 0.1.2 but there are tags and source bundles available for 0.1.3 and 0.1.4. Please explain. Is there a reason for the absence of 0.1.3 or 0.1.4 JARs? Is the code at those tags considered stable and "safe to use?"
Thanks.

Issues when building from source

Hi,
Your project seems to be the most advanced one compared to javapns and apns4j, in terms of features and documentation. But since you don't provide a binary distribution yet, I downloaded source from github and launched mvn install on the command line. But I miss 3 dependencies (logback-classic, json-lib and mina-core) and before tinkering with the respective projects and recreate those dependencies in my local repository, I wanted to make sure they are not already available somewhere in a repository that is just configured locally on your machine?

Also, are you thinking of releasing a binary distribution soon?

Cheers.

Reconnecting doesn't appear to work when using SOCKS proxy

My uneducated guess is that the problem comes down to the SOCKS proxy socket not being closed when the main socket is closed; I see a connect but no close's anywhere for the underlyingSocket in ApnsConnectionImpl.

com.notnoop.exceptions.NetworkIOException: java.net.SocketException: already connected
at com.notnoop.apns.internal.ApnsConnectionImpl.socket(ApnsConnectionImpl.java:146) [apns-0.1.5.jar:na]
at com.notnoop.apns.internal.ApnsConnectionImpl.sendMessage(ApnsConnectionImpl.java:160) [apns-0.1.5.jar:na]
at com.notnoop.apns.internal.ApnsServiceImpl.push(ApnsServiceImpl.java:46) [apns-0.1.5.jar:na]
at com.notnoop.apns.internal.AbstractApnsService.push(AbstractApnsService.java:52) [apns-0.1.5.jar:na]
at com.notnoop.apns.internal.ApnsServiceImpl.push(ApnsServiceImpl.java:36) [apns-0.1.5.jar:na]
...
Caused by: java.net.SocketException: already connected
at java.net.Socket.connect(Socket.java:500) [na:1.6.0_07]
at java.net.Socket.connect(Socket.java:469) [na:1.6.0_07]
at com.notnoop.apns.internal.ApnsConnectionImpl.socket(ApnsConnectionImpl.java:135) [apns-0.1.5.jar:na]
... 73 common frames omitted

Problem with empty or null password in 'APNS.newService().withCert(certificate.p12, password)'

When a password was not defined on keyStore generation I have the following situations:

1 - Using a null password in APNS.newService().withCert(certificate.p12, password) returns a "NullPointerException";

2 - Using an empty password in APNS.newService().withCert(certificate.p12, password) returns "java.io.IOException: failed to decrypt safe contents entry: java.lang.ArithmeticException: / by zero"

Problem with apns: certificate_expired?

Hi!

Following the description on the wiki page I updated my keystore to include all the keys from Apple's apns service. However, when I talk to the feedback server, I do still get an SSLHandshakeException. Before the update, the Exception was

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Now it's

Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_expired
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1657)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:744)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:50)
at java.io.DataInputStream.readInt(DataInputStream.java:370)
at com.notnoop.apns.internal.Utilities.parseFeedbackStreamRaw(Utilities.java:192)

I think it would be helpful if this project would use some kind of AllTrustingSSLSocketFactory, not bothering with what f***up Apple is doing with it's servers.

Regards
Christian

MonitoringThread throws SocketException when socket being monitored closes

MonitoringThread throws SocketException when the socket being monitored closes. This happens, for example, when using the ReconnectPolicy.EVERY_HALF_HOUR. The relevant socket gets closed and a new one gets reset. Meanwhile, the MonitoringThread is still tracking that closed socket. The method call

in.read(bytes)

in ApnsConnectionImpl.MonitoringThread is blocking until something happens. Unfortunately, that something happens to be the closing of the socket, at which point it throws java.net.SocketException.

To reproduce issue:

  • Create custom ReconnectPolicy with period of 15 seconds.
  • Send out a notification once every second.
  • Watch an error crop up every ~15 iterations.

Potential fixes:
I spent too much time on this to get so little result. The shame.

  • Tried shutting down thread, but I avoided Thread.stop() (cf. Effective Java 2nd Ed Item 66) and tried a synchronized boolean, but the thread blocks on the method read method so there's no acknowledging the flag.
  • Tried shutting down the socket with shutdownInput(), but I get "java.lang.UnsupportedOperationException: The method shutdownInput() is not supported in SSLSocket"
  • Unless you think of something more clever, it's...
  • Catch the "Socket closed" exception. Ugh.

support for the feedback service?

Hi,

First I would like to thank you for the great job you've already done with this library.

Is there any chance of adding support for retrieving tokens from the feedback service?

Thanks,
David

JARs for 0.1.4

I would like to see JARs available for download for version 0.1.4, please. (It appears that java-apns is on version 0.1.4, but only 0.1.2 is available.) It would also be nice to have src JARs in here as well. Thanks!

Allow Executor to be configured in pooled connections

It would be nice to be able to configure some aspects of the Executor used for pooled connections. Right now, I think if all the threads in the pool are busy, say, attempting a retry when an IOException is raised, incoming push requests are rejected by the Executor, and the delegate's messageSendFailed() method is not called.

Java's ThreadPoolExecutor allows a custom RejectedExecutionHandler to decide what to do. For example, I would like to be able to specify that java-apns block while the threads are busy (CallerRunsPolicy), or just to discard the incoming requests (DiscardPolicy).

withNoErrorDetection() does not work

ApnsServiceBuilder.withNoErrorDetection() seems to set errorDetection to true (the default value) instead of false, so it is always enabled:

public ApnsServiceBuilder withNoErrorDetection() {
this.errorDetection = true;
return this;
}

Support for launch image

iPhone OS 4.0 is now supporting launch-image property.

The filename of an image file in the application bundle; it may include the extension or omit it. The image is used as the launch image when users tap the action button or move the action slider. If this property is not specified, the system either uses the previous snapshot,uses the image identified by the UILaunchImageFile key in the application’s Info.plist file, or falls back to Default.png.

Enrich API to be able to send notification when device tokens are byte[]

ApnsService has a nice push method that takes a collection of String deviceTokens and a payload. And from what I've seen, you decode those deviceTokens to turn them into byte[] arrays.
In my case, deviceToken's are stored directly as byte[].
So would it be possible for you to add a public void push(Collection<byte[]> deviceTokens, String payload) method to ApnsService?

License of project and integrating with Apache Camel

Hi

I noticed the license file, but I cannot see if its based on any of the public and regular used licenses such as: Apache, BSD, LGPL etc.

The reason I am asking is that we would like to integrate Apache Camel with this project, and thus we must ensure there are no license implications doing so.

The Apache Software Foundation has a license policy which outlines approved here:
http://www.apache.org/legal/3party.html

But we can hose the integration outside Apache as we do
http://code.google.com/a/apache-extras.org/p/camel-extra/?redir=1

Regards

Claus Ibsen

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.