Remote Method Invocation (RMI) FAQ From jGuru Generated Sep 13, 2005 2:17:06 PM Location: http://www.jguru.com/faq/RMI Ownership: http://www.jguru.com/misc/user-agree.jsp#ownership. Why must the CLASSPATH environment variable not include the path of the remote object's stub classes on the server host? Location: http://www.jguru.com/faq/view.jsp?EID=959 Created: Nov 13, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) If the CLASSPATH environment variable on the server host includes the path of the remote object's stub classes, it will cause rmiregistry to ignore the java.rmi.server.codebase property setting for the server. rmiregistry must contain the location of the stub files for the remote server object in an HTTP URL-encoded format, so that when this information is sent to the client, the classes can then be downloaded via an HTTP server. If rmiregistry does not send the location of the stub classes in HTTP-encoded format, the client having no way to download them, will simply throw a ClassNotFoundException. Comments and alternative answers
java.rmi.server.codebase, CLASSPATH Author: Federica Ciotti (http://www.jguru.com/guru/viewbio.jsp?EID=1176012), Jun 3, 2004 How can I tell rmiregistry to contain the location of the stub class in the HTTP URL encoded format? I try to do > unsetenv CLASSPATH > rmiregistry & > setenv CLASSPATH... > java -Djava.rmi.server.codebase=http://... server/Server But in this way when I start rmiregistry the CLASSPATH is empty?? Do you need an HTTP server to use RMI? Location: http://www.jguru.com/faq/view.jsp?EID=992 Created: Nov 14, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14)
Technically, you don't need an HTTP server to use RMI. You can always place the stub classes for the remote objects, along with any user-defined classes, within the client's CLASSPATH. But such a deployment is highly inflexible, and feasible only for the more simple implementations. In most real-life RMI deployment scenarios, the client retrieves all the classes dynamically via the HTTP protocol, by interacting with an web server running on the same host as the remote server objects. You can also make use of a simple HTTP "class server" implementation provided free by Sun, exclusively for use with RMI. The class-server can be downloaded at: ftp://ftp.javasoft.com/pub/jdk1.1/rmi/class-server.zip How do I run rmiregistry and RMI servers in the background under Windows? Location: http://www.jguru.com/faq/view.jsp?EID=995 Created: Nov 14, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) You can start rmiregistry or RMI servers from a DOS window under Win32 using the start command. But this does not run your servers truly in the background, as a little DOS window for the java interpreter remains in the foreground for each server that is started. If you are starting numerous remote servers under Win32, all the DOS windows could prove rather problematic. A solution is to use the javaw command that is supplied as part of the Windows JDK/SDK. This fires up the Java interpreter as a seperate process and runs your RMI server in the background. This effectively eliminates the clutter of DOS windows in the foreground for each of your RMI servers. Do note that there are some downsides to using javaw. For instance, it is no longer that simple to terminate a running Java process - you now have to do it via the task manager. Also, if you are in debugging mode, you will not be able to see any of the diagnostic messages sent to the console, as it is now in the background. Comments and alternative answers
Java Rmi Author: Amit jain (http://www.jguru.com/guru/viewbio.jsp?EID=425018), Apr 9, 2002 There is no nees to use the start service of windows to start Rmiregistry just write the below code before rebind methord for ur remote object like as below :- Registry registry =LocateRegistry.createRegistry(1099); SaveImageInterface server=new SaveImageServer(); registry.rebind("//localhost/remoteserver",server); Naming.rebind("//localhost/remoteserver); this code will register the object on the host which is running the servre and for making the server as background user javaw [name of the server ]
Re: Java Rmi Author: kumar padhu (http://www.jguru.com/guru/viewbio.jsp?EID=1089663), Jun 3, 2003 can you run only the rmiregistry in a seperate server and keep it alive Re[2]: Java Rmi Author: sandeep pathuri (http://www.jguru.com/guru/viewbio.jsp?EID=1215078), Jun 24, 2005 Yes Can I run an RMI application that makes use of callbacks across firewalls? Location: http://www.jguru.com/faq/view.jsp?EID=997 Created: Nov 14, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) No, you cannot use RMI applications that make use of callbacks across firewalls. The RMI transport layer makes use of HTTP tunneling to get through firewalls. Since HTTP is a stateless protocol, it does not offer a suitable transport layer for the callback mechanism. Comments and alternative answers
I do not think this is the right answer. If the st... Author: Randolph Kahle (http://www.jguru.com/guru/viewbio.jsp?EID=1391), Dec 1, 1999 I do not think this is the right answer. If the stateless nature of the HTTP protocol is a problem, then how can it work for non-callback connections? HTTP could be used for callbacks if the client side was given the same capabilities as the server. I think the answer should be that the RMI team did not elect to put in the functionality to support this feature. -- Randy Kahle Even if the RMI team had provided functionality fo... Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14), Dec 3, 1999 Even if the RMI team had provided functionality for invoking callbacks across firewalls, it would be impractical to use, all the same. For instance, then each of the client machines behind a firewall would also have to run a HTTP server in order to do the call forwarding using the java-rmi.cgi script. That means that if the server is behind a firewall... Author: Vishal Malhan (http://www.jguru.com/guru/viewbio.jsp?EID=71977), Jun 11, 2000 That means that if the server is behind a firewall we can do callbacks and not when the clients are behind a firewall. Re: That means that if the server is behind a firewall... Author: Mark Riner (http://www.jguru.com/guru/viewbio.jsp?EID=1125568),
Nov 3, 2003 Hello, I'm facing the Same problem (CallBack Socket) and I'd like to check the solution your proposed. The link does not seem to work. Can you please make it available or just give instruction about how you made it?
To make a callback, the server has to become a client.... Author: Tim Taylor (http://www.jguru.com/guru/viewbio.jsp?EID=238921), Oct 27, 2000 To make a callback, the server has to become a client. For that to happen, the server has to be able to establish a socket to the client address and port. This is sometimes not possible with a firewall in the way or when the client initially contacts the server through dial-up networking. I have an experimental solution if you would like to try it. It uses socket factories to negotiate socket creation. Sockets are always initiated from the client. Let me know if you find it useful or find bugs in it. You can try my free solution if you want to. It... Author: Tim Taylor (http://www.jguru.com/guru/viewbio.jsp?EID=238921), Oct 29, 2000 You can try my free solution if you want to. It uses socket factories to implement twoway RMI call communication between client and server. Re: You can try my free solution if you want to. It... Author: Surendra Rathi (http://www.jguru.com/guru/viewbio.jsp?EID=587439), Dec 17, 2001 can u post your free solution ?? Re[2]: You can try my free solution if you want to. It... Author: Surendra Rathi (http://www.jguru.com/guru/viewbio.jsp?EID=587439), Dec 17, 2001 I saw the solution. But can u post some documentation on how it works. Re[3]: You can try my free solution if you want to. It... Author: Tim Taylor (http://www.jguru.com/guru/viewbio.jsp?EID=238921), Dec 18, 2001 When your client starts up, it creates a special socket connection to the server. When the server needs to connect to the client, it sends a request over the special socket, asking the client to make a connection to the server. The server waits for the connection to come from the client and uses that socket for the callback. I.e., all socket connections (call and callback both) are made from the client to the server.
Generally, I think callbacks should be avoided, but if you need them and know that you don't need HTTP tunnelling, my hack can help. There was some speculation in the excellent book titled "java.rmi" that the callback issue and HTTP tunnelling might be solved in Java 1.4 either for JRMP or IIOP or both. Re[4]: You can try my free solution if you want to. It... Author: Surendra Rathi (http://www.jguru.com/guru/viewbio.jsp?EID=587439), Dec 18, 2001 thanks for the response. But can u see your solution working in my case below. The problem i am facing now is when a firewall/gateway exists at the client side. The clients callback registered to the server has a local address which is not reachable by the server. And so the updates dont reach. Client connects over a vpn connection. 1) The server knows the VPN assigned ip address of the client and can give it to the remote client ? Is there any way i can make the client register its callback object with this 'vpn' address. 2) I have gone thru ur solution code (most of it). What i dont understand is should i use it both at the client and the server side ? (eg the call to RMISocketFactory.setSocketFactory()). Can i just use it only on client so that it makes the callback register with the right address on the server. I surely dont understand the rmisocket factory all that much. I would have avoided the rmi callbacks if there was another way of pushing updates to the client instead of client polling endlessly. thanks in advance suren Re[5]: You can try my free solution if you want to. It... Author: Tim Taylor (http://www.jguru.com/guru/viewbio.jsp?EID=238921), Dec 19, 2001 If you are using a VPN, my solution should work transparently. I.e., you don't need to do anything except install the client and server socket factories and establish the signalling socket as shown in the example. After that, the socket factories on the client and server side will negotiate the callback connections. Just code your callbacks as normal, and they should just work. Tim
Re: You can try my free solution if you want to. It... Author: Paloma Ortega (http://www.jguru.com/guru/viewbio.jsp?EID=926756), Jun 25, 2002 I have been trying to access your solution but I can´t get to it. Is there any other way to download it? I have a server behind a firewall and a client accessing its interface methods through RMI. There is also a callback interface for the server to access the client once it has registered and there is no problem when the client is connected to a LAN (we are using SocketFactory), but if the client is connected through GPRS, we get the exception java.rmi.ConnectException: Connection refused to host:X.X.X.X nested exception is: java.net.ConnectException: Connection timed out: connect Is there anything we are missing? Thank you, P
Re[2]: You can try my free solution if you want to. It... Author: Tim Taylor (http://www.jguru.com/guru/viewbio.jsp?EID=238921), Jul 4, 2002 Anonymous FTP wasn't working at my site. It's back now. The solution should work for you over GPRS if you can get a true socket connection to your server from the client. You are getting the ConnectException on the server because it is trying to connect back to the client. With my solution, the server will instead send a request to the client and ask the client to create the socket back to the server. Re[3]: You can try my free solution if you want to. It... Author: Paloma Ortega (http://www.jguru.com/guru/viewbio.jsp?EID=926756), Oct 15, 2002 Hello, We have successfully used this solution in order to get through a firewall for callback requests. However, if the client application finishes, we obtain an exception in the server side saying: java.net.SocketException: Connection reset by peer: JVM_recv in socket input stream read at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:116) at java.io.BufferedInputStream.fill(BufferedInputStream.java:183) at java.io.BufferedInputStream.read(BufferedInputStream.java:201) at java.io.DataInputStream.readInt(DataInputStream.java:392) at com.css.rmi.ServerTwoWaySocketFactory$1.run(ServerTwoWaySocketFactory.java:65) When using only RMI and no socket factories at all, this exception is not thrown. We have been thinking about closing the sockets used for the communication, is it possible to use the solution for this? is there any other way we haven´t thought of? Thank you, Paloma Re: You can try my free solution if you want to. It...
Author: jia wei (http://www.jguru.com/guru/viewbio.jsp?EID=1042437), Jan 2, 2003 Hi Tim, I am encountering RMI callback through firewall problem in my java application. I tried to access your solution, but it was not successful. Could you post or show me your solution? Thanks in advance. Jenny Re[2]: You can try my free solution if you want to. It... Author: sudipta tripathy (http://www.jguru.com/guru/viewbio.jsp?EID=1085174), May 15, 2003 I want download your rmi free solutions.Could send me the link ? Thanks Sudipta Re[3]: You can try my free solution if you want to. It... Author: Jeff Shao (http://www.jguru.com/guru/viewbio.jsp?EID=1087400), May 23, 2003 Tim, Can you share the link for your solution? I don't have a clue how other folks were able to see your solution. Thanks, Jeff If I convert my application from RMI to RMI-IIOP, can... Author: stefano orselli (http://www.jguru.com/guru/viewbio.jsp?EID=290863), Jan 15, 2001 If I convert my application from RMI to RMI-IIOP, can I solve the problem of the callback in RMI across firewall, assuming my firewall has been configured to allow IIOP traffic? How can I control the lease period associated with a client's reference for my remote object? Location: http://www.jguru.com/faq/view.jsp?EID=1001 Created: Nov 14, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) When a RMI client obtains a reference for the remote object, by default, the reference is live for 10 minutes. If there is no client activity before the lease term expires, the reference is considered to be invalid, and the remote object may be subject to garbage collection, presuming there are no other clients holding a live reference to it. However, the lease term can be easily changed, and is controlled by the system property java.rmi.dgc.leaseValue. For example: java -Djava.rmi.dgc.leaseValue=300000 MyRemoteImpl resets the lease term to 5 minutes. The lease period is indicated in milliseconds. Note that for optimal performance, the lease term should not be set toa very small value. An active RMI client automatically renews the lease when it is halfway expired,
and a very small lease term would cause the client to consume precious network resources in repeatedly renewing the lease. Comments and alternative answers
After a remote server object is exported (and an object... Author: Avi Kak (http://www.jguru.com/guru/viewbio.jsp?EID=26410), Apr 7, 2000 After a remote server object is exported (and an object reference to it created) by invoking its constructor, it starts listening on a TCP connection. It is at this moment that its lease begins. This lease is renewed periodically and repeatedly after the expiration of half the value of rmi.dgc.leaseValue. As can be seen from the logged server activity (which can be observed by setting the rmi.server.logCalls property true), this renewal takes place regardless of the extent of client activity. Can my remote object obtain notification when there are no live references to it? Location: http://www.jguru.com/faq/view.jsp?EID=1002 Created: Nov 14, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Yes, you can enable remote objects to get notified as soon as there are no valid references to it. Although the distributed garbage collection mechanism takes care of memory management issues, explicit notification can help the remote server release valuable resources like network and database connections immediately. Any remote object that implements java.rmi.server.Unreferenced interface can get immediate notification via the unreferenced() method as soon as the server does not have any valid references to it. The following code snippet demonstrates how: public class RemoteServerImpl extends UnicastRemoteObject implements MyRemoteInterface, Unreferenced { public RemoteServerImpl() { super(); . . . //allocate resources } . . . public void unreferenced() { //deallocate resources here } } Comments and alternative answers
It seems to me that merely implementing the Unrefe... Author: Avi Kak (http://www.jguru.com/guru/viewbio.jsp?EID=26410), Apr 8, 2000 It seems to me that merely implementing the Unreferenced interface is not enough for receiving notification of no more live references to a remote server object. In the
following "Hello" example, the class HelloImpl implements the Unreferenced interface and provides an implementation for its unreferenced() method. Yet this method is never invoked even long after the client has stopped interacting with the server. The RMI Specification document says: "As long as some client holds a remote reference to the remote object, the RMI runtime keeps a local reference to the remote object. When the "reference" set becomes empty, the Unreferenced.unreferenced method is invoked (if the server implements the Unreferenced interface)." But the following example shows that the meaning one would ordinarily give to these statements in the RMI specification document is not valid. /////////
server file: Hello.java
////////
import java.rmi.*; public interface Hello extends Remote { public String sayHello() throws RemoteException; } ///////
server file: HelloImpl.java
////////
import java.rmi.*; import java.rmi.server.*; import java.net.*; public class HelloImpl extends UnicastRemoteObject implements Hello, Unreferenced { public HelloImpl() throws RemoteException {} public String sayHello() { String hostname = null; try { hostname = InetAddress.getLocalHost().getHostName(); } catch( java.net.UnknownHostException un ) {} return "Hello from Avi Kak at " + hostname; } public void unreferenced() { System.out.println( ">>>> No clients holding remote references <<<" ); } } ///////// server file: HelloServer.java import java.rmi.*; import java.rmi.server.*;
////////
import java.rmi.registry.*; public class HelloServer { public static void main( String[] args ) { try { LocateRegistry.createRegistry( 1099 ); HelloImpl helloserver = new HelloImpl(); Naming.rebind( "rmi://localhost/HelloServer", helloserver ); } catch( Exception e ) {} } } /////////
client file: HelloClient.java
///////
import java.rmi.*; public class HelloClient { public static void main( String[] args ) { try { Hello server = ( Hello ) Naming.lookup( "rmi://RVL4.ecn.purdue.edu/HelloServer" ); System.out.println( server.sayHello() ); } catch( Exception e ) {} } }
But at the same time, the jGuru Distributed Garbage... Author: Avi Kak (http://www.jguru.com/guru/viewbio.jsp?EID=26410), May 18, 2000 But at the same time, the jGuru Distributed Garbage Collection Exercise shows that when there are no client references to a remote object that has implemented the Unreferenced interface, the server does indeed receive notification via the automatic invocation of the Unreferenced.unreferenced() method. For the reason for why the RMI system acts differently in the two cases, see the jGuru RMI FAQ entry 48518. There's got to be a better way Author: JJ Furman (http://www.jguru.com/guru/viewbio.jsp?EID=860138), Apr 29, 2002 Although the Unreferenced mechanism seems to be working, a simple test is taking 10 minutes to detect a dropped client. This is far far too long for my application. Is there any way to encourage it to go faster? JJ
Re: There's got to be a better way Author: Raul Guiu (http://www.jguru.com/guru/viewbio.jsp?EID=878594), May 14, 2002 You can try to add the system property: -Dsun.rmi.dgc.checkInterval=1000 How does the Distributed Garbage Collection algorithm work? Location: http://www.jguru.com/faq/view.jsp?EID=1004 Created: Nov 14, 1999 Modified: 1999-11-18 22:16:04.265 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) The RMI subsystem implements a reference counting-based distributed garbage collection (DGC) algorithm to provide automatic memory management facilities for remote server objects. Basically, DGC works by having the remote server keep track of all external client references to it at any given time. When a client obtains a remote reference, it is addded to the remote object's referenced set. The DGC then marks the remote object as dirty and increases its reference count by one. When a client drops a reference, the DGC decreases its reference count by one, and marks the object as clean. When the reference count reaches zero, the remote object is free of any live client references. It is then placed on the weak reference list and subject to periodic garbage collection. Where can I find a detailed comparison between RMI, DCOM and CORBA? Location: http://www.jguru.com/faq/view.jsp?EID=1006 Created: Nov 14, 1999 Modified: 2000-05-29 11:25:34.963 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Suresh Gopalan Raj has written a detailed article comparing the three technologies. The article can be found in his "Web Cornucopia" site, at: http://www.execpc.com/~gopalan/misc/compare.html Is there a way I can disable my RMI client from using HTTP tunneling to get through firewalls? Location: http://www.jguru.com/faq/view.jsp?EID=1011 Created: Nov 14, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Yes. Although HTTP tunneling is automatically used by the RMI transport layer to get across firewalls, you can choose to disable this feature by setting the following property at the client: java.rmi.server.disableHttp=true What's the cleanest way to have a client terminate a RMI server that is no longer needed? Location: http://www.jguru.com/faq/view.jsp?EID=1013 Created: Nov 15, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14)
The cleanest way to exit is to convert your remote object into an activatable remote object and then a client can invoke the Activatable.unexportObject() method to get rid of it. Things are a little more complicated if you do not have an activatable remote object. It is very important that your server does not exit before the client's request has been fully processed, as otherwise an UnmarshallException is thrown. One approach is to define an "exit handler thread" as an inner class, and instantiate it within the remote object's constructor. The exit handler can then loop in the background, waiting for an "exit" flag to be set by the client via an RMI call. As soon as the flag is set, the exit handler can then wait for a couple of seconds such that the client call is completely processed, and then call System.exit() to terminate the server. Is it true that my RMI applet can make socket connections only to the host from which the applet was downloaded from? Location: http://www.jguru.com/faq/view.jsp?EID=1031 Created: Nov 15, 1999 Modified: 2001-07-07 20:58:56.171 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Yes, the default behaviour for applets (including those that may be RMI clients) is to communicate with an RMI server that is hosted on the same platform from which the applet was served from. It is one of the manifestations of the applet sandbox paradigm, and can be overcome by deploying "signed applets" which can go beyond the sandbox. Comments and alternative answers
peer to peer applet communication Author: sebastian marcet (http://www.jguru.com/guru/viewbio.jsp?EID=1138545), Jan 12, 2004 there is any posibility to establish a communication between two applets comming from the same server but runnig in diferents clients machines(there is differents JVM and Browseers) without having a server that perform the rol of menssager dispathcher? Re: peer to peer applet communication Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7), Jan 12, 2004 The fact that two applets came from the same server is irrelevant. Without signing your applet, they won't have permission to talk to each other. Even with signing, unless you use a server to discover the other client address, there is no way for the applets to chat. Is there a servlet implementation of the java-rmi.cgi script for enabling call forwarding when using RMI across firewalls? Location: http://www.jguru.com/faq/view.jsp?EID=1033
Created: Nov 15, 1999 Modified: 2000-05-29 11:32:07.363 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Yes, Sun has a servlet implementation of the call forwarding script for performing HTTP tunneling. You can download it from: http://java.sun.com/products/jdk/1.2/docs/guide/rmi/faq.html#servlet I get the exception "java.net.SocketException: Address already in use" whenever I try to run rmiregistry. Why? Location: http://www.jguru.com/faq/view.jsp?EID=1034 Created: Nov 15, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) The exception means that there is already an rmiregistry process running on the default port 1099 on that machine. You can either choose to kill it and restart rmiregistry, or start it up on a different port , say port 9999, as: rmiregistry 9999 Why is that my remote objects can bind themselves only with a rmiregistry running on the same host? Location: http://www.jguru.com/faq/view.jsp?EID=1035 Created: Nov 15, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Although an RMI application can perform a lookup on any host, it can bind, rebind or unbind remote object references only with a registry running on the same host. This is mainly for security reasons, as this restriction prevents a remote client from deleting or overwriting entries from a server's registry. Comments and alternative answers
Is there are way to get around it ? Author: piyush sheth (http://www.jguru.com/guru/viewbio.jsp?EID=705911), Jan 16, 2002 Is there are way to get around it ? What are the different RMI system configurations possible? Location: http://www.jguru.com/faq/view.jsp?EID=1110 Created: Nov 17, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) RMI systems can be configured in diverse ways: •
Closed: All classes used by clients and the server must be located on the JRE and referenced by the CLASSPATH environment variable. No dynamic class loading is supported.
• •
•
• •
Server based: A client applet is loaded from the server's CODEBASE along with all supporting classes. This is similar to the way applets are loaded from the same HTTP server that supports the applet's web page. Client dynamic: The primary classes are loaded by referencing the CLASSPATH environment variable of the JRE for the client. Supporting classes are loaded by java.rmi.server.RMIClassLoader from an HTTP or FTP server on the network at a location specified by the server. Server dynamic: The primary classes are loaded by referencing the CLASSPATH environment variable of the JRE for the server. Supporting classes are loaded by the java.rmi.server.RMIClassLoader from an HTTP or FTP server on the network at a location specified by the client. Bootstrap client: In this configuration, all of the client code is loaded from an HTTP or FTP server across the network. The only code residing on the client machine is a small bootstrap loader. Bootstrap server: In this configuration, all of the server code is loaded from an HTTP or FTP server located on the network. The only code residing on the server machine is a small bootstrap loader.
When would I use the java.rmi.server.codebase property? Location: http://www.jguru.com/faq/view.jsp?EID=1111 Created: Nov 17, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) The property java.rmi.server.codebase is used to specify a URL. This URL points to a file:, ftp:, or http: location which supplies classes for objects that are sent from this JRE. If a program running in a JRE sends an object to another JRE (as the return value from a method), that other JRE needs to load the class file for that object. When RMI sends the object via serialization RMI embeds the URL specified by this parameter into the stream, alongside of the actual object. It is important to note that RMI does not send class files along with the serialized objects. If the remote JRE needs to load a class file for an object, it looks for the embedded URL and contacts the server at that location for the file. What is the purpose of the java.rmi.server.useCodebaseOnly property? Location: http://www.jguru.com/faq/view.jsp?EID=1115 Created: Nov 17, 1999 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) When the property java.rmi.server.useCodebaseOnly is set to true, then the JRE will load classes only from either a location specified by the CLASSPATH environment variable or the URL specified in the java.rmi.server.codebase property. This is an easy way of imposing additional security to the behaviour of RMIClassLoader. Comments and alternative answers
that's a very good solution Author: Marc Tauber (http://www.jguru.com/guru/viewbio.jsp?EID=990941), Jan 29,
2003 cool! that works and is very easy to do! thanx a lot What's new in RMI under Java 2? Location: http://www.jguru.com/faq/view.jsp?EID=1845 Created: Dec 4, 1999 Modified: 2000-07-09 20:44:16.676 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Java 2 SDK adds significant enhancements to the RMI implementation found within JDK 1.1. The most important changes are: •
•
•
Under JDK 1.1, RMI servers have to be up and running all the time, and could not be started 'on demand'. Java 2 adds Remote Object Activation framework to RMI. It is now possible to instantiate server objects "on the fly," making it possible to build even more scalable distributed object networks. Java 2 allows you to implement Custom Socket Types making it simpler to incorporate SSL encryption, data compression and so forth at the transport level. With JDK 1.1, the RMI socket factory could use only one custom socket type per JVM. You also had to use a different rmiregistry for each custom socket implemented by an RMI server. Now, all those limitations are removed. There have been numerous other API changes as well. For instance, you can now unexport a remote object, as well as export a object on a specific port. Also, the RMI transport protocol JRMP has been significantly streamlined, and server-side skeletons are no longer necessary under Java 2. For an exhaustive list of changes, consult the release notes at http://java.sun.com/products/jdk/1.2/docs/guide/rmi/relnotes.html
How does Java RMI differ from Jini? Location: http://www.jguru.com/faq/view.jsp?EID=5075 Created: Jan 15, 2000 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14)
Java RMI RMI clients use the class Naming.Lookup() for locating the requested RMI Service The service storing information about other service providers is the RMI registry The RMI client must know the RMI registry host explicitly. The same rule applies to RMI servers The approach is more rigid since client is dependant on a particular service provider
Jini Jini clients use the discovery process to locate Jini Lookup services. Discovery is done through multicast requests to well-known addresses or ports In Jini the service storing information about other service providers is called Jini Lookup Service The Jini clients search for the Jini service without any Service hosting knowledge The approach is more tolerant to service providers faults and maximizes client independence from a particular service provider
The Jini proxy concept is more protocol independent since it does not rely on generated fixed-protocol stubs. The RMI proxy-stub approach is The proxy fulfills requests by itself or either uses an strictly adhered to RMI call or uses an internal proxy provider to fulfill a request No concept of built in support for Programming model provides for support for transactions, distributed events or transactions, distributed events and leasing leasing
Is there another RMI FAQ that I can look at? Location: http://www.jguru.com/faq/view.jsp?EID=9241 Created: Jan 27, 2000 Modified: 2000-01-27 08:57:07.397 Author: John Mitchell (http://www.jguru.com/guru/viewbio.jsp?EID=4) Yes, check out: Sun's RMI FAQ. Comments and alternative answers
New url Author: Thomas Hartwig (http://www.jguru.com/guru/viewbio.jsp?EID=1108477), Apr 6, 2005 SUN's RMI FAQ Is there a mailing list for RMI discussions? Location: http://www.jguru.com/faq/view.jsp?EID=9243 Created: Jan 27, 2000 Modified: 2000-01-27 08:36:11.952 Author: John Mitchell (http://www.jguru.com/guru/viewbio.jsp?EID=4) Yes, Sun's RMI-USERS mailing list. To subscribe, send an email to
[email protected] which contains the message: subscribe RMI-USERS Note that the archives of the mailing list are here. Please check them out before sending questions to the mailing list. Is "pass by value" enforced for calls within the same VM to objects that implement java.rmi.Remote? In other words, if I'm writing an object that implements java.rmi.Remote, can I assume that calls to it that originate within the local VM will enjoy the same "copy by value" rules for serializable
parameters? Location: http://www.jguru.com/faq/view.jsp?EID=10742 Created: Feb 1, 2000 Modified: 2000-02-01 14:10:06.078 Author: Tim Rohaly (http://www.jguru.com/guru/viewbio.jsp?EID=10) Question originally posed by Ben Youngdahl (http://www.jguru.com/guru/viewbio.jsp?EID=6973 Say I have a remote interface: public interface Hello extends Remote { public String sayHello() throws RemoteException; } and an implementation like: public class HelloImpl extends UnicastRemoteObject implements Hello { public String sayHello() { return "Hello!"; } } Here, the return parameter of the sayHello() method is a serializable object (String). If you obtain a reference by simply instantiating HelloImpl, then its semantics are that of a normal Java object. i.e., if you do: Hello hello = new HelloImpl(); String result = hello.sayHello(); then the "result" reference points to the same object as the local String object created within HelloImpl.sayHello() - a copy of the String object is not made. But, if we obtain a remote reference to the object, for example: Hello hello = (Hello) Naming.lookup("rmi://localhost/helloserver"); hello.sayHello(); then the semantics are different, because we don't have a normal reference created by "new", we have a remote reference obtained by contacting the RMI registry. In this second case, the result string is serialized and returned, effectively creating a copy. Note that this is true whether or not the actual implementation object lives in the same VM. The deciding factor is how the reference was obtained. Comments and alternative answers
Note that the call semantics also differ depending on... Author: Tim Rohaly (http://www.jguru.com/guru/viewbio.jsp?EID=10), Feb 1, 2000 Note that the call semantics also differ depending on how the reference was obtained. Method invocations on a remote reference can throw a RemoteException, which must be handled. Method invocations on a local reference need handle only those exceptions declared by that method in the implementation class. There are two problems with your example. First of... Author: Ben Youngdahl (http://www.jguru.com/guru/viewbio.jsp?EID=10764), Feb 1, 2000
There are two problems with your example. First of all, you focus on the return value, which is not as interesting here as argument parameters. Second of all, you focus on an immutable type, String, which is also not as interesting. Also, I think you should talk about why this is DANGEROUS that different things can happen depending on how the reference is obtained. The two things you mention have no relevance to the... Author: Tim Rohaly (http://www.jguru.com/guru/viewbio.jsp?EID=10), Feb 4, 2000 The two things you mention have no relevance to the problem: return parameters are treated the same as method arguments, and references to immutable objects are treated the same as references to mutable objects. I disagree that this is dangerous. There are fundamental differences between remote objects and local objects that you can't abstract away. Indeed, it is dangerous if you don't treat them differently! This is why the compiler forces you to deal with RemoteException, like I say above. Thus, it is always explicit in your code what the object's semantics are. You can learn more about the necessary differences between local and remote objects from "A Note on Distributed Computing" by Jim Waldo et al. http://www.sun.com/research/technical-reports/1994/abstract-29.html. This issue has also been discussed ad nauseam on the RMI-USERS mailing list. See: http://archives.java.sun.com/archives/rmi-users.html. Does this mean that: In the first case (new "... Author: Jong Hann Wong (http://www.jguru.com/guru/viewbio.jsp?EID=49040), May 30, 2000 Does this mean that: In the first case (new "local" instance), we will not need a stub for every instance? Eg. a server has a dispatcher that sends down a new servant instance to each client. In the second case (using remote references), the server application must already have instantiated such a servant instance, bound it to an entry in rmiregistry. More work coming up: the client has to actually know beforehand which "name" that instance is bound to. True/False?
Tim, consider the following: 1) X obtains a reference... Author: Ben Youngdahl (http://www.jguru.com/guru/viewbio.jsp?EID=6973), Jun 10,
2000 Tim, consider the following: 1) X obtains a reference to Y, an object implementing Remote 2) X calls a method on Y passing in mutable, serializable object M 3) Y makes some evil changes to M The danger as I see it is that if Y is within a seperate VM, M is not truly affected. If Y is within the same VM as X, M is affected. If M is immutable, it can't be changed by Y anyways, so no harm done. If M is returned by Y but not passed in by X, the only risk is if Y hangs on to a reference to M and plays around with it later. See Appendix D.7 (pp 511,512) of the EJB 2.0 public draft. Doesn't it acknowledge this situation is dangerous? I do agree with you that it is dangerous to ignore whether an object is local or remote, like for example COM/DCOM. I guess that's my point here: don't assume that because an object extends Remote that it actually IS remote and will honor RMI passby-value.
How do I send a ResultSet back to a client using RMI? Location: http://www.jguru.com/faq/view.jsp?EID=14711 Created: Feb 16, 2000 Modified: 2000-02-16 01:11:05.293 Author: Tim Rohaly (http://www.jguru.com/guru/viewbio.jsp?EID=10) java.sql.ResultSet is not serializable, so it cannot be sent over an RMI connection. You will need to extract the data from the ResultSet and encapsulate it in a serializable object to send back to your client. Or, wrap the ResultSet in a remote object, and make that remote object available to your client. A danger with the second method is that you are giving control over the life span of the ResultSet to the client--as long as the client holds a reference to the remote object your server must maintain the database connection. Because database connections are vital system resources, you probably want to maintain control of them entirely on the server side or in a middle tier. Comments and alternative answers
Can anyone post some code for this? Author: sreedhar garimella (http://www.jguru.com/guru/viewbio.jsp?EID=46673), Jun 10, 2000 Can anyone post some code for this?
How can I log my remote server calls? Location: http://www.jguru.com/faq/view.jsp?EID=17504 Created: Feb 23, 2000 Modified: 2000-02-23 22:25:06.746 Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) If you start the server with the java.rmi.server.logCalls system property set to true (java -Djava.rmi.server.logCalls=true Server), you'll be able to monitor server activity. By default, what port does the RMI registry listen to? Location: http://www.jguru.com/faq/view.jsp?EID=17516 Created: Feb 23, 2000 Modified: 2000-02-23 22:40:26.761 Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) The rmiregistry program uses port 1099 by default. You can have it listen to a different port by specifying a different port from the command line: rmiregistry 1234 Comments and alternative answers
Well known port for registry. Author: John Sinues (http://www.jguru.com/guru/viewbio.jsp?EID=339990), Sep 6, 2002 You can also use the predefined constant, java.rmi.Registry.REGISTRY_PORT. What's the scoop with HTTP-tunnelling? Does it really work? Reliably? Quickly? Easily? Location: http://www.jguru.com/faq/view.jsp?EID=19859 Created: Mar 2, 2000 Modified: 2000-05-29 12:14:42.95 Author: Govind Seshadri (http://www.jguru.com/guru/viewbio.jsp?EID=14) Question originally posed by John Mitchell PREMIUM (http://www.jguru.com/guru/viewbio.jsp?EID=4 For complete details, see my RMI tutorial at Sun's Java Developer Connection: http://developer.java.sun.com/developer/onlineTraining/rmi/RMI.html#FirewallIssues Where can I get the RMI classes for Internet Explorer? Location: http://www.jguru.com/faq/view.jsp?EID=20626 Created: Mar 6, 2000 Modified: 2000-09-14 07:42:58.557 Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) You can get these either directly from Microsoft (ftp://ftp.microsoft.com/developr/msdn/unsup-ed/rmi.zip) and figure out where to put them or get a nice bundled package from IBM (http://www.alphaworks.ibm.com/tech/RMI) that installs them in the right location. I have a servlet that is doing an RMI call to a single remote object. Since any invocation of the servlet is created in a new thread, I'm observing a new TCP/IP connection for every single servlet request. Creating and tearing down a TCP/IP connection between the servlet engine and the
remote object's JVM for every request seems to be a lot of overhead. I have read through the RMI spec. It seems that one could create an alternate implementation of java.rmi.server.RMIClientSocketFactory that could manage a pool of TCP/IP connections and assign them to threads on an asneeded basis. Is this possible? Location: http://www.jguru.com/faq/view.jsp?EID=20880 Created: Mar 6, 2000 Modified: 2000-03-08 09:14:11.159 Author: Sameer Tyagi (http://www.jguru.com/guru/viewbio.jsp?EID=4381) Question originally posed by Phil Earnhardt (http://www.jguru.com/guru/viewbio.jsp?EID=8332 A method dispatched by the RMI runtime to a remote object implementation (a server) may or may not execute in a separate thread. Some calls originating from the same client virtual machine will execute in the same thread; some will execute in different threads. Calls originating from different client virtual machines will execute in different threads. Other than this last case of different client virtual machines, the RMI runtime makes no guarantees with respect to mapping remote object invocations to threads. Consider the following example. A remote object MyObject is bound to the registry and it has a method called mymethod(). Servlets obtain a reference and invoke this method in their service methods. Let us assume that 500 concurrent calls are made to this method from the servlet instance. Does this mean that the 500 calls will be queued up ? Well, actually no. The RMI object can be called by several threads concurrently. It is very easy to test: simply have a counter in the object which is ticked up one at the beginning of the method, and decrease it at the end. This way you'll know how many threads are working on it concurrently. Print it out and you'll know for sure what's happening. It is rather simple: RMI/JRMP maintains connections from the client to the server. If a call is to be made and all connections is currently in use another one is created. This will only hold to a certain point however since there is a finite number of server threads. In the scenario you describe, it would be simple to obtain a reference to the object in the init of the servlet and invoke methods on the objects in the service method. Since you will always deal with the same instance of the remote object at all points in time. As long as the object itself is thread safe, everything should be fine. Comments and alternative answers
For RMI callback from server to clients(say, applets)... Author: Maxim Senin (http://www.jguru.com/guru/viewbio.jsp?EID=21992), Nov 3, 2000
For RMI callback from server to clients(say, applets) this would be disaster. 1st, you will spawn separate thread for each callback to client, which in turn will try to open connection to it (100 clients = 100 attempts to open TCP/IP connections to clients who probably have dial-up), and then method invocations themselves!!! Singleton RMI object Author: Sudha Subramaniam (http://www.jguru.com/guru/viewbio.jsp?EID=270396), Sep 21, 2001 In reply to one of the RMI question posted here, it was mentioned that an 'RMI object can have multiple threads accessing it concurrently". My question is: Does this mean that the JVM creates seperate threads for each remote request? Thanks Sudha Re: Singleton RMI object Author: karthik Guru (http://www.jguru.com/guru/viewbio.jsp?EID=849009), Apr 23, 2002 quoting from RMI SPec:
A method dispatched by the RMI runtime to a remote object implementation (a server) may or may not execute in a separate thread. Some calls originating from the same client virtual machine will execute in the same thread; some will execute in different threads. Calls originating from different client virtual machines will execute in different threads. Other than this last case of different client virtual machines, the RMI runtime makes no guarantees with respect to mapping remote object invocations to threads
that means RMI Runtime may/may not create a separate thread for each remote request. rather it does'nt. How do I communicate over a secure RMI link? Location: http://www.jguru.com/faq/view.jsp?EID=20911 Created: Mar 6, 2000 Modified: 2000-03-08 09:23:49.51 Author: Sameer Tyagi (http://www.jguru.com/guru/viewbio.jsp?EID=4381) Question originally posed by John Zukowski PREMIUM (http://www.jguru.com/guru/viewbio.jsp?EID=7 You can find all the details you need within the following Sun documents: The SUN SSL Info Creating custom socket factories The naming registry is implemented as a standard RMI service, so attempts to register and lookup services will involve network connections being established. With an SSL socket factory installed in a client these connections will be SSL-secured. As a result, the naming registry must use SSL to accept connections. For this reason you must install the SSL socket factory in your naming registry as well as your RMI server. The most straightforward way to achieve this is to have your server start its own naming registry. This registry will then benefit from the server's SSL support. The server would need to invoke a method like this before binding the object and starting the registry and similarly on the client beore looking up the object
RMISocketFactory.setSocketFactory (some vendor provided factory); Note : In other words the vendors provide a SSL implementation of the registry that needs to be started instead of the rmiregisty in case you are not programmatically statring the registry through a LocateRegistry.createRegistry(). For activation, how do I get my objects to run in multiple VMs and not the VM of rmid.exe ?? Location: http://www.jguru.com/faq/view.jsp?EID=22886 Created: Mar 10, 2000 Modified: 2000-03-10 13:08:36.557 Author: Sameer Tyagi (http://www.jguru.com/guru/viewbio.jsp?EID=4381) The deal with spawning multiple VMs is the following bottom line. Refer to page 56 of the RMI specs ... "All objects with the same groupID are activated in the same Java VM". period. To start multiple VMs, the object must have a differnt ActivationGroupID. and you must use one of the 2 constructors ActivationDesc(ActivationGroupID groupID, String className, String location, MarshalledObject data) ActivationDesc(ActivationGroupID groupID, String className, String location, MarshalledObject data, boolean restart) I have written an example for you that registers 2 Activable objects with the registry. The 2 objects have different ActivationGroupID's as you can see in the source. Since the objects are lazily activated, you can see that 2 VMs are spawned when the client is run. I have enclosed with this the complete example. The example contains 1. The remote interface 2. The remote interface implementation 3. The program to register the server. 4. The client program 5. The batch files to run both client and server. package com.sameer; import java.net.InetAddress; import java.rmi.*; import java.rmi.activation.*; public class HelloServer
extends Activatable implements Hello {
private static int counter=0; public HelloServer(ActivationID id, MarshalledObject data) throws RemoteException { super( id, 0 ); System.out.println("Hello Server Constructor invoked" +counter); counter++; }
public String sayHello(){ String hostname=null; try{ hostname= InetAddress.getLocalHost().getHostName(); }catch (java.net.UnknownHostException who){} return "Hello World from " + hostname; } }
package com.sameer; public interface Hello extends java.rmi.Remote { String sayHello() throws java.rmi.RemoteException; }
package com.sameer; import import import public
java.rmi.*; java.rmi.activation.*; java.util.Properties; class RegisterHelloServer { public static void main(String[] args) throws Exception {
Properties policyFileLocation = new Properties(); policyFileLocation.put("java.security.policy","c:\\rmiac\\java.po licy"); ActivationGroupDesc exampleGroup = new ActivationGroupDesc(policyFileLocation, null); ActivationSystem localActivationSystem = ActivationGroup.getSystem(); ActivationGroupID agi = localActivationSystem.registerGroup(exampleGroup); a JVM
//The activation group is what creates the activatible object in // Sets the activation group for the current JVM ActivationGroup.createGroup(agi, exampleGroup, 0);
// Since the ActivationGroupID is not given in the constructor of desc, the // current JVMs activation group is used // create more ActivationGroupIDs since objects with the same ActivationGroupID are activated in the same VM //ActivationDesc(ActivationGroupID groupID, String className, Stringl ocation, MarshalledObject data, boolean restart) /*
This creates in the current VM and the current identifier for the ActivationGroupID. If the ActivationGroupID does not exist a new one is created. ActivationDesc desc = new ActivationDesc("com.sameer.HelloServer", "file:/export/home/whitney/java/classes/", null, true); */ ActivationDesc desc = new ActivationDesc(agi, "com.sameer.HelloServer", "file:/export/home/whitney/java/classes/", null, true); System.out.println("Gourp ID =" +desc.getGroupID()); Hello stub = (Hello)Activatable.register(desc); Naming.rebind("HelloServer", stub); // create another one for a new VM ActivationGroupID agi_2 = localActivationSystem.registerGroup(exampleGroup); ActivationDesc desc_2 = new ActivationDesc(agi_2, "com.sameer.HelloServer", "file:/export/home/whitney/java/classes/", null, true); System.out.println("Gourp ID =" +desc_2.getGroupID()); Hello stub_2 = (Hello)Activatable.register(desc_2); Naming.rebind("HelloServer2", stub_2); System.exit(0); }
}
package com.sameer; import java.rmi.*; public class HelloClient { private static String message = ""; public static void main(String args[]) { try { Hello obj = (Hello) Naming.lookup("/HelloServer"); System.out.println(obj.sayHello()); // Spawn the second VM !! Hello obj_2 = (Hello) Naming.lookup("/HelloServer2"); System.out.println(obj_2.sayHello()); } catch (Exception e) { System.out.println("HelloClient exception: " + e.getMessage()); e.printStackTrace(); } } }
grant { };
// Allow everything for now permission java.security.AllPermission;
What protocol does RMI use to communicate between objects? Do developers need to know the underlying protocol (eg. UDP, TCP/IP) while developing RMI applications? Location: http://www.jguru.com/faq/view.jsp?EID=23444 Created: Mar 12, 2000 Modified: 2000-03-12 23:55:45.054 Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question originally posed by YekSoon Lok (http://www.jguru.com/guru/viewbio.jsp?EID=12624 On top of TCP/IP, RMI uses a wire level protocol called Java Remote Method Protocol (JRMP). JRMP is a proprietary, stream-based protocol that is only partially specified and now consists of two versions. The first version was released with the JDK 1.1 version of RMI and required the use of Skeleton classes on the server. The second version was released with the Java 2 SDK. It has been optimized for performance and it does not require skeleton classes. (It is important to note that some alternate implementations, such as BEA Weblogic and NinjaRMI do not use JRMP, but instead use their own wire level protocol. ObjectSpace's Voyager does recognize JRMP and will interoperate with RMI at the wire level.) Sun and IBM have jointly worked on the next version of RMI, called RMI-IIOP, which will be available with Java 2 SDK Version 1.3. The interesting thing about RMI-IIOP is that instead of using JRMP, it will use the Object Management Group (OMG) Internet Inter-ORB Protocol, IIOP, to communicate between clients and servers. In most cases, developers do not need to know about the underlying protocol. With JDK 1.2, what policies do I have to setup to grant the necessary permissions for RMI? Location: http://www.jguru.com/faq/view.jsp?EID=24539 Created: Mar 15, 2000 Modified: 2000-03-15 07:34:14.029 Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question originally posed by sajith prasad k (http://www.jguru.com/guru/viewbio.jsp?EID=15898 Sun's RMI tutorial shows the necessary policies at http://java.sun.com/docs/books/tutorial/rmi/running.html. Basically, you have to enable connecting from anywhere to the HTTP port and connecting or accepting a connection to any port over 1K. Is there some way to lookup what remote services are available? Location: http://www.jguru.com/faq/view.jsp?EID=24729 Created: Mar 15, 2000 Modified: 2000-03-15 17:59:37.946 Author: John Zukowski (http://www.jguru.com/guru/viewbio.jsp?EID=7) Question originally posed by John Zukowski PREMIUM (http://www.jguru.com/guru/viewbio.jsp?EID=7
The Naming.list() method allows you to get a list of the objects in the registry, returning a String[] of names that can be looked up. Comments and alternative answers
Is there some way to lookup what remote services are available? Author: Ricardo V (http://www.jguru.com/guru/viewbio.jsp?EID=1214371), Dec 3, 2004 And, is there some way to avoid clients from looking up what remote services are available? Thanks. How do I setup a Servlet as an RMI client (and not get an RMI Security exception in the process)? Location: http://www.jguru.com/faq/view.jsp?EID=25918 Created: Mar 19, 2000 Modified: 2000-08-13 16:39:20.301 Author: Dieter Wimberger (http://www.jguru.com/guru/viewbio.jsp?EID=25708) Question originally posed by John Collins (http://www.jguru.com/guru/viewbio.jsp?EID=21866 I think this depends a lot on the JDK you are using to run your Servlet Engine. • •
Platform 2 (JDK 1.2, 1.3): take a look at the security policy. Refer to the documentation for setting correct java.net.SocketPermission entries, plus maybe File Access Permissions and in some cases ClassLoader permissions. Platform 1 (JDK 1.1.x): The only real way I found to circumvent my problems was to implement my own RMI SecurityManager. Therefore simply extend the java.rmi.RMISecurityManager class and implement your own policy overriding specific permission check methods. Most likely those will be: checkConnect, checkRead, checkWrite. But I suggest to examine the API doc of the RMISecurityManger to find out more.
To set that SecurityManager you have to add following line to your Servlet init() method: //set RMI Security Manager
System.setSecurityManager(new WebSpaceSecurityManager()); Comments and alternative answers
Beware -- some vendors have broken implementations... Author: Jeff Williams (http://www.jguru.com/guru/viewbio.jsp?EID=231946), Oct 19, 2000 Beware -- some vendors have broken implementations of the security manager that will prevent this type of access control from working. If you are running third-party code, you should be aware that it might be able to seriously compromise your server. You have to make sure that the servlet engine and JVM you are using... 1) use a security manager 2) the security manager does something meaningful
3) the security policy is meaningful Try these flags in the command that starts java -Djava.security.manager -Djava. security.policy==.\foo.policy Here's some code I use in the doGet of a TestServlet to test security... try { System.out.println( h2o + "Information..." + h2c ); System.out.println( " Security Manager: " + System.getSecurityManager().getClass().getName() + p ); System.out.println( " ClassLoader: " + this.getClass().getClassLoader() + p ); // weblogic.utils.classloaders.GenericClassLoader gcl = (weblogic.utils.classloaders.GenericClassLoader)this.getClass().getClassLoader(); // gcl.setDebug( true ); System.out.println( " CodeSource: " + this.getClass().getProtectionDomain().getCodeSource().getLocation() + p ); System.out.println( " -- allowed -- " + p ); } catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } /* try { out.println( h2o + "Trying some dangerous J2EE calls..." + h2c ); String hack = request.getParameter( "hack" ); Cookie[] cookies = request.getCookies(); out.println( " -- allowed -- " + p ); int x = 1 + 2 + 3; System.out.println( hack ); // use it int y = 1 + 2 + 3; System.out.println( cookies ); // use it String m = "COOKIE: " + cookies[0]; // use it again cookies = new Cookie[10]; // reset it String n = "COOKIE: " + cookies[5]; // use it again } catch( Exception e ) { out.println( " -- rejected -- " + e.getMessage() + p ); } */ try { );
System.out.println( h2o + "Attempting file write to d:/Java..." + h2c File f = new File( "d:/Java/blah.txt" ); FileWriter fw = new FileWriter( f ); fw.write( "test\n" ); fw.close(); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try { System.out.println( h2o + "Attempting file write to d:/Java/TestServlet..." + h2c ); File f = new File( "d:/Java/TestServlet/blah.txt" ); FileWriter fw = new FileWriter( f ); fw.write( "test\n" ); fw.close(); System.out.println( " -- allowed -- " + p ); } catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try { h2c );
System.out.println( h2o + "Attempting file read to c:/Ntdetect..." + File f = new File( "c:/Ntdetect.com" ); FileReader fr = new FileReader( f ); int c = fr.read(); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try {
System.out.println( h2o + "Attempting file read to c:/weblogic/weblogic.properties..." + h2c ); File f = new File( "c:/weblogic/weblogic.properties" ); FileReader fr = new FileReader( f ); int c = fr.read(); System.out.println( " -- allowed -- " + p ); } catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try { h2c );
System.out.println( h2o + "Attempting to connect to yahoo.com..." + Socket s = new Socket( "yahoo.com", 8080 ); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try { h2c );
System.out.println( h2o + "Attempting to connect to hacker.com..." + Socket s = new Socket( "hacker.com", 8080 );
System.out.println( " -- allowed -- " + p ); } catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try { h2c );
System.out.println( h2o + "Attempting to listen on port 37337..." + ServerSocket s = new ServerSocket( 37337 ); Socket c = s.accept(); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try { System.out.println( h2o + "Attempting to listen on port 7001..." +
h2c );
ServerSocket s = new ServerSocket( 7001 ); Socket c = s.accept(); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } /* try { System.out.println( h2o + "Attempting native call..." + h2c ); native0( 1 ); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } */ try { System.out.println( h2o + "Attempting exec..." + h2c ); Runtime.getRuntime().exec( "dir" ); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); } try {
System.out.println( h2o + "Attempting system exit..." + h2c ); System.exit( 3 ); System.out.println( " -- allowed -- " + p );
} catch( Exception e ) { System.out.println( " -- rejected -- " + e.getMessage() + p ); }
System.out.println("