问题描述:

I have successfully deployed the GCM sample applications on both server & client side. I am able to register the devices successfully . But when I am trying to send message to the devices , the following exception is being shown on the server log:

Exception in thread "pool-1-thread-1" java.lang.IllegalArgumentException: argume

nt cannot be null

at com.google.android.gcm.server.Sender.nonNull(Sender.java:553)

at com.google.android.gcm.server.Sender.getString(Sender.java:534)

at com.google.android.gcm.server.Sender.sendNoRetry(Sender.java:365)

at com.google.android.gcm.server.Sender.send(Sender.java:261)

at com.google.android.gcm.demo.server.SendAllMessagesServlet$1.run(SendA

llMessagesServlet.java:119)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec

utor.java:886)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor

.java:908)

at java.lang.Thread.run(Thread.java:662)

Exception in thread "pool-1-thread-2" java.lang.IllegalArgumentException: argume

nt cannot be null

at com.google.android.gcm.server.Sender.nonNull(Sender.java:553)

at com.google.android.gcm.server.Sender.getString(Sender.java:534)

at com.google.android.gcm.server.Sender.sendNoRetry(Sender.java:365)

at com.google.android.gcm.server.Sender.send(Sender.java:261)

at com.google.android.gcm.demo.server.SendAllMessagesServlet$1.run(SendA

llMessagesServlet.java:119)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec

utor.java:886)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor

.java:908)

at java.lang.Thread.run(Thread.java:662)

On the browser ,

the following message displayed , but the devices doesnot receive any message due to the exception.

Asynchronously sending 1 multicast messages to 2 devices

Any hints / suggestions will be helpful.

网友答案:

I was getting the exact same error. Looking at the source code for Sender.java, this appears to happen right when the Sender tries to figure out the nature of the error via HttpURLConnection.getErrorStream().

if (status != 200) {
  // Exception on the line below due to getErrorStream() returning null
  responseBody = getString(conn.getErrorStream()); 
  logger.finest("JSON error response: " + responseBody);
  throw new InvalidRequestException(status, responseBody);
}

In my case the error was getting triggered due to the gcm server returning a 401 (I had forgotten I was VPNed to work and had not white-listed that IP on my Google API account).

You are likely getting a non 200 status from the server. Try looking at what the problem is via:

$ curl -D headers.txt --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send  -d "{\"registration_ids\":[\"$registrationID\"]}" && cat headers.txt

where $api_key is your apiKey and $registrationID is the destination registration Id.

The fact that the Sender doesn't handle this correctly is a different problem though, I'm not sure if it's related to the way the gcm library is attempting to read the error or if it's an issue with the jdk.. (1.6 here). It is very odd that this is getting thrown given that the GCM docs mention this scenario explicitly.

According to the docs, getErrorStream() will return null:

if there have been no errors, the connection is not connected or the server sent no useful data.

  • We know there was an error (status code != 200 checked)
  • We know there was a connection (401 was returned in my case)
  • We know the server sends useful data:

From an unauthorized ip:

[[email protected] ~]$ curl -D headers.txt --header "Authorization: key=$api_key" --header Content-Type:"application/json" https://android.googleapis.com/gcm/send  -d "{\"registration_ids\":[\"$registrationID\"]}" && cat headers.txt

<HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
HTTP/1.1 401 Unauthorized
Content-Type: text/html; charset=UTF-8
Date: Tue, 14 Aug 2012 00:30:47 GMT
Expires: Tue, 14 Aug 2012 00:30:47 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Transfer-Encoding: chunked

EDIT: This has now been entered as an issue to the GCM project here: http://code.google.com/p/gcm/issues/detail?id=7

EDIT: The issue has been fixed and should be available on the next release of the gcm.jar helper classes.

网友答案:

Argument to the Sender must not be null. Check in logs if you are passing null as argument to the Sender. For example if you have something like:

Sender sender = new Sender(businessLayer.Helper.getAndroidAPIkey());

if for some reason businessLayer.Helper.getAndroidAPIkey() is null you will get this exception.

相关阅读:
Top