JNI与RMI无法正常工作

时间:2015-04-14 10:16:06

标签: java java-native-interface rmi

我正在尝试使用JNI的本机c ++函数,并希望通过RMI使其可用。

将RMI客户端连接到RMI服务器并访问包含本机函数的方法时,出现以下错误消息:

java.rmi.ServerError: Error occurred in server thread; nested exception is: 
java.lang.UnsatisfiedLinkError: rmi.Server.setInputOutputPaths(Ljava/lang/String;Ljava/lang/String;)V
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.setInputAndOutputPaths(Unknown Source)
at rmi.RMIClient.setInputAndOutputPaths(RMIClient.java:47)
at rmi.RMIClient.main(RMIClient.java:27)
Caused by: java.lang.UnsatisfiedLinkError: rmi.Server.setInputOutputPaths(Ljava/lang/String;Ljava/lang/String;)V
at rmi.Server.setInputOutputPaths(Native Method)
at rmi.Server.setInputAndOutputPaths(Server.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.rmi.ServerError: Error occurred in server thread; nested exception is: 
java.lang.UnsatisfiedLinkError: rmi.Server.createNN([ID)V
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.createNeuralNetwork(Unknown Source)
at rmi.RMIClient.createNeuralNetwork(RMIClient.java:55)
at rmi.RMIClient.main(RMIClient.java:28)
Caused by: java.lang.UnsatisfiedLinkError: rmi.Server.createNN([ID)V
at rmi.Server.createNN(Native Method)
at rmi.Server.createNeuralNetwork(Server.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

服务器接口:

package rmi;

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

public interface ServerInterface extends Remote
{
    public void setInputAndOutputPaths(String inputPath, String outputPath) throws RemoteException;
    public void createNeuralNetwork(int[] topology, double learnRate) throws RemoteException;
    public void trainNeuralNetwork(String inputDataFileName, int numIterations) throws RemoteException;
    public void tradeUsingNeuralNetwork(String inputDataFileName) throws RemoteException;
}

服务器代码:

package rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import rmi.ServerInterface;

public class Server extends UnicastRemoteObject implements ServerInterface
{
    Server() throws RemoteException
    {
        super();
    }

    static {
        System.loadLibrary("BAITLibrary");
    }

    public native void setInputOutputPaths(char[] inputPath, char[] outputPath);
    public native void createNN(int[] topology, double learnRate);
    public native void trainNN(String inputDataFileName, int numIterations);
    public native void trade(String inputDataFileName);

    public static void main(String[] args)
    {

        try {
            Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);

            ServerInterface engine = new Server();
            //ServerInterface stub = (ServerInterface) UnicastRemoteObject.exportObject(engine, Registry.REGISTRY_PORT);

            registry.rebind("Server", engine);
        }

        catch (RemoteException ex) {
            System.out.println(ex.getMessage());
        }
    }

    public void setInputAndOutputPaths(String inputPath, String outputPath) {
        try {
            new Server().setInputOutputPaths(inputPath, outputPath);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void createNeuralNetwork(int[] topology, double learnRate) {
        try {
            new Server().createNN(topology, learnRate);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void trainNeuralNetwork(String inputDataFileName, int numIterations) {
        try {
            new Server().trainNN(inputDataFileName, numIterations);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void tradeUsingNeuralNetwork(String inputDataFileName) {
        try {
            new Server().trade(inputDataFileName);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

客户代码:

package rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;


import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;


public class RMIClient {
    private ServerInterface server;

    public RMIClient() {
    }
    public static void main(String[] args){
        RMIClient huan = new RMIClient();
        huan.connect();

        String inputPath = "C:\\Users\\Fabian\\Desktop\\Huan\\Input\\NN_1";
        String outputPath = "C:\\Users\\Fabian\\Desktop\\Huan\\Output\\NN_1";
        int[] topology = { 25, 35, 50, 15, 1 };
        double learnRate = 0.009;

        huan.setInputAndOutputPaths(inputPath, outputPath);
        huan.createNeuralNetwork(topology, learnRate);
    }

    public void connect() {

        try {
            Registry registry = LocateRegistry.getRegistry(Registry.REGISTRY_PORT);
            server = (ServerInterface) registry.lookup("Server");

            //server = (ServerInterface)Naming.lookup("Server");
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (NotBoundException e) {
            e.printStackTrace();
        }
    }

    public void setInputAndOutputPaths(String inputPath, String outputPath) {
        try {
            server.setInputAndOutputPaths(inputPath, outputPath);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void createNeuralNetwork(int[] topology, double learnRate) {
        try {
            server.createNeuralNetwork(topology, learnRate);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void trainNeuralNetwork(String inputDataFileName, int numIterations) {
        try {
            server.trainNeuralNetwork(inputDataFileName, numIterations);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void tradeUsingNeuralNetwork(String inputDataFileName) {
        try {
            server.tradeUsingNeuralNetwork(inputDataFileName);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

服务器启动时使用:“ - Djava.library.path = C:/ Users / Fabian / Desktop / BAITLibrary / x64 / Debug”将.dll文件添加到java路径。

1 个答案:

答案 0 :(得分:1)

错误说您正在尝试调用一个需要两个String数组的方法:

java.lang.UnsatisfiedLinkError:
    rmi.Server.setInputOutputPaths(Ljava/lang/String;Ljava/lang/String;)V

但是,在接口(和实现)中,该方法需要两个char数组:

public void setInputAndOutputPaths(char[] inputPath, char[] outputPath)
                throws RemoteException;

更改接口和实现以获取两个char数组,或者确保在调用端传递char数组而不是String数组。

您确定您的客户端代码是最新的,还是您在客户端使用旧版本?