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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~