将RMI服务公开为REST时出错?

时间:2014-11-18 10:28:23

标签: java rest tomcat rmi

我正在尝试编写一个接受REST服务调用的应用程序层,并在RMI服务器上执行它们,检索响应并在格式化后将其发回。

我正在使用Jersey实现服务类并在Tomcat上运行它。我创建了一个在不同VM实例上运行的测试RMI服务器,以及在localhost上运行的rmiregistry。现在,当我调用REST URL时:

http://localhost:8080/Rest2RMI/rmi/getServerTime

我明白了:

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.lang.ClassNotFoundException: com.desmond.rmitest.ServerTimeImpl_Stub (no security manager: RMI class loader disabled)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at java.rmi.Naming.lookup(Unknown Source)
at com.desmond.rmitest.ServiceClass.getMessage(ServiceClass.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:540)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:715)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:221)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:107)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:76)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:934)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:90)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:515)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1012)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:642)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1555)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.desmond.rmitest.ServerTimeImpl_Stub (no security manager: RMI class loader disabled)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
... 44 more

我认为Tomcat使用自己的安全管理器,但是,我不确定是否需要它。当我在与Service类相同的包中运行客户端类时,它会毫无问题地输出日期,即使它位于与RMI服务器类不同的VM实例上。我查了一切,我无法理解我错过了什么。请检查我的代码和帮助。

我的代码如下:

ServerTimeInterface:

package com.desmond.rmitest;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface ServerTimeInterface extends Remote{
    public String getServerTime() throws RemoteException;
}

ServerTimeImpl:

package com.desmond.rmitest;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ServerTimeImpl extends UnicastRemoteObject implements ServerTimeInterface{

/**
 * 
 */
private static final long serialVersionUID = 1L;

public ServerTimeImpl() throws RemoteException {
    super();
}

@Override
public String getServerTime() throws RemoteException {
    System.out.println("Inside getServerTime() Implementation.");
    Date date = new Date();
    DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    String d = dateFormat.format(date);
    System.out.println("Data returned: "+d);
    return d;
}
}

的RMIServer:

package com.desmond.rmitest;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry;

public class RMIServer {

public static void main(String[] args){
    if(System.getSecurityManager() == null){
        System.setSecurityManager(new RMISecurityManager());
    }
    try{
        ServerTimeInterface stub = new ServerTimeImpl();
        System.out.println("Before rebinding");
        Naming.rebind("//localhost/serverdate", stub);
        System.out.println("Server started and rebind done");
    }catch(Exception e){e.printStackTrace();}
}
}

ServiceClass(在Tomcat上运行,此处定义的REST服务):

package com.desmond.rmitest1;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/rmi")
public class ServiceClass {

    @GET
    @Path("/test")
    @Produces(MediaType.TEXT_PLAIN)
    public String test(){
        return "All ok!";
    }

    @GET
    @Path("/getServerTime")
    @Produces(MediaType.TEXT_PLAIN)
    public String getServerTime(){
        String response = null;
        //Registry registry;
        try {
            ServerTimeInterface sti = (ServerTimeInterface) Naming.lookup("rmi://127.0.0.1:1099/serverdate");
            response = sti.getServerTime();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(response);
        return response;
    }
}

上面的类在Tomcat中抛出异常。但是,如果我运行以下操作,它会毫无问题地执行。:

RMIClient(与上面的Service类相同的包,作为普通的java应用程序运行):

package com.desmond.rmitest1;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;

public class RMIClient {
    public static void main(String[] args){
        if(System.getSecurityManager()==null){
            System.setSecurityManager(new RMISecurityManager());
        }
        String jsonDate;
        String date;
        try {
            ServerTimeInterface stub = (ServerTimeInterface) Naming.lookup("rmi://localhost:1099/serverdate");
            date = stub.getServerTime();
            System.out.println("Data received: "+date);
            jsonDate = "{\"Server date\":\""+date+"\"}";
            System.out.println("Data in JSON format: "+jsonDate);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

0 个答案:

没有答案