运行 Tomcat 在不相关的项目中导致 java.rmi.ServerException

Running Tomcat causes java.rmi.ServerException in the unrelated project

我有一个 java 非网络应用程序,它以编程方式启动 Jetty 服务器以提供 API 访问权限。它们之间的通信是通过 RMI 完成的。一切正常,直到我开始 Tomcat 与该项目没有任何关系。如果 Tomcat 是 运行,那么我在尝试启动应用程序时遇到以下异常:

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: ua.cn.stu.datalink.rmi.AcmRemoteService (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.run(Transport.java:200)
    at sun.rmi.transport.Transport.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run4(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda/351702438.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    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 ua.cn.stu.datalink.acmserver.rmi.AcmRemoteServiceImpl.main(AcmRemoteServiceImpl.java:107)
    at ua.cn.stu.datalink.acmserver.rmi.AcmRemoteServiceImpl.run(AcmRemoteServiceImpl.java:138)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: ua.cn.stu.datalink.rmi.AcmRemoteService (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.run(Transport.java:200)
    at sun.rmi.transport.Transport.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run4(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda/351702438.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: ua.cn.stu.datalink.rmi.AcmRemoteService (no security manager: RMI class loader disabled)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:556)
    at java.rmi.server.RMIClassLoader.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)
    ... 16 more

问题似乎出在这里 - ua.cn.stu.datalink.rmi.AcmRemoteService(没有安全管理器:RMI class 加载程序已禁用)

但是为什么启动 Tomcat 会禁用 RMI class 加载程序?

您必须有条件地启动注册表,如果 运行 无论如何都不会启动,并且 Tomcat 正在启动它自己的注册表。因此,当您绑定时,您将绑定到 Tomcat 的注册表,该注册表没有 class 可用,因此它失败了。