【问题标题】:Java Remote method invocationJava 远程方法调用
【发布时间】:2015-07-02 10:06:52
【问题描述】:

如果我使用来自不同位置的客户端调用此服务器方法,我会收到以下错误。如果我从服务器所在的同一位置运行客户端,我会得到输出。

请提供一些解决方案,以便从不同位置使用 rmi 客户端调用我的 rmi 服务器。

Error
Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
    java.lang.ClassNotFoundException: com.transform.xsl.XslFoTransformer_Stub (no security manager: RMI class loader disabled)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Naming.java:101)
    at com.transform.xsl.RmiClient.main(RmiClient.java:15)
Caused by: java.lang.ClassNotFoundException: com.transform.xsl.XslFoTransformer_Stub (no security manager: RMI class loader disabled)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:394)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:184)
    at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:637)
    at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
    at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:222)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1610)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
    ... 3 more

代码 ======

import java.io.File;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface XslFoTransformerInterface extends Remote {
    public byte[] doTransform(File stylesheet, File datafile) throws Throwable,RemoteException;

}

public class XslFoTransformer extends UnicastRemoteObject  implements XslFoTransformerInterface {

    protected XslFoTransformer() throws RemoteException {
        super();

    }

    public byte[] doTransform(File stylesheet, File datafile) throws Exception {

        String fileName = datafile.getName();
        int pos = fileName.lastIndexOf(".");
        if (pos > 0) {
            fileName = fileName.substring(0, pos);

        }
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        File file = new File(fileName + ".xsl-fo");
        try {
            // File stylesheet = new
            // File("C:\\Users\\Q811213\\Documents\\XSLT\\files\\ECGSearchResultsPDF_changed1.xsl");
            // File datafile = new
            // File("C:\\Users\\Q811213\\Documents\\XSLT\\files\\NEWDATA.xml");
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(datafile);
            TransformerFactory tFactory = TransformerFactory.newInstance();
            StreamSource stylesource = new StreamSource(stylesheet);
            Transformer transformer = tFactory.newTransformer(stylesource);
            DOMSource source = new DOMSource(document);
            ByteArrayOutputStream bos=new ByteArrayOutputStream();
            StreamResult result=new StreamResult(bos);
            transformer.transform(source, result);
             byte [] array=bos.toByteArray();


        return array;
        } catch (Exception e) {
            throw e;
        }}}


--Rmi server class


public class RmiServer {
    public static void main(String args[]) throws Exception{  
        try{  


        XslFoTransformerInterface stub=new XslFoTransformer();  
        Naming.rebind("rmi://localhost:1099/Xsl-Fo_Transform",stub);  
        }catch(Exception e){
            throw e;

        }  
        }  

}


--Rmi client created in different location



public class RmiClient {
    public static void main(String args[]) throws Throwable {
        try {
            XslFoTransformerInterface stub = (XslFoTransformerInterface) Naming
                    .lookup("rmi://localhost:1099/Xsl-Fo_Transform");
            System.out.println("stub is ready" + stub);
            File f1 = new File(
                    "C:\\Users\\s811213\\osbwstest\\XSL-FO_Transformer\\files\\ECGSearchResultsPDF_changed1.xsl");
            File f2 = new File(`enter code here`
                    "C:\\Users\\s811213\\osbwstest\\XSL-FO_Transformer\\files\\NEWDATA.xml");
            try {
                byte[] f = stub.doTransform(f1, f2);
                }cartch(){}

}}

如果我使用来自不同位置的客户端调用此服务器方法,我会收到以下错误。如果我从服务器所在的同一位置运行客户端,我会得到输出。 请提供一些解决方案,以便从不同位置使用 rmi 客户端调用我的 rmi 服务器。

【问题讨论】:

    标签: java rmi


    【解决方案1】:

    您需要将异常中命名的存根类部署到客户端。

    【讨论】:

      【解决方案2】:

      在 RMI 客户端中

      XslFoTransformerInterface 存根 = (XslFoTransformerInterface) 命名 .lookup("rmi://localhost:1099/Xsl-Fo_Transform");

      你需要将localhost更改为服务器ip

      【讨论】:

      • 线程“主”java.rmi.UnmarshalException 中的异常:解组返回错误;嵌套异常是:java.lang.ClassNotFoundException: com.transform.xsl.XslFoTransformer_Stub(无安全管理器:禁用 RMI 类加载器)
      • 不正确的 IP 地址不会导致 ClassNotFoundExceptuon。
      【解决方案3】:

      我不确定您是否在不同位置(不是服务器机器)运行您的程序,并使用您为 localhost 硬编码的 ip 代码的更新版本。

      如果这不是问题,您必须确保将 XslFoTransformerInterface 类放在客户端代码中与服务器代码放在同一包中

      将来如果你有一些可序列化的 POJO 类作为参数或远程方法的返回类型,同样的规则也适用于它们。始终将它们与服务器代码放在同一个包中。

      祝你好运。

      【讨论】:

      • 我已经在客户端位置添加了 XslFoTransformerInterface 但它仍然给出同样的错误
      • 例如,如果 XslFoTransformerInterface 的包是:服务器项目中的 com.java.rmi,那么在客户端项目中你应该有 com.hava.rmi 包并将你的 XslFoTransformerInterface 接口放在那里。你做到了吗?
      • 你用的是哪个java版本?
      • 没有办法改变存根的包。 Java版本也没有任何关系。
      • 亲爱的@EJP,我认为您错误地否决了我的答案,因为我在上面解释的两种情况都可能产生这种异常。首先,如果您在生产中不使用 RMI 并且在没有公共代码库的情况下使用它,您应该临时手动将 Remote 接口和 Serializable POJO 放入客户端项目代码中。如果将接口或 POJO 放在客户端项目中的不同包中,则可能会发生这种情况。所以这肯定会产生 ClassNotFoundException。
      猜你喜欢
      • 1970-01-01
      • 2023-04-11
      • 2012-03-31
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多