Java RMI远程调用踩坑
Java RMI的原理就不多说了,可以在其他地方看到,这里记录主要是在尝试一个小的rmi示例的时候遇到的坑
1
示例里使用了jndi.properties来配置java的命名空间,所以要把这个文件跟编译生成的class文件放在一起(项目中就是out文件夹下那些class文件一起的位置),并且在idea里设置项目的CLASSPATH为编译生成的文件位置
2
一开始使用的是Java13进行编译的,但是我的电脑上原来装的运行环境是Java8,这样就会报错说是版本有问题之类的,可以设置项目jdk为1.8
3
一定要在server启动之前,启动rmiregistery,在classpath下启动(也就是jndi配置文件所在的位置)
code
server
Warehouse.java
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Warehouse extends Remote {
double getPrice(String description) throws RemoteException;
}
WarehouseImpl.java
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
public class WarehouseImpl extends UnicastRemoteObject implements Warehouse {
private Map<String, Double> prices;
public WarehouseImpl() throws RemoteException
{
prices = new HashMap<String, Double>();
prices.put("Blackwell Toaster", 24.95);
prices.put("ZapXpress Microwave Oven", 49.95);
}
public double getPrice(String description) throws RemoteException
{
Double price = prices.get(description);
return price == null ? 0 : price;
}
}
WarehouseServer.java
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.rmi.RemoteException;
public class WarehouseServer {
public static void main(String[] args) throws
RemoteException, NamingException {
System.out.println("Constructing server implementation...");
WarehouseImpl centralWarehouse = new WarehouseImpl();
System.out.println("Binding server implementation to registry...");
Context namingContext = new InitialContext();
namingContext.bind("rmi:central_warehouse", centralWarehouse);
System.out.println("Waiting for invocations from clients...");
}
}
client
Warehouse.java
这个文件与server端Warehouse相同
WarehouseClient.java
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.rmi.RemoteException;
public class WarehouseClient {
public static void main(String[] args) throws NamingException, RemoteException {
Context namingContext = new InitialContext();
String url = "rmi://localhost/central_warehouse";
Warehouse centralWarehouse = (Warehouse) namingContext.lookup(url);
String descr = "Blackwell Toaster";
double price = centralWarehouse.getPrice(descr);
System.out.println(descr + ": " + price);
}
}
jndi.properities
java.naming.factory.initial=com.sun.jndi.rmi.registry.RegistryContextFactory
java.naming.provider.url=rmi://localhost:1099