小弟是新手,开始调试第一个经典的RMI小程序,遇到了许多问题,令小弟很郁闷!请教各位高手:
小弟的代码是这样的:
1。hello.java
package examples.hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
2.helloImpl.java
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl extends UnicastRemoteObject implements Hello {
public HelloImpl() throws Exception, RemoteException {
super();
}
public String sayHello() {
return "Hello World!";
}
public static void main(String arg[]) throws Exception {
if (System.getSecurityManager()==null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
HelloImpl obj = new HelloImpl();
Naming.rebind("//localhost/HelloServer",obj);
System.out.println("HelloServer bound in Registry");
}
catch(Exception e) {
System.out.println("HelloImpl err: "+e.getMessage());
e.printStackTrace();
}
}
}
3. HelloClient.java
package examples.hello;
import java.awt.*;
import java.awt.event.*;
import java.rmi.*;
import javax.swing.*;
public class HelloClient extends JFrame {
private JPanel jPanel1 = new JPanel();
private JLabel jLabel1 = new JLabel();
private BorderLayout borderLayout1 = new BorderLayout();
public String message=null;
public HelloClient(String ip) {
super("RMI HelloWorld Client....");
getRemoteTemp(ip);
setSize(300,300);
setResizable(false);
show();
}
private void getRemoteTemp(String ip) {
String serverObjectName="//"+ip+"/HelloServer";
Hello myTemp= (Hello) Naming.lookup(serverObjectName) ;
message=hlo.sayHello();
jLabel1.setText(message);
}
public HelloClient() {
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
jLabel1.setText("");
jPanel1.setLayout(borderLayout1);
this.getContentPane().add(jPanel1, BorderLayout.CENTER);
jPanel1.add(jLabel1, BorderLayout.CENTER);
}
public static void main(String[] args) {
HelloClient gt = null;
if(args.length ==0)
gt=new HelloClient("localhost");
else
gt=new HelloClient(args[0]);
gt.addWindowListener( new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0) ;
}
}
) ;
}
}
小弟在编译时遇到下列问题:
1。"Hello.java": error: examples.hello.Hello is an interface; stubs are needed only for remote object classes.
2。"HelloImpl_Skel.java": Error #: 302 : cannot access class examples.hello.HelloImpl; java.io.IOException: class not found: class examples.hello.HelloImpl at line 33, column 17
3。"HelloImpl_Skel.java": Error #: 302 : cannot access class examples.hello.HelloImpl; java.io.IOException: class not found: class examples.hello.HelloImpl at line 33, column 52
小弟疑惑的是Hello.java 里面实现的是一个接口 interface Hello,为何在jBuilder 里面老是在HelloClient里面说Class Hello not found!难道接口不算一个类吗?不能来创建一个对象吗?
请各位高手多多赐教!!!谢谢!!!
//File:Hello.java
package examples;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote
{
String sayHello() throws RemoteException;
}
//File:HelloClient.java
package examples;
import java.awt.*;
import java.awt.event.*;
import java.rmi.*;
import javax.swing.*;
public class HelloClient extends JFrame
{
private JPanel jPanel1 = new JPanel();
private JLabel jLabel1 = new JLabel();
private BorderLayout borderLayout1 = new BorderLayout();
public String message = null;
public HelloClient(String ip)
{
super("RMI HelloWorld Client....");
getRemoteTemp(ip);
setSize(300,300);
setResizable(false);
show();
}
private void getRemoteTemp(String ip)
{
String serverObjectName = "//" + ip + "/HelloServer";
try
{
Hello myTemp = (Hello)Naming.lookup(serverObjectName);
//message = hlo.sayHello();
message = myTemp.sayHello();
jLabel1.setText(message);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public HelloClient()
{
try
{
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
jLabel1.setText("");
jPanel1.setLayout(borderLayout1);
this.getContentPane().add(jPanel1,BorderLayout.CENTER);
jPanel1.add(jLabel1,BorderLayout.CENTER);
}
public static void main(String[] args)
{
HelloClient gt = null;
if(args.length == 0)
{
gt = new HelloClient("localhost");
}
else
{
gt = new HelloClient(args[0]);
}
gt.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
}
//File:HelloImpl.java
package examples;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl extends UnicastRemoteObject implements Hello
{
public HelloImpl() throws Exception,RemoteException
{
super();
}
public String sayHello()
{
return "Hello World!";
}
public static void main(String arg[]) throws Exception
{
if(System.getSecurityManager() == null)
{
System.setSecurityManager(new RMISecurityManager());
}
try
{
HelloImpl obj = new HelloImpl();
Naming.rebind("//localhost/HelloServer",obj);
System.out.println("HelloServer bound in Registry");
}
catch(Exception e)
{
System.out.println("HelloImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
找不到类是包的问题,确认你的package名称一致,另外运行rmi要先将你的server类用rmic编译一下:
rmic HelloImpl
然后启动rmiregistry:
start rmiregistry
在启动你的服务器:
java HelloImpl
最后是你的客户端:
java HelloClient
建议用命令行运行,因为步骤比较多
可能的问题:
2.helloImpl.java
package examples.hello;//少了package语句
import java.rmi.Naming;
建议使用文本编辑器,不借助Jbuilder
完整过程实例:
//RMI-简单使用.txt
1、接口代码PerfectTimeI.java
package c15.rmi;
import java.rmi.*;
interface PerfectTimeI extends Remote
{
long getPerfectTime() throws RemoteException;
}
2、服务代码PerfectTime.java
package c15.rmi;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.net.*;
public class PerfectTime extends UnicastRemoteObject implements PerfectTimeI
{
public long getPerfectTime() throws RemoteException
{
return System.currentTimeMillis();
}
public PerfectTime() throws RemoteException
{
}
public static void main(String[] args) throws Exception
{
System.setSecurityManager( new RMISecurityManager());
PerfectTime pt=new PerfectTime();
Naming.bind("//localhost:2005/PerfectTime",pt);
System.out.println("Ready to do Time");
}
}
3、客户代码DisplayPerfectTime.java
package c15.rmi;
import java.rmi.*;
import java.rmi.registry.*;
public class DisplayPerfectTime
{
public static void main(String[] args) throws Exception
{
System.setSecurityManager( new RMISecurityManager());
PerfectTimeI t=(PerfectTimeI)Naming.lookup("//localhost:2005/PerfectTime");
for(int i=0;i<10;i++)
System.out.println("Perfect time= "+t.getPerfectTime());
}
}
4、编译
F:\java\rmi>javac -d server PerfectTimeI.java PerfectTime.java
F:\java\rmi>javac -d client PerfectTimeI.java DisplayPerfectTime.java
生成目录及文件:
├─client
│ └─c15
│ └─rmi
│ DisplayPerfectTime.class
│ PerfectTimeI.class
└─server
└─c15
└─rmi
PerfectTime.class
PerfectTimeI.class
5、生成rmi根
F:\java\rmi>cd server
F:\java\rmi\server>rmic c15.rmi.PerfectTime
又生成两个文件:
F:\JAVA\RMI\SERVER
└─c15
└─rmi
PerfectTime.class
PerfectTimeI.class
PerfectTime_Stub.class
PerfectTime_Skel.class
6、拷贝文件 PerfectTime_Stub.class、PerfectTime_Skel.class到client\c15\rmi目录
7、编辑策略文件policy:
grant {
// Allow everything for now
permission java.security.AllPermission;
};
保存在源文件所在目录中即F:\java\rmi\。
8、启动rmi注册服务器
F:\java\rmi>start rmiregistry 2005
9、启动服务类(为了验证rmi功能,最好屏蔽classpath环境变量,即set classpath=)
F:\java\rmi\server>java -Djava.rmi.server.codebase=file:///f:/java/rmi/server/
-Djava.security.policy=file:///f:/java/rmi/policy c15.rmi.PerfectTime
Ready to do Time
说明:file:///f:/java/rmi/server/部分的server后面的/不能少
10、运行客户类(新开一个command窗口。为了验证rmi功能,最好屏蔽classpath环境变量,即set classpath=)
F:\java\rmi\client>java -Djava.security.policy=file:///f:/java/rmi/policy c15.rm
i.DisplayPerfectTime
Perfect time= 1049338846285
Perfect time= 1049338846295
Perfect time= 1049338846315
Perfect time= 1049338846325
Perfect time= 1049338846325
Perfect time= 1049338846335
Perfect time= 1049338846335
Perfect time= 1049338846335
Perfect time= 1049338846335
Perfect time= 1049338846345
说明:不能少:-Djava.security.policy=file:///f:/java/rmi/policy,否则无法访问