Fer*_*ano 7 java rmi classpath
我正在用RMI做我的第一步,我有一个简单的问题.
我有一个.jar文件,它有一个库中的几个方法的实现.我想使用RMI在.jar文件中调用此方法.
我正在尝试创建一种包装来做它.
所以,我正在做这样的事情:
接口类:此接口具有远程对象要实现的方法.
实现类:这个类,具有接口方法的实现,每个实现调用.jar文件中的相应方法.例如,jar文件有一个名为getDetails()的方法,它返回一个"ResponseDetail"对象.ResponseDetail是我在.jar中的响应类.
服务器类:它将方法绑定到rmiregistry
客户端类:它将使用实现中实现的方法.
到现在为止还挺好?:)
现在,我有一个lib文件夹,其中包含.jar文件.
在服务器机器中,我已经部署了Interface,Implementation和Server类.我已经生成了存根,并成功运行了rmiregistry,但是,有了这些细节:
要启动rmiregistry,我必须在命令行中设置classpath来引用.jar文件,否则我得到java.lang.NoClassDefFoundError.我用这个.sh文件做了:
THE_CLASSPATH=
for i in `ls ./lib/*.jar`
do
THE_CLASSPATH=${THE_CLASSPATH}:${i}
done
rmiregistry -J-classpath -J".:${THE_CLASSPATH}"
Run Code Online (Sandbox Code Playgroud)
要启动服务器,我还必须设置类路径以引用.jar文件,否则,我得到java.lang.NoClassDefFoundError.我用过这样的东西:
THE_CLASSPATH=
for i in `ls ./lib/*.jar` do
THE_CLASSPATH=${THE_CLASSPATH}:${i}
done
java -classpath ".:${THE_CLASSPATH}" Server
Run Code Online (Sandbox Code Playgroud)
客户端机器: 要从客户端机器运行Client.class文件,我必须将.jar文件复制到它,并在类路径中引用它们,否则,它不会运行,我得到java.lang. NoClassDefFoundError错误.我不得不在客户端机器上使用它:
THE_CLASSPATH=
for i in `ls ./lib/*.jar`
do
THE_CLASSPATH=${THE_CLASSPATH}:${i}
done
java -classpath ".:${THE_CLASSPATH}" HelloClient
Run Code Online (Sandbox Code Playgroud)
这个可以吗?我的意思是,我是否必须将.jar文件复制到客户端计算机以通过RMI执行方法?
在JDK v5之前,必须使用rmic(RMI编译器)生成RMI存根.这是从JDK v5自动完成的.此外,您还可以从Java代码中启动RMI注册表.要从简单的RMI应用程序开始,您可能需要按照以下步骤操作:
import java.rmi.*;
public interface SomeInterface extends Remote {
public String someMethod1() throws RemoteException;
public int someMethod2(float someParameter) throws RemoteException;
public SomeStruct someStructTest(SomeStruct someStruct) throws RemoteException;
}
Run Code Online (Sandbox Code Playgroud)
import java.rmi.*;
import java.rmi.server.*;
public class SomeImpl extends UnicastRemoteObject implements SomeInterface {
public SomeImpl() throws RemoteException {
super();
}
public String someMethod1() throws RemoteException {
return "Hello World!";
}
public int someMethod2( float f ) throws RemoteException {
return (int)f + 1;
}
public SomeStruct someStructTest(SomeStruct someStruct) throws RemoteException {
int i = someStruct.getInt();
float f = someStruct.getFloat();
someStruct.setInt(i + 1);
someStruct.setFloat(f + 1.0F);
return someStruct;
}
}
Run Code Online (Sandbox Code Playgroud)
import java.io.*;
public class SomeStruct implements Serializable {
private int i = 0;
private float f = 0.0F;
public SomeStruct(int i, float f) {
this.i = i;
this.f = f;
}
public int getInt() {
return i;
}
public float getFloat() {
return f;
}
public void setInt(int i) {
this.i = i;
}
public void setFloat(float f) {
this.f = f;
}
}
Run Code Online (Sandbox Code Playgroud)
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.net.*;
import java.io.*;
public class SomeServer {
public static void main(String args[]) {
String portNum = "1234", registryURL;
try{
SomeImpl exportedObj = new SomeImpl();
startRegistry( Integer.parseInt(portNum) );
// register the object under the name "some"
registryURL = "rmi://localhost:" + portNum + "/some";
Naming.rebind(registryURL, exportedObj);
System.out.println("Some Server ready.");
} catch (Exception re) {
System.out.println("Exception in SomeServer.main: " + re);
}
}
// This method starts a RMI registry on the local host, if it
// does not already exist at the specified port number.
private static void startRegistry(int rmiPortNum) throws RemoteException{
try {
Registry registry = LocateRegistry.getRegistry(rmiPortNum);
registry.list( );
// The above call will throw an exception
// if the registry does not already exist
} catch (RemoteException ex) {
// No valid registry at that port.
System.out.println("RMI registry is not located at port " + rmiPortNum);
Registry registry = LocateRegistry.createRegistry(rmiPortNum);
System.out.println("RMI registry created at port " + rmiPortNum);
}
}
}
Run Code Online (Sandbox Code Playgroud)
import java.io.*;
import java.rmi.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
public class SomeClient {
public static void main(String args[]) {
try {
String hostName;
String portNum = "1234";
String registryURL = "rmi://localhost:" + portNum + "/some";
SomeInterface h = (SomeInterface)Naming.lookup(registryURL);
// invoke the remote method(s)
String message = h.someMethod1();
System.out.println(message);
int i = h.someMethod2(12344);
System.out.println(i);
SomeStruct someStructOut = new SomeStruct(10, 100.0F);
SomeStruct someStructIn = new SomeStruct(0, 0.0F);
someStructIn = h.someStructTest(someStructOut);
System.out.println( someStructIn.getInt() );
System.out.println( someStructIn.getFloat() );
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
较大的客户端 - 服务器应用程序应分为三个模块:client,server和common(对于服务器和客户端代码之间共享的类,即本示例中的远程接口和非基本对象).客户端应用程序将被从创建client+ common类路径上的,并从服务器模块server+ common类路径上的模块.
我多年前用这个例子来学习RMI的基础知识,它仍然有效.然而,它远非完美(使用默认的Java包,不正确的异常处理,主机名和端口参数是硬编码的,不可配置等)
不过,对初学者来说这是好事.所有文件都可以放在一个目录中,并使用simple javac *.java命令进行编译.然后,可以java SomeServer通过启动java SomeClient命令来启动服务器应用程序和客户端应用程序.
我希望这有助于理解Java RMI,事实上,它远比这复杂得多.
| 归档时间: |
|
| 查看次数: |
4059 次 |
| 最近记录: |