Java RMI AccessControlException:アクセスが拒否されました
-
19-09-2019 - |
質問
やあ、もらってるよ AccessControlException: access denied
作成中の RMI アプリを起動しようとすると、デフォルトのポート 1099 または別の動的ポートで開いた場合にこの例外が発生する理由がわかりません。ポリシー ファイルは現在すべてを許可しています (変更されると変更されます)。アプリは終了しました)。
どこが間違っているのか困っています。何か助けがあれば大変役に立ちます
私のコード
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {
if (System.getSecurityManager() == null)
{
System.setSecurityManager ( new RMISecurityManager() );
}
CreditCardServer ccs = new CreditCardServer();
int port = 1099;
try {
port = Integer.valueOf(args[0]);
}
catch (Exception e)
{
System.out.println("Invlaid Port");
}
if (((port <= 65535) && (port >= 49152)) || port ==1099)
{
System.out.println("Valid Port");
}
else
{
port = 1099;
System.out.println("Port not in Dynamic Range 49152<-->65535");
}
System.out.println(port);
LocateRegistry.createRegistry(port);
LocateRegistry.getRegistry().bind("CreditCardServer", ccs);
while (true)
{
//hum?
}
}
}
スタックトレース
vega3 [ia32.linux] 23% java -Djava.security.policy=wideopen.policy -jar "BookStore-CreditCardServer.jar 65000"
有効なポート
65000
Exception in thread "main" java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
at java.security.AccessController.checkPermission(AccessController.java:553)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)
at java.net.Socket.connect(Socket.java:536)
at java.net.Socket.connect(Socket.java:492)
at java.net.Socket.<init>(Socket.java:389)
at java.net.Socket.<init>(Socket.java:203)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)
at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
at bookstorecreditcardserver.Main.main(Main.java:56)
私のポリシーファイル
grant {
// Allow everything for now
permission java.security.AllPermission;
};
解決 2
基本的に、私は愚かです。Java は文句を言わないので、.policy ファイル AOK を見つけていると思っていましたが、作業ディレクトリに .policy ファイルの新しいコピーを移動していなかったことが判明し、すべてが解決しました:-D
他のヒント
私は一日中これで立ち往生しており(コマンドラインからrmiregistryを開始する必要があることがわかった後)、これをEclipseを使用してローカルで機能させることを試み、最終的に解決しました。他の人をこの残酷な運命から救うためのいくつかのヒント:
1 - コマンドライン フラグを使用して、ポリシー ファイルを正しく割り当てます。
java -Djava.security.policy=/home/.../<filename>.policy ...
または、これをコードに直接記述します。
System.setProperty("java.security.policy","file:///home/.../<filename>.policy");
プロジェクトのルートと同じフォルダーに配置して、URI を次のように減らすこともできます。
file:./<filename>.policy
(絶対 URI の代わりに相対 URI を使用してください。実際、私は今日までこれを理解していませんでした)。
2 - ポリシー ファイルの形式が正しいことを確認します。例:
grant codeBase "file:<path>/bin/-" {
permission java.security.AllPermission;
};
これは、バイナリが配置されているフォルダーを参照する必要があります。ポリシーファイルのフォーマットについて詳しく解説します。 ここ.
それはそれです、私もお勧めします このチュートリアル, 正しい軌道に乗るのに非常に役立ちました。
このトピックに関する回答のほとんどは曖昧で役に立たないことがわかり、これをデバッグするのに数時間を費やしました。おそらく、エラーの原因は、ポリシー ファイルの形式が間違っているか、コマンド ライン引数として正しく設定されていないことです。
を取得している場合は、 java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
- テストのために、すべての権限を持つセキュリティ ポリシー ファイルを作成します。
grant codeBase "file:/-" {
permission java.security.AllPermission;
};
このセキュリティ ファイルは、クライアントとサーバーの両方で実行するためだけに使用します。
タイプミスがないか確認してください。なぜ機能しないのかを理解するのに何時間も費やしましたが、代わりに -Djava.rmi.security.policy と入力しました。 -Djava.security.policy=...
Oracle の RMI チュートリアルを稼働させたいだけの人にとっては、このセキュリティ ポリシーはその例としては十分です。