- - PR -
RMI + Windowsサービス
1
投稿者 | 投稿内容 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-02-07 14:50
お世話になっております。
内容的にwindowsの会議室かもしれませんが、RMIの扱いの可能性があるので、こちらに質問をさせて頂きたいと思います。 RMIサーバを稼働させるに当たり、Windowsサービス化したいと思いました。 sc.exeコマンドを使い、サービスに登録する方法は理解できているつもりです。(サービス自体にはあまり知識はないです。) 下記方法に、問題等があればご教授頂きたく存じます。 ちなみにOSはwindowsXPです。 例えば、D:\にあるServer.jarファイルをRMIサーバのサービスとして起動させたいと考えております。 手順として、 1.batファイル(server.bat)の作成 CLASSPATHを通す。(set CLASSPATH=D:\Server.jar) start rmiregistry を行い、RMIレジストリを起動 java -jar D:\Server.jar を行いサーバを起動。 ※ちなみにこのbatファイルは正常に作動する事を確認済みです。 2.scコマンドによるサービス化 sc create RMIserver binpath= D:\server.bat 以上でサービスの一覧にRMIserverが登録された事は確認しております。 しかし、サービスを開始しても、[SC] StartService FAILED 1053 とエラーが表示され、作動しません。 RMIサーバの場合、何かしないといけない事があるのか、それともサービスに関してすべきことがあるのかが見えていない状態です。 よろしくお願い致します。 | ||||||||||||||||||||||||||||
|
投稿日時: 2008-02-07 17:47
こんばんは。
エラーの内容は次のようになっています。 Error 1053: The service did not respond to the start or control request in a timely fashion エラー1053:そのサービスは指定時間内に開始要求または制御要求に応答しませんでした。 これは、サービス制御マネージャ(SCM)から、サービスプログラムへ開始要求をしたにもかかわらず、 サービスプログラム側がそれに対して応答を返していない、ということです。 サービスプログラム側では、SCMからの制御要求に対し、その報告を返す必要があります。 Handler(msdn)
Windowsサービスアプリケーションとして動作させるためには、要件をみたす必要がありますので サービスとして登録しただけでは動作しません。 | ||||||||||||||||||||||||||||
|
投稿日時: 2008-02-07 18:41
Windows で RMI サービスを作ろうとはおもしろい。簡単なサンプルがあるので、どうぞ。
(1) rmiregistry.exe を使用しなくてもプログラムコードからRMI レジストリを起動できる。 (2) exewrap というツールを使うことで、Windows サービスを作成することができる。 ■ Hello.java
■ HelloImpl.java
■ HelloClient.java
■ HelloServer.manifest
■ HelloClient.manifest
■ HelloServer.policy
■ HelloClient.policy
■ コンパイル & サービスインストール & 実行 (コンパイル) javac Hello.java HelloImpl.java HelloClient.java (サーバーJAR作成 & EXE作成) jar cvfm HelloServer.jar HelloServer.manifest HelloImpl.class exewrap -s HelloServer.jar (サービスインストール & サービス開始) HelloServer.exe -install net start HelloServer (クライアントJAR作成 & EXE作成) jar cvfm HelloClient.jar HelloClient.manifest HelloClient.class exewrap HelloClient.jar (クライアント実行) HelloClient.exe (サービスの停止 & 削除) net stop HelloServer HelloServer.exe -remove | ||||||||||||||||||||||||||||
|
投稿日時: 2008-02-07 18:45
補足。
(1) 以下のファイルは同じところに配置する。 Hello.java HelloImpl.java HelloClient.java HelloServer.manifest HelloClient.manifest HelloServer.policy HelloClient.policy (2) exewrap はここからダウンロードする。 http://www.ne.jp/asahi/web/ryo/exewrap/ | ||||||||||||||||||||||||||||
|
投稿日時: 2008-02-07 23:31
Tdnr_Symさん、未記入さん、早速のご回答、ありがとうございます。
scコマンドを見つけたときは、これで解決するとは思ったのですが、、、やはりそう簡単にはいきませんね。 未記入さんに教えて頂いた、javaからrmiregistryを立ち上げるというのは、実は一時探したのですが、検索の仕方がまずかったらしく、当時見つかりませんでした。 ですから、お教え頂いて感動です。 とりあえずサービス化の前に現状のRMIを書き換えて、一旦プログラムから立ち上げるのを試そうと思いましたが、、、上手くいきません。 セキュリティポリシーの部分が良く分からない状態です。 内容を記載致しますので、お手数をお掛け致しますが、ご指摘頂きたく存じます。 ・policyファイル(all.policy) grant{ permission java.security.AllPermission; }; ・RMIサーバ側の問題部分 System.setProperty("java.security.policy", "D:\\all.policy"); LocateRegistry.createRegistry(38925); Naming.rebind("rmi://192.168.21.45:38925/Server",new Server()); まず、System.setProperty("java.security.policy", "D:\\all.policy");の部分で引っ掛かり、エラーが出てしまいます。下記、その際のスタックです。 java.security.AccessControlException: access denied(java.util.PropertyPermissio n java.security.policy write) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.System.setProperty(System.java:727) at src.Win_server.start(Win_server.java:40) at src.Win_server.main(Win_server.java:29) System.setProperty("java.security.policy", "D:\\all.policy");を削除して実行すると、サーバは稼動しますが、クライアントからの接続が上手くいかない状態になります。 下記、クライアントから接続した際に、サーバのコンソールに出てくるスタックです。 Exception in thread "RMI TCP Connection(idle)" java.security.AccessControlException: access denied (java.net.SocketPermission 192.168.21.45:49961accept,resolve) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkAccept(SecurityManager.java:1157) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.checkAcceptPermission(TCPTransport.java:636) at sun.rmi.transport.tcp.TCPTransport.checkAcceptPermission(TCPTransport.java:275) at sun.rmi.transport.Transport$1.run(Transport.java:158) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:155) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619) 最終的にはpolicyファイルを使う方がセキュリティ面でも良いのであれば、そのほうが好ましいと思っております。 ネットで調べてもセキュリティマネージャの仕組みがいまいち分かっていないのもあり、良く分からない状態です。 宜しくお願い致します。 | ||||||||||||||||||||||||||||
|
投稿日時: 2008-02-08 09:21
セキュリティマネージャをインストールする前にポリシーを指定しておかないといけないので、System.setProperty("java.security.policy", ...) をしてから、System.setSecurityManager(new RMISecurityManager()) を実行すること。 というかセキュリティポリシーは実行時に指定したほうが良いのでは? java -Djava.security.policy=all.policy ... といった感じで。 | ||||||||||||||||||||||||||||
|
投稿日時: 2008-02-09 16:47
未記入さん、早速のご返答ありがとうございました。
batとサービスにすると、細々と違う部分があり、少し苦戦しましたが、やっと思い通りのサービスを稼動させることができました。(知識が乏しかったので、手当たり次第やっていました。) セキュリティポリシーに関しては、何でもjavaでやりたがる傾向があるので、内包してしまいました。 今回のサービスには、どの道、同じフォルダにpolicyファイルを置くだけで良かったので、プログラムから除外しました。 理想通りの状態になって、感謝しております。 ありがとうございました。 |
1