《Thinking in Enterprise Java》中Remote Method Invocation (RMI)一节例程编译问题

claider 2019-01-28 02:49:32
鄙人在看《Thinking in Enterprise Java》,并对书中的例程进行编译,
读到Remote Method Invocation (RMI)一节
有两个例程的编译现碰到一点问题,请教各位高手:
第一个程序,定义了接口PerfectTimeI :
//: c15:rmi:PerfectTimeI.java
// The PerfectTime remote interface.
package c15.rmi;
import java.rmi.*;

public interface PerfectTimeI extends Remote {
long getPerfectTime() throws RemoteException;
} ///:~


第二个程序,实现上述接口:
//: c15:rmi:PerfectTime.java
// The implementation of
// the PerfectTime remote object.
// {Broken}
package c15.rmi;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.net.*;

public class PerfectTime
extends UnicastRemoteObject
implements PerfectTimeI {
// Implementation of the interface:
public long getPerfectTime()
throws RemoteException {
return System.currentTimeMillis();
}
// Must implement constructor
// to throw RemoteException:
public PerfectTime() throws RemoteException {
// super(); // Called automatically
}
// Registration for RMI serving. Throw
// exceptions out to the console.
public static void main(String[] args)
throws Exception {
System.setSecurityManager(
new RMISecurityManager());
PerfectTime pt = new PerfectTime();
Naming.bind(
"//peppy:2005/PerfectTime", pt);
System.out.println("Ready to do time");
}
} ///:~


/* public interface PerfectTimeI extends Remote {
long getPerfectTime() throws RemoteException;
} ///:~
*/


现将这两个程序都放在同一个目录,第一个程序编译没有问题;第二个程序进行编译时,出错如下:
PerfectTime.java:13: 错误: 找不到符号
implements PerfectTimeI {
^
符号: 类 PerfectTimeI
注: PerfectTime.java使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
1 个错误


上面这个“找不到符号”的错误,我作如下解决:
在本地电脑的,“C:\开发调试\Java”目录下,建立目录 \c15\rmi,加入到本地电脑CLASS_PATH环境变量,重启;
进入到目录“C:\开发调试\Java”然后运行
javac  .\c15\rmi\PerfectTime.java

返回信息:
注: .\c15\rmi\PerfectTime.java使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
按照提示,运行javac -Xlint:deprecation .\c15\rmi\PerfectTime.java,那么返回:
.\c15\rmi\PerfectTime.java:29: 警告: [deprecation] java.rmi中的RMISecurityManager已过时
new RMISecurityManager());
^
1 个警告


看起来除了一个警告之外是编译通过了,那么进入“C:\开发调试\Java\c15\rmi\”去运行
java PerfectTime

则返回:
错误: 找不到或无法加载主类 PerfectTime
原因: java.lang.NoClassDefFoundError: c15/rmi/PerfectTime (wrong name: PerfectTime)


请问这是什么原因?是否和RMISecurityManager已经过时有关?有无解决之道?谢谢!


...全文
310 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
claider 2019-09-01
  • 打赏
  • 举报
回复
楼主感谢各位!这阵子因为去忙别的工作,没有时间继续测试该问题了,先结帖。
qybao 2019-01-29
  • 打赏
  • 举报
回复
rmi需要注册服务,java.security.AccessControlException是因为java的安全规范引起的,不让虚拟机轻易使用或修改系统的资源(如端口等等),可以通过修改安全规范来达到正常运行,具体怎么修改你可以网上查一下,jre下有个什么policy文件的
你编译的时候就已经告诉你是过时的API了(PerfectTime.java使用或覆盖了已过时的 API),所以书里有些东西(技术实现或API)已经过时了,但是基本原理是差不多的
claider 2019-01-29
  • 打赏
  • 举报
回复
根据本书后续小节“Creating stubs and skeletons”,应作如下操作

C:\开发调试\Java>rmic c15.rmi.PerfectTime
警告: 为 JRMP 生成和使用骨架及静态存根
已过时。骨架不再必要, 而静态存根
已由动态生成的存根取代。建议用户
不再使用rmic来生成骨架和静态存根。
请参阅 java.rmi.server.UnicastRemoteObject 的文档。


看起来目前由于Java升级,原书的部分程序使用了老旧的技术,但应该是用rmic运行。
claider 2019-01-28
  • 打赏
  • 举报
回复
引用 5 楼 qybao 的回复:
你先编译PerfectTimeI啊
javac -d . PerfectTimeI.java
javac -Xlint:deprecation -d . PerfectTime.java
java c15.rmi.PerfectTime


编译了获得一个警告。按照如上运行之后,返回下面:
Exception in thread "main" java.security.AccessControlException: access denied ("java.net.SocketPermission" "peppy" "resolve")
at java.base/java.security.AccessControlContext.checkPermission(Unknown Source)
at java.base/java.security.AccessController.checkPermission(Unknown Source)
at java.base/java.lang.SecurityManager.checkPermission(Unknown Source)
at java.base/java.lang.SecurityManager.checkConnect(Unknown Source)
at java.base/java.net.InetAddress.getAllByName0(Unknown Source)
at java.base/java.net.InetAddress.getAllByName(Unknown Source)
at java.base/java.net.InetAddress.getAllByName(Unknown Source)
at java.base/java.net.InetAddress.getByName(Unknown Source)
at java.base/java.net.InetSocketAddress.<init>(Unknown Source)
at java.base/java.net.Socket.<init>(Unknown Source)
at java.rmi/sun.rmi.transport.tcp.TCPDirectSocketFactory.createSocket(Unknown Source)
at java.rmi/sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at java.rmi/sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at java.rmi/sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at java.rmi/sun.rmi.server.UnicastRef.newCall(Unknown Source)
at java.rmi/sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
at java.rmi/java.rmi.Naming.bind(Unknown Source)
at c15.rmi.PerfectTime.main(PerfectTime.java:31)

是不是说明起来了?剩余的Exception是其他问题?
qybao 2019-01-28
  • 打赏
  • 举报
回复
你先编译PerfectTimeI啊
javac -d . PerfectTimeI.java
javac -Xlint:deprecation -d . PerfectTime.java
java c15.rmi.PerfectTime
claider 2019-01-28
  • 打赏
  • 举报
回复
引用 3 楼 qybao 的回复:
把两个文件都保存到“C:\开发调试\Java"目录
cd “C:\开发调试\Java"
javac -d . PerfectTime.java //编译时会自动生成包的
java c15.rmi.PerfectTime //执行时直接用包路径形式


javac -d . PerfectTime.java 执行这个命令,返回:
C:\开发调试\Java>javac -d . PerfectTime.java
PerfectTime.java:13: 错误: 找不到符号
implements PerfectTimeI {
^
符号: 类 PerfectTimeI
注: PerfectTime.java使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
1 个错误
qybao 2019-01-28
  • 打赏
  • 举报
回复
把两个文件都保存到“C:\开发调试\Java"目录
cd “C:\开发调试\Java"
javac -d . PerfectTime.java //编译时会自动生成包的
java c15.rmi.PerfectTime //执行时直接用包路径形式
claider 2019-01-28
  • 打赏
  • 举报
回复
引用 1 楼 qybao 的回复:
have a try
cd “C:\开发调试\Java"
java c15.rmi.PerfectTime


若如下编译,则返回:
C:\开发调试\Java>javac c15.rmi.PerfectTime.java
javac: 找不到文件: c15.rmi.PerfectTime.java
用法: javac <选项> <源文件>
使用 --help 可列出可能的选项

换用以下命令,则返回:
C:\开发调试\Java>javac c15.rmi.PerfectTime
错误: 仅当显式请求注释处理时才接受类名称 'c15.rmi.PerfectTime'
1 个错误
qybao 2019-01-28
  • 打赏
  • 举报
回复
have a try
cd “C:\开发调试\Java"
java c15.rmi.PerfectTime

50,533

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧