我正在尝试使用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路径。
答案 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
数组。
您确定您的客户端代码是最新的,还是您在客户端使用旧版本?