2008-10-07 12 views
15

कल मैंने जावा आरएमआई के साथ शुरू करने की कोशिश की। मुझे यह सूर्य ट्यूटोरियल (http://java.sun.com/docs/books/tutorial/rmi/index.html) मिला और सर्वर अपूर्णता के साथ शुरू किया। लेकिन हर बार जब मैं प्रोग्राम शुरू करता हूं (rmiregistry चल रहा है) मैं निम्नलिखित StackTrace के साथ एक AccessControlException मिलती है:जावा आरएमआई ट्यूटोरियल - एक्सेसकंट्रोल अपवाद: एक्सेस अस्वीकार (java.io.FilePermission

LoginImpl exception: 
java.security.AccessControlException: access denied (java.io.FilePermission \\\C\ProjX\server\serverProj\bin\usermanager read) 
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264) 
    at java.security.AccessController.checkPermission(AccessController.java:427) 
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) 
    at java.lang.SecurityManager.checkRead(SecurityManager.java:871) 
    at java.io.File.exists(File.java:700) 
    at sun.net.www.protocol.file.Handler.openConnection(Handler.java:80) 
    at sun.net.www.protocol.file.Handler.openConnection(Handler.java:55) 
    at java.net.URL.openConnection(URL.java:943) 
    at sun.rmi.server.LoaderHandler.addPermissionsForURLs(LoaderHandler.java:1020) 
    at sun.rmi.server.LoaderHandler.access$300(LoaderHandler.java:52) 
    at sun.rmi.server.LoaderHandler$Loader.<init>(LoaderHandler.java:1108) 
    at sun.rmi.server.LoaderHandler$Loader.<init>(LoaderHandler.java:1089) 
    at sun.rmi.server.LoaderHandler$1.run(LoaderHandler.java:861) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.server.LoaderHandler.lookupLoader(LoaderHandler.java:858) 
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:541) 
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628) 
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294) 
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238) 
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1494) 
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1457) 
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693) 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339) 
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) 
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:375) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240) 
    at sun.rmi.transport.Transport$1.run(Transport.java:153) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:149) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701) 
    at java.lang.Thread.run(Thread.java:595) 
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) 
    at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) 
    at sun.rmi.server.UnicastRef.invoke(Unknown Source) 
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) 
    at startserver.StartServer.main(StartServer.java:22) 

मेरे server.policy फ़ाइल इस तरह दिखता है:

grant { 
    permission java.security.AllPermission; 
}; 

लेकिन मैं भी इस एक कोशिश की ...

grant { 
    permission java.security.AllPermission; 
    permission java.io.FilePermission "file://C:/ProjX/server/serverProj/bin/usermanager", "read"; 
}; 

... और यह एक (और कई अन्य :-():

grant codeBase "file:///-" { 
    permission java.security.AllPermission; 
}; 

लेकिन हर मामले में परिणाम एक ही है। और हां, पॉलिसी फाइल पथ में है (जब मैं पॉलिसी फाइल में गलत स्टेटस लिखता हूं तो मुझे एक पार्स अपवाद दिखाई देता है)। मैंने कई अन्य "/" और "\" नक्षत्रों की कोशिश की लेकिन इसका कोई प्रभाव नहीं पड़ा।

मैं ग्रहण और मेरी वी एम-पैरामीटर का उपयोग इस तरह हैं:

-cp C:\ProjX\server\serverProj\bin\usermanager\ 
-Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/ 
-Djava.rmi.server.hostname=XYZ (anonymized) 
-Djava.security.policy=server.policy 

संकलित रिमोट-इंटरफेस और इंटरफेस-कार्यान्वयन वर्ग (LoginImpl) वर्ग इस पथ में हैं: "C:/ProjX/सर्वर/serverProj/bin/usermanager/"। मुख्य विधि, मैं कहाँ instanciate और रजिस्ट्री में ठूंठ rebind एक और पैकेज में है और इस तरह दिखता है:

public static void main(String[] args) { 
    if (System.getSecurityManager() == null) { 
     System.setSecurityManager(new SecurityManager()); 
    } 
    try { 
     String name = "Login"; 
     Login login = new LoginImpl(); 
     Login stub = (Login) UnicastRemoteObject.exportObject(login, 0); 
     Registry registry = LocateRegistry.getRegistry(); 
     registry.rebind(name, stub); 
     System.out.println("LoginImpl bound"); 
    } catch (Exception e) { 
     System.err.println("LoginImpl exception:"); 
     e.printStackTrace(); 
    } 
} 

किसी को भी मेरे लिए एक सलाह है? मदद के लिए शुक्रिया।


तो सवाल ही है (java.rmi.UnmarshalException पता चलता है कि codebase बदलते मेरी AccessControlException का समाधान नहीं है)। और नहीं: मैं एक प्लगइन "जी बी" खरीदना नहीं चाहता ;-)।

+0

मुझे एक समान समस्या थी। मैंने इसे इस दृष्टिकोण के माध्यम से हल किया - https://stackoverflow.com/a/44275905/1509058 –

उत्तर

7

सभी कोड के लिए सभी अनुमतियों को प्रदान करना एक बहुत बुरा है। कोई भी आरएमआई क्लाइंट ऐसा कर सकता है जो उपयोगकर्ता में लॉग इन के रूप में चाहता था। आम तौर पर उचित अनुमतियों को प्रतिबंधित करने का प्रयास करें, खासकर जब आप नहीं जानते कि कोड कहां से आया है।

प्रश्न पर वापस ...

-Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/ 

कि या तो "file:///C:/..." या "file:/C:/..." होना चाहिए। Http के बारे में सोचो। "http://C:/..."C नामक एक होस्ट को संदर्भित करता है। ध्यान दें कि अपवाद संदेश ने कोलन गिरा दिया है, क्योंकि यह पोर्ट नंबर के लिए सिंटैक्स है।

यदि आप सभी कोडों के लिए अनुमति देते हैं तो भी आपको सुरक्षा अपवाद क्यों मिलता है, यह है कि आरएमआई उस यूआरएल को शामिल किए गए उचित अनुमतियों को प्रतिबंधित कर रहा है (AccessController doPrivileged दो तर्क फ़ॉर्म का उपयोग करके)।

+0

अरे! मैंने यह बहुत उपयोगी पाया। क्या आप कृपया मुझे बता सकते हैं कि server.policy टेक्स्ट फ़ाइल कहां स्टोर करें? – user1799214

+0

@ user1799214 मूल पोस्टर ने एचटीई सर्वर की वर्तमान कार्यशील निर्देशिका का उपयोग किया, जो '-Djava.security.policy = server.policy' के साथ निर्दिष्ट है। (हमेशा के रूप में, नेटवर्क-सुलभ कोड पर प्रतिबंधों को हटाने के लिए सुरक्षित रूप से करना मुश्किल है।) –

0

मैं अपवाद वास्तव में rmiregistry से बाहर आ रहा है लगता है। स्टैक ट्रेस का यह हिस्सा मुझे ऐसा लगता है। Rmiregistry के लिए स्टब अपवाद प्राप्त कर रहा है और इसे पुनर्जीवित करने के प्रयास के परिणामस्वरूप इसे वापस पास कर रहा है।

 
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) 
    at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) 
    at sun.rmi.server.UnicastRef.invoke(Unknown Source) 
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) 

-J-Djava.security.policy=all.policy, जहां नीति फ़ाइल सभी अनुमतियों को अनुदान के साथ rmiregistry चलाने की कोशिश करें (कम से कम चीजों के लिए जा रहा प्राप्त करने के लिए)।

आखिरकार आप एक HTTP कोडबेस यूआरएल पर भी स्विच करना चाहते हैं, ताकि आप अपने सर्वर से अलग मशीन पर क्लाइंट चला सकें।

7

ठीक है, मेरे पास है। यह ´ टी rmiregistry प्रॉपर्टी (किसी भी पैरामीटर के बिना काम करता है) था।

-cp C:\ProjX\server\serverProj\bin\usermanager\ 
-Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/ 
-Djava.rmi.server.hostname=XYZ (anonymized) 
-Djava.security.policy=server.policy 

... बजाय इस तरह दिखना चाहिए:

-Djava.rmi.server.codebase=file:/C:/ProjX/server/serverProj/bin/ 
-Djava.rmi.server.hostname=XYZ (anonymized) 
-Djava.security.policy=server.policy 

=> फ़ाइल:/(केवल एक स्लैश) + गलत पैकेज समाप्त मेरे codebase वी एम-पैरामीटर में दो त्रुटियां थीं।

लेकिन ट्रेस इतना भ्रमित था, मेरा पहला विचार था कि नीति-फ़ाइल या नीति-कॉन्फ़िगरेशन के साथ कुछ गलत होना चाहिए।

फिर भी: मदद और खुश हैकिंग के लिए धन्यवाद।

Hello h = null; 
Properties props = System.getProperties(); 
System.setProperty("java.rmi.server.codebase", "file:/C:/PROJECTX/bin/"); 
try { 
    h = new HelloImpl(); 
    Naming.bind("//localhost:1099/HelloService", h); 
    System.out.println("Serwis gotów..."); 
} catch (RemoteException e) { 
    e.printStackTrace(); 
} catch (MalformedURLException e) { 
    e.printStackTrace(); 
} catch (AlreadyBoundException e) { 
    e.printStackTrace(); 
} 

कुछ काल्पनिक Hello RMI सेवा के लिए: ;-)

2

तुम भी प्रोग्राम के java.rmi.server.codebase गुण सेट कर सकते हैं।

+0

मुझे लगता है कि यह संपत्ति सेट करने में असमर्थ है। मेरा जावा सेट ऑपरेशन निष्पादित करने के लिए मुझे अस्वीकार करता प्रतीत होता है। –

0

मैं एक बहुत ही कम सवाल है ...

क्यों वह इस पथ का उपयोग करता है: "file: // सी:/ProjX/सर्वर/serverProj/bin/usermanager" मैं लगता है कि वह खिड़कियों में है, और खिड़कियों में पथ सी लिखे गए हैं: \ ProjX ...... मैं पूछता हूँ क्योंकि मैं RMI के साथ कुछ समस्याएं भी है, लेकिन मैं इस फैशन में नीति फ़ाइल है:

grant codebase  
"file:///C:\Users\anna\Desktop\lab5\Eclipse\ProgramareServer\programare.jar-" { 
    permission java.security.AllPermission; 
}; 

है क्या गलत है?

0

यह ठीक काम करता है जब मैंने Rmi रजिस्ट्री शुरू करने से पहले CLASSPATH चर तय किया। मुझे लगता है कि विचार यह है कि आरएमआई रजिस्ट्री आपके रिमोट स्टब्स लोड करेगी और इसके पास पहुंच होनी चाहिए। रजिस्ट्री चलाने से पहले कक्षाओं को क्लासस्पैट पर डालना आसान था। तो यह किसी भी अन्य कारण से संबंधित नहीं है जैसे कि जेडीके 7 या फ़ाइल:/प्रोटोकॉल।

संबंधित मुद्दे