【问题标题】:ClassNotFoundException is thrown on attempt to start RMI server in a web service running under Jetty尝试在 Jetty 下运行的 Web 服务中启动 RMI 服务器时抛出 ClassNotFoundException
【发布时间】:2016-03-30 11:12:05
【问题描述】:

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

我想在 Zimbra (8.6.0, jetty-distribution-9.1.5.v20140505) 网络服务扩展中启动 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

【问题讨论】:

  • 这是真正的代码吗?通常使用该堆栈跟踪,我希望看到您在单独的进程中运行注册表。试试registry.rebind() 而不是Naming.rebind()
  • @EJP 是的,那是真正的代码。刚刚尝试使用registry.rebind() - 结果相同。
  • 不,这不是真正的代码。异常是由TestAddService 抛出的,你还没有发布任何这样的代码。
  • 抱歉,我将TestAddService 类重命名为TestServiceExtension,以免与TestAddServer 混淆(就在提问之前)。我刚刚恢复了该更改。
  • 我仍然不相信这是真正的代码,原因在我的回答中给出。这根本不可能。也许你没有运行你认为你正在运行的代码版本。

标签: java jetty rmi zimbra


【解决方案1】:
  1. 注册表的 CLASSPATH 中没有提到的类。
  2. 只有在将注册表作为单独的进程运行时才会发生这种情况。
  3. 这不是真正的代码。异常由TestAddService 引发,您尚未发布。
  4. 最简单的解决方案是按照您发布的代码在您的 JVM 中运行 Registry,这不可能抛出此异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2016-09-24
    • 2013-12-03
    • 2021-04-29
    • 2013-05-29
    相关资源
    最近更新 更多