Google app engine NoClassDefFoundError:javax.naming.directory.InitialDirContext是一个受限类。在Google应用程序引擎中使用CCS(GCM)

Google app engine NoClassDefFoundError:javax.naming.directory.InitialDirContext是一个受限类。在Google应用程序引擎中使用CCS(GCM),google-app-engine,google-cloud-messaging,Google App Engine,Google Cloud Messaging,我正在尝试使用google App Engine实现google的云连接服务器,遵循本教程- . 我从(smack.jar和smackx.jar)复制了最新的smack jar,将它们放在WEB-INF/lib中,并将它们添加到类路径中(我使用eclipse) 在我发布的第一个链接中的代码示例中,XMPPConnection是通过“main”方法启动的。由于这不适合GAE,我创建了一个ServletContextListener并将其添加到web.xml中 public class GCMCon

我正在尝试使用google App Engine实现google的云连接服务器,遵循本教程- . 我从(smack.jar和smackx.jar)复制了最新的smack jar,将它们放在WEB-INF/lib中,并将它们添加到类路径中(我使用eclipse)

在我发布的第一个链接中的代码示例中,XMPPConnection是通过“main”方法启动的。由于这不适合GAE,我创建了一个ServletContextListener并将其添加到web.xml中

public class GCMContextListener implements ServletContextListener {

   private static final String GCM_SENDER_ID = "*GCM_SENDER_ID*";
   private static final String API_KEY = "*API_KEY*";

   private SmackCcsClient ccsClient;

   public GCMContextListener() {
   }

   @Override
   public void contextInitialized(ServletContextEvent arg0) {
       final String userName = GCM_SENDER_ID + "@gcm.googleapis.com";
       final String password = API_KEY;

       ccsClient = new SmackCcsClient();

       try {
           ccsClient.connect(userName, password);
       } catch (XMPPException e) {
           e.printStackTrace();
       }
   }

   @Override
   public void contextDestroyed(ServletContextEvent arg0) {
       try {
           ccsClient.disconnect();
       } catch (XMPPException e) {
        e.printStackTrace();
       }
   }
}
web.xml

<web-app> 
   <listener>
       <listener-class>com.myserver.bootstrap.GCMContextListener</listener-class>
   </listener>
</web-app>

com.myserver.bootstrap.GCMContextListener
现在,当我启动GAE服务器时,出现以下异常:

java.lang.NoClassDefFoundError:javax.naming.directory.InitialDirContext是一个受限类。有关更多详细信息,请参阅谷歌应用程序引擎开发者指南。


我在“谷歌应用引擎开发者指南”中搜索了更多细节,但没有找到任何相关信息。你能帮我吗?

谷歌应用程序引擎限制对某些JRE类的访问。事实上,他们发表了一篇文章,告诉你哪些类是可用的。在我看来,Smack库可能需要一些对目录上下文的引用(可能是为了创建XMPP消息?),这就是为什么servlet会导致此异常。不在白名单中

我目前正在建立一个GCM服务器。在我看来,您需要通读这个示例,看看主方法在做什么。我看到的是与GCM服务器的连接:

try {
  ccsClient.connect(userName, password);
} catch (XMPPException e) {
  e.printStackTrace();
}
然后,向设备发送下游消息:

// Send a sample hello downstream message to a device.
String toRegId = "RegistrationIdOfTheTargetDevice";
String messageId = ccsClient.getRandomMessageId();
Map<String, String> payload = new HashMap<String, String>();
payload.put("Hello", "World");
payload.put("CCS", "Dummy Message");
payload.put("EmbeddedMessageId", messageId);
String collapseKey = "sample";
Long timeToLive = 10000L;
Boolean delayWhileIdle = true;
ccsClient.send(createJsonMessage(toRegId, messageId, payload, collapseKey,
    timeToLive, delayWhileIdle));
//向设备发送示例hello下游消息。
String toRegId=“RegistrationIdOfTheTargetDevice”;
字符串messageId=ccsClient.getRandomMessageId();
Map payload=newhashmap();
payload.put(“你好”,“世界”);
有效载荷put(“CCS”,“虚拟消息”);
payload.put(“EmbeddedMessageId”,messageId);
字符串collapseKey=“sample”;
长期寿命=10000升;
布尔delayWhileIdle=true;
ccsClient.send(createJsonMessage(toRegId、messageId、payload、collapseKey、,
时间的推移,延迟(有时);
}

这些操作将在应用程序生命周期的某个时间点完成,因此您的servlet应该通过提供示例正在实现的方法来支持它们,例如我粘贴在这里的第一段代码中出现的connect方法。如果我没有弄错的话,它的实现在235行的示例中

正如文档所述,您正试图使用GAE实现的第三方应用程序服务器应该是:

能够与客户沟通。 能够向GCM服务器发出格式正确的请求。 能够处理请求并根据需要重新发送,使用指数后退。 能够存储API密钥和客户端注册ID。API密钥包含在发送消息的POST请求的标头中。 能够存储API密钥和客户端注册ID。
能够生成消息ID以唯一标识它发送的每条消息。

我能够使用“旧”http协议实现gcm。我只是假设,如果谷歌发布一些新的做事方式,它将得到现有基础设施的支持。谷歌的云应用服务器应该支持谷歌的云消息传递,我错了吗?显然我是。他们文档中的广告库(Smack)由于其白名单而不能在GAE基础设施上工作,这看起来确实很奇怪。即使他们声明第三方服务器的实现取决于开发人员,在这种情况下GAE的PaaS方法似乎是缺乏的。为了使用新的GCM实现,我必须将服务器部署到另一个提供商中。另一种选择是使用另一个库而不是Smack,一个不需要JNI的库。