沒有執行安全管理器的 Tomcat 訪問控制異常(綁定到 RMI)(Ubuntu)
我遇到了來自 Tomcat servlet 的一些奇怪的訪問控制異常(當它嘗試綁定到 RMI 伺服器時)。我在沒有安全管理器的情況下執行,整個應用程序以前在基本相同的設置上執行良好。
這是對我所在的 webapp 的類文件夾的 java.io.FilePermission 訪問被拒絕。當我將我的 RMI 存根重新綁定到 RMI 系統資料庫時發生錯誤(這是在我訪問了相同的其他一些類之後webapp,在我導出存根並找到系統資料庫之後;做了一些日誌消息來證明這一點)。任何幫助都會很棒,因為我現在已經死在這個水里了……
更新:好的,取得了一些進展(此更新覆蓋了以前的假設)。這與 RMI 系統資料庫的程式碼庫訪問有關,並且可能與 OpenJDK 的一些怪癖有關。
當我將伺服器綁定到系統資料庫時,它會嘗試通過它認為是程式碼庫的方式訪問相關類。看來,使用系統資料庫用於獲取程式碼庫位置的任何隱蔽 RMI 魔法,它以某種方式無法獲取 JVM 屬性中的那個,而是試圖查看 webapp 的類路徑(??)。
推理(!):這曾經適用於程式碼庫的文件 URL(並且沒有 Java 安全策略)。我在 Tomcat 之外測試了 RMI 伺服器設置(就像 POJO 一樣),它使用HTTP URL而不是文件 URL。後者給出了與 Tomcat 中相同的訪問權限錯誤,但顯示它試圖訪問這個特定的文件位置(與 Tomcat 中它試圖訪問完全不同的位置不同)。我懷疑文件 URL 的失敗可能是由於 OpenJDK 和 Sun JDK 之間的差異。(我以前用過 Sun 的;我只記得。)
但是,當我嘗試使用 Tomcat 設置的工作 HTTP URL(確保服務它的 Web 伺服器位於與 Tomcat 不同的埠上)時,它仍然像嘗試訪問 webapp 的類路徑區域一樣失敗。我已經在 servlet 程式碼中確認 java.rmi.server.codebase 屬性設置正確(所以它可以通過 servlet 程式碼)。也許是 OpenJDK rmiregistry 中的一個錯誤(似乎不太可能)?
這是否有助於任何人有更多的想法?這是否更好地放置在 StackOverflow 上(有人可能會爭辯說它在我認為的任何一個位置)?
使用 Tomcat 6.0.24 本地環境,由 Ubuntu 10.04 x64 和 OpenJDK 1.6.0_20 上的 tomcat6-instance-create cmd 創建。(所有 Ubuntu 10.04 的預設設置。)
異常跟踪如下:
simHAWSER.core.exceptions.HAWSER_RMI_ConfigurationException: Error setting up observer gateway server HAWSER_ObserverGateway at simHAWSER.core.internal.yawlInterface.HAWSER_ObserverGateway.announceEngineInitialised(HAWSER_ObserverGateway.java:1404) at org.yawlfoundation.yawl.engine.ObserverGatewayController$8.run(ObserverGatewayController.java:278) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:636) Caused by: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: access to class loader denied at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267) at sun.rmi.transport.Transport$1.run(Transport.java:177) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:173) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:636) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377) at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) at simHAWSER.core.internal.yawlInterface.HAWSER_ObserverGateway.announceEngineInitialised(HAWSER_ObserverGateway.java:1400) ... 4 more Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: access to class loader denied at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267) at sun.rmi.transport.Transport$1.run(Transport.java:177) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:173) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667) ... 3 more Caused by: java.lang.ClassNotFoundException: access to class loader denied at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:603) at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646) at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311) at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255) at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1548) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1510) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368) ... 12 more Caused by: java.security.AccessControlException: access denied (java.io.FilePermission /home/rigsby/Build/yawl/r1803/tomcat6/webapps/yawl/WEB-INF/classes/- read) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:393) at java.security.AccessController.checkPermission(AccessController.java:553) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at sun.rmi.server.LoaderHandler$Loader.checkPermissions(LoaderHandler.java:1173) at sun.rmi.server.LoaderHandler$Loader.access$000(LoaderHandler.java:1127) at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:569) ... 20 more
原始 simHAWSER 類是我的應用程序(作為 yawl webapp 的一部分執行)。如果有任何影響,我的程式碼在 webapp lib 目錄中作為單獨的 JAR 執行,並由 yawl servlet(部署到正常的類目錄)呼叫。
在半絕望中,我嘗試使用安全管理器啟動 Tomcat(授予此 web 應用程序的所有權限),但這在讀取我的 catalina.policy 文件時導致了一些奇怪的“空 KeyStore 名稱”異常(我只是從這裡複製了預設的.) 無論如何,我知道它在沒有安全性的情況下工作(並且應該工作),所以不想在這個方向上大打出手:-)
如果有人想要更多細節,請告訴我。
PS 想要添加一個 RMI 標籤(或 rmiregistry 以匹配StackOverflow),但沒有它的代表 :-( 如果有人想添加它,那就太好了。
好的,解決了。問題在於使用 OpenJDK 而不是 Sun Java。OpenJDK
rmiregistry
實現不喜歡文件 URL(訪問異常),並且當嘗試訪問 Tomcat webapp 的程式碼庫屬性時,它以某種方式無法正確看到它(假設與 Tomcat 中使用的 per-webapp 類載入器有關搞砸了)。切換到 Sun
rmiregistry
實現(即使保留對 Tomcat 的 OpenJDK 的使用)意味著它可以正常工作。如果我在這方面找不到任何 OpenJDK 錯誤,我會提出一個並在此處連結到它以確保完整性。我懷疑 OpenJDK 的文件 URL 問題是由於不同的預設(無顯式 java 策略)安全設置,我可以使用顯式策略文件來使其工作……
希望這對其他人有所幫助,因為它確實令人頭疼。