Java 将RMI与JSF和Tomcat一起使用

Java 将RMI与JSF和Tomcat一起使用,java,tomcat,rmi,Java,Tomcat,Rmi,我想用RMI编写一个简单的应用程序。在服务器端,我有一个接口foo和一个类fooImpl。 我的界面是: import java.rmi.Remote; public interface Foo extends Remote { public String exec(String test) throws Exception; } import java.rmi.server.UnicastRemoteObject; public class FooImpl extends Unic

我想用RMI编写一个简单的应用程序。在服务器端,我有一个接口foo和一个类fooImpl。 我的界面是:

import java.rmi.Remote;

public interface Foo extends Remote {
   public String exec(String test) throws Exception;
}
import java.rmi.server.UnicastRemoteObject;

public class FooImpl extends UnicastRemoteObject implements Foo {

    public FooImpl() throws Exception {
        java.rmi.registry.LocateRegistry.createRegistry(1099);
        java.rmi.Naming.rebind("myFoo",this);
    }

    public String exec(String test) {
        return "This is a Test";
    }

    public static void main(String[] args) {
        try {
            FooImpl fooImpl = new FooImpl();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
我对上述接口的实现是:

import java.rmi.Remote;

public interface Foo extends Remote {
   public String exec(String test) throws Exception;
}
import java.rmi.server.UnicastRemoteObject;

public class FooImpl extends UnicastRemoteObject implements Foo {

    public FooImpl() throws Exception {
        java.rmi.registry.LocateRegistry.createRegistry(1099);
        java.rmi.Naming.rebind("myFoo",this);
    }

    public String exec(String test) {
        return "This is a Test";
    }

    public static void main(String[] args) {
        try {
            FooImpl fooImpl = new FooImpl();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
在客户端,我有一个使用PrimeFace的web应用程序,它在Tomcat上运行。客户端有一个IndexBean:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

@ManagedBean
@RequestScoped
public class IndexBean {

    public void execute() {
        try {
            Foo foo = (Foo) java.rmi.Naming.lookup("//localhost/myFoo");
            System.out.println(foo.exec());
        } catch (NotBoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}
当我执行代码时,在客户端出现以下错误:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

@ManagedBean
@RequestScoped
public class IndexBean {

    public void execute() {
        try {
            Foo foo = (Foo) java.rmi.Naming.lookup("//localhost/myFoo");
            System.out.println(foo.exec());
        } catch (NotBoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}
java.rmi.UnmarshalException:错误解组返回;嵌套 异常为:java.lang.ClassNotFoundException:Foo(无安全性 管理器:RMI类加载程序(已禁用)位于 sun.rmi.registry.RegistryImpl\u存根查找(未知源)位于 java.rmi.Naming.lookup(Naming.java:101)位于 execute(IndexBean.java:15)位于 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)位于 invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 位于java.lang.reflect.Method.invoke(Method.java:606) org.apache.el.parser.AstValue.invoke(AstValue.java:245)位于 org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:277) 在 org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression.invoke(ContextAwareTagMethodExpression.java:96) 在 javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:88) 位于javax.faces.event.ActionEvent.processListener(ActionEvent.java:51) 在 javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:409) 在javax.faces.component.UICommand.broadcast(UICommand.java:103)中 javax.faces.component.UIViewRoot.\u broadcastAll(UIViewRoot.java:1013) 在 javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:284) 位于javax.faces.component.UIViewRoot.\u进程(UIViewRoot.java:1302) 在 javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:745) 在 org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:38) 在 org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170) 在 org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117) 位于javax.faces.webapp.FacesServlet.service(FacesServlet.java:197) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 在 org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1081) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) 在 org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在java.lang.Thread.run(Thread.java:744)处,由以下原因引起: java.lang.ClassNotFoundException:Foo(无安全管理器:RMI类 加载程序(已禁用)位于 loadProxyClass(LoaderHandler.java:553) 在 RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646) 在 rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311) 在 sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255) 在 java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1558) 在 java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514) 在 java.io.ObjectInputStream.ReadOrderinaryObject(ObjectInputStream.java:1771) 位于java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350) 位于java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) ... 44多


此外,我还更改了Tomcat使用的端口,以避免与RMI端口冲突。

客户机的类路径上没有远程接口,或者可能也没有存根。要避免使用存根,请添加

super(0);
作为构造函数的第一行


注意:您必须将
createRegistry()
的结果存储在静态变量中,以防止注册表退出。

客户端也有Foo接口。一、 另外,从Foo接口创建了一个jar文件,并将其放在WEB-INF的lib文件夹中,但没有任何更改。我在FooImpl的构造函数中添加了“super(0);”,但没有任何更改。客户端没有
Foo
。例外情况是这样的。这个问题更多地与Java和RMI有关。JSF与这个问题无关。