尝试在Jetty下运行的Web服务中启动RMI服务器时抛出ClassNotFoundException

时间:2016-03-30 11:12:06

标签: java jetty rmi zimbra

我知道这是一个常见的问题,但是在阅读了十几个类似的问题后,经过多次尝试,我仍然无法解决问题。

我想在Zimbra(8.6.0,jetty-distribution-9.1.5.v20140505)Web服务扩展中启动RMI。

服务器接口类位于服务扩展jar

$ jar -ft /opt/zimbra/lib/ext/addserver/addserver.jar | grep AddServer
com/gussy/zimbra/TestAddServer.class
com/gussy/zimbra/TestAddServerIntf.class

我尝试通过zmlocalconfig设置java选项,例如

zmlocalconfig -e zimbra_zmjava_options="-Xmx256m -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djava.net.preferIPv4Stack=true -Djava.rmi.server.useCodebaseOnly=true -Djava.rmi.server.codebase=file:///opt/zimbra/lib/ext/addserver/addserver.jar"

并尝试了

export CLASSPATH=/opt/zimbra/lib/ext/addserver/addserver.jar && zmmailboxdctl restart

还试图从java代码中设置java选项

System.setProperty("java.rmi.server.codebase", "file:///opt/zimbra/lib/ext/addserver/addserver.jar");
System.setProperty("java.rmi.server.useCodebaseOnly", "false");

但无法解决问题。

TestAddService.java

import com.zimbra.cs.extension.ExtensionHttpHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class TestAddService extends ExtensionHttpHandler {

    private static final Logger logger = LoggerFactory.getLogger(TestAddService.class);

    public TestAddService() {
    try {
        Registry registry = LocateRegistry.createRegistry(1099);
        TestAddServer testAddServer = new TestAddServer();
        Naming.rebind("TestAddServer", testAddServer);
    } catch (RemoteException | MalformedURLException e) {
        logger.error(null,e);
    }
    }

    @Override
    public String getPath() {
    return "/testadd";
    }

    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws IOException, ServletException {}
}

TestAddServer.java

package com.gussy.zimbra;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class TestAddServer extends UnicastRemoteObject implements TestAddServerIntf {
    private static final long serialVersionUID = 3527439814680102697L;

    protected TestAddServer() throws RemoteException {}

    @Override
    public int add(int a, int b) throws RemoteException {
    return a + b;
    }
}

TestAddServerIntf.java

package com.gussy.zimbra;

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

public interface TestAddServerIntf extends Remote {
    int add(int a, int b) throws RemoteException;
}

异常

2016-03-30 12:47:10,601 ERROR [main] [] TestAddService - 
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.gussy.zimbra.TestAddServerIntf (no security manager: RMI class loader disabled)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:420)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
    at sun.rmi.transport.Transport$1.run(Transport.java:178)
    at sun.rmi.transport.Transport$1.run(Transport.java:175)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:174)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:557)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:812)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:671)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:379)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
    at java.rmi.Naming.rebind(Naming.java:177)
    at com.gussy.zimbra.TestAddService.<init>(TestAddService.java:25)
    at pro.prokator.zimbra.ext.casem.SubscriptumExtension.init(SubscriptumExtension.java:53)
    at com.zimbra.cs.extension.ExtensionUtil.initAll(ExtensionUtil.java:116)
    at com.zimbra.cs.util.Zimbra.startup(Zimbra.java:263)
    at com.zimbra.cs.util.Zimbra.startup(Zimbra.java:178)
    at com.zimbra.soap.SoapServlet.init(SoapServlet.java:126)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:582)
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:372)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:847)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:300)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1359)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1352)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:744)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:497)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:125)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:107)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:154)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:125)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:107)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:125)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:107)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:125)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:107)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
    at org.eclipse.jetty.server.handler.DebugHandler.doStart(DebugHandler.java:140)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:125)
    at org.eclipse.jetty.server.Server.start(Server.java:358)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:107)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:60)
    at org.eclipse.jetty.server.Server.doStart(Server.java:325)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1250)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1174)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.eclipse.jetty.start.Main.invokeMain(Main.java:297)
    at org.eclipse.jetty.start.Main.start(Main.java:727)
    at org.eclipse.jetty.start.Main.main(Main.java:103)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: com.gussy.zimbra.TestAddServerIntf (no security manager: RMI class loader disabled)
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:410)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:268)
    at sun.rmi.transport.Transport$1.run(Transport.java:178)
    at sun.rmi.transport.Transport$1.run(Transport.java:175)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:174)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:557)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:812)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:671)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.gussy.zimbra.TestAddServerIntf (no security manager: RMI class loader disabled)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:556)
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255)
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1559)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
    ... 13 more

1 个答案:

答案 0 :(得分:1)

  1. 注册表没有CLASSPATH中提到的类。
  2. 只有当您将注册表作为单独的进程运行时才会发生这种情况。
  3. 这不是真正的代码。 TestAddService引发了例外情况,但您尚未发布。
  4. 最简单的解决方案是根据您发布的代码在JVM中运行Registry,这可能会导致此异常。