在 GWT 中使用 RPC 时出现 IncompatibleRemoteServiceException

Posted

技术标签:

【中文标题】在 GWT 中使用 RPC 时出现 IncompatibleRemoteServiceException【英文标题】:IncompatibleRemoteServiceException while using RPC in GWT 【发布时间】:2012-03-21 13:08:21 【问题描述】:

我的 Web 应用程序项目具有 RPC 调用。

一个 RPC 异步工作正常。但是另一个给出了错误

    Mar 21, 2012 1:34:51 PM com.google.appengine.tools.development.ApiProxyLocalImpl log
SEVERE: javax.servlet.ServletContext log: ObjectStore: An      IncompatibleRemoteServiceException was thrown while processing this call.
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: This application is out of date, please click the refresh button on your browser. ( Blocked attempt to access interface 'com.client.RepositoryInterface', which is not implemented by 'com.server.ObjectStore'; this is either misconfiguration or a hack attempt )
at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:252)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:206)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)

工作 RPC

 public interface ConnectionInterface extends RemoteService

String connection(String[] authentication);

 public interface ConnectionInterfaceAsync 

void connection(String[] authentication, AsyncCallback<String> callback);

公共类 ConnectionService 实现 ConnectionInterfaceAsync

ConnectionInterfaceAsync service = (ConnectionInterfaceAsync)GWT.create(ConnectionInterface.class);

ServiceDefTarget endpoint = (ServiceDefTarget) service;

public ConnectionService() 

    endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc");


public void connectionCMIS(String[] authentication,
        AsyncCallback<String> callbackConnection) 

    service.connectionCMIS(authentication, callbackConnection);


//客户端调用

public class Login extends Composite  
 private ConnectionService connectionService = new ConnectionService();
// more code
 public void onClick(ClickEvent event) 
      AsyncCallback<String> callbackConnection = new AsyncCallback<String>() 

            public void onSuccess(String result) 
                             // print Succuss
                          
      
      connectionService.connection(authentication, callbackConnection );


无法使用 RPC

 public interface RepositoryInterface extends RemoteService 
public FolderCollection getRepositories();
 

 public interface RepositoryInterfaceAsync 
void getRepositories(AsyncCallback<FolderCollection> repositoryCallback);
 


  public class RepositoryService implements RepositoryInterfaceAsync

RepositoryInterfaceAsync async = (RepositoryInterfaceAsync)GWT.create(RepositoryInterface.class);
ServiceDefTarget endpoint = (ServiceDefTarget) async;

public CmisRepositoryService() 
    endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "repository");

public void getRepositories(
        AsyncCallback<FolderCollection> repositoryCallback) 

    async.getRepositories(repositoryCallback);


客户调用

 public class Workplace 
  private RepositoryService service = new RepositoryService();
  // some more code
  void doRepo()
    AsyncCallback<FolderCollection> repositoryCallback = new AsyncCallback<FolderCollection>() 

        public void onSuccess(FolderCollection result) 
        

        public void onFailure(Throwable caught) 
        
    ;

    service.getRepositories(repositoryCallback);
  
 

XML 代码

  <servlet>
  <servlet-name>ConnectionServlet</servlet-name>
   <servlet-class>com.server.ConnectionServiceImpl</servlet-class>
 </servlet>
<servlet>
 <servlet-name>ObjectStore</servlet-name>
<servlet-class>com.server.ObjectStore</servlet-class>

 <servlet-mapping>
 <servlet-name>ConnectionServlet</servlet-name>
 <url-pattern>/*</url-pattern>
  </servlet-mapping>
 <servlet-mapping>
 <servlet-name>ObjectStore</servlet-name>
 <url-pattern>/*</url-pattern>
 </servlet-mapping>

两个 RPC 的设计模式相似,但它仍然给我一个错误。

如果有人能告诉我为什么会有很大帮助

谢谢。

【问题讨论】:

【参考方案1】:

您的 URL 映射已关闭,您需要将 RPC RemoteServiceServlets 映射到更好的 url-pattern。您将两个 servlet 映射到 /*。当两个或多个 a 映射到完全相同的url-pattern 时,无法保证执行哪个 Servlet。所以我的猜测是,每次执行不工作的服务时,调用都会映射到其他服务。

解决这个问题的一种方法是使用 web.xml 之类的

<servlet-mapping>
  <servlet-name>ConnectionServlet</servlet-name>
  <url-pattern>/ConnectionService.rpc</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
   <servlet-name>ObjectStore</servlet-name>
   <url-pattern>/ObjectStoreService.rpc</url-pattern>
 </servlet-mapping>

当然,您还必须更改您的客户端服务以使用正确的serviceEntryPoint,所以

 endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "rpc");

必须改成类似的东西

 endpoint.setServiceEntryPoint(GWT.getHostPageBaseURL() + "ConnectionService.rpc");

获取正确的 servlet。

编辑:更改错误:

错误

 @ftr   `com.google.appengine.tools.development.ApiProxyLocalImpl log
SEVERE: javax.servlet.ServletContext log: ConnectionServlet: An IncompatibleRemoteServiceException was thrown while processing this call.
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: This application is out of date, please click the refresh button on your browser. ( Blocked attempt to access interface 'com.client.RepositoryInterface', which is not implemented by 'com.server.ConnectionServiceImpl'; this is either misconfiguration or a hack attempt )
at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:252)
at  com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:206)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)

所以如果你仔细看,错误是不同的:

阻止访问接口“com.client.RepositoryInterface”的尝试,该接口未由“com.server.ConnectionServiceImplObjectStore”实现

而不是

阻止访问接口“com.client.RepositoryInterface”的尝试,该接口未由“com.server.ObjectStore”实现

这意味着您的配置仍然错误,您必须将您的客户端RepositoryInterfaceAsync 指向实现RepositoryInterfaceRemoteServiceServlet

【讨论】:

我仍然遇到同样的错误。我正在更新您的代码中的错误。 @GameBuilder 你有其他实现com.server.ObjectStore 的服务吗?我刚刚意识到您对RepositoryInterface 的请求实际上已映射到该请求。我仍然认为这是您的 web.xml/service 入口点配置错误的情况。 不,只有一个服务在使用com.server.ObjectStore。但其他服务正在使用com.server.ConnectionServiceImplobjectStore extends ConnectionServiceImpl @GameBuilder 应该有一个RepositoryInterfaceImpl 或类似的东西来提供RepositoryInterface-RemoteService 的服务器端实现。您还需要在 web.xml 中声明它并在客户端上进行适当的服务端点定义。 @GameBuilder 您的更新显示ObjectStore 实现了存储库接口。为此,您还必须在客户端 Repository-Service 中调整 ServiceEndpoint-Definition - 因此您必须将 `endpoint.setServiceEntryPoint(GWT.getModuleBaseURL() + "repository");` 替换为 ` endpoint.setServiceEntryPoint(GWT.getHostPageBaseURL() + "ObjectStoreService.rpc");. This would point your client-side service to the ObjectStore`-您在 web.xml 中声明的 Servlet。这是服务入口点的任务 - 将您的客户端服务映射到服务器端 servlet。【参考方案2】:

这可能是您的 web-container 上 gwt-servlet.jar 版本配置错误。检查您的开发 gwt-servlet.jar 版本和 web 容器 gwt-servlet.jar 版本。 n 供参考 Misconfiguration or hack attempt

【讨论】:

以上是关于在 GWT 中使用 RPC 时出现 IncompatibleRemoteServiceException的主要内容,如果未能解决你的问题,请参考以下文章

检索 ArrayList 时出现 GWT-RPC 无法解释的 500 状态错误

执行 RPC 时出现 GWT 序列化问题

GWT:为 com.extjs.gxt.ui.client.data.BaseListLoadResult 分派传入 RPC 调用时出现异常

初始化 AsyncCallback 时出现 GWT RPC ClassNotFoundException

分派传入 RPC 调用时出现异常 java.lang.NoSuchMethodError: com.google.gwt.user.server.rpc.RPCRequest

调度传入 RPC 调用时出现异常