Java RMI not closing socket after lease expiration

My RMI enabled application seems to be leaking sockets. I have a Java application providing a service over RMI. It is using the Java SE 1.6 RMI implementation running on Linux. The problem I am observing is that if a client obtains a reference to my Remote object, using the Registry, and then the connection is severed abruptly (power loss, cable unplugged, etc...), the server keeps the socket open. I would expect the RMI implementation to clean up after the client's lease expires, but that is not happening. On the server, my Remote object's unreferenced() method is called when the lease expires, but the socket remains visible in netstat in the "ESTABLISHED" state indefinitely.

Since we are not able to force the clients into any specific behavior, after several days we are hitting the default limit, 1024 in our Linux distro, for open file descriptors, causing the server to become unable to open any new sockets or files. I thought about TCP keepalives, but since RMI is abstracting away the network layer, I don't have access to the actual server socket after the connection has been established.

Is there any way to force the RMI layer to cleanup sockets tied to client connections with expired leases?

Update: The solution I used is similar to the chosen answer, but uses a different approach. I used a custom socket factory, and then wrapped the ServerSocket instance returned by createServerSocket() in a transparent wrapper that passed all methods through, except for accept(). In the accpet method, keepalives are enabled before the socket is returned.

public class KeepaliveSocketWrapper extends ServerSocket
{
    private ServerSocket _delegate = null;
    public KeepaliveSocketWrapper(ServerSocket delegate)
    {
        this._delegate = delegate;
    }

    public Socket accept() throws IOException
    {
        Socket s = _delegate.accept();
        s.setKeepAlive(true);
        return s;
    }
    .
    .
    .
}


Asked by: Thomas525 | Posted: 21-01-2022






Answer 1

public class MySocketFactorySettingKeepAlive ... {
  // overwrite createSocket methods, call super.createSocket, add keepAlive
}

Socket.setSocketImplFactory(youFactoryDemandingKeepAlive);

and then just use RMI.

The trick, if I remember right, is to manage to set the factory before the system opens first socket -- Java disallows to overwrite the factory; in worst case, use reflection to overwrite it :))) (kidding; would be a hack)

Also, you may need to allow specific operation in SecurityManager.

Answered by: Nicole422 | Posted: 22-02-2022



Similar questions

java - Wicket session Expiration

i am using a class for session which extends org.apache.wicket.protocol.http.WebSession; i need a method to be called when this session expires as a consequence of logging out or time out. but i have found nothing. How can i do it?


java - How to test expiration conditions?

I'm developing a component that provides tokens that have a limited lifespan and need not be persisted in case of application restart. Hence, the tokens are only stored in memory. Each token is identified by a key and have an associated time-to-live after which the token expires and can no longer be used. I halted to think how would you go about testing that the expiration conditions work as planned?


java - How to set different expiration timeout for each new map entry using Google Guava?

Google guava allows to set expiration timeout for each map enty using CacheBuilder. However I want to set different timeout for each new enty. Is is possible?


sockets - Get a Domains Expiration date using Java

I am working on an application that is suppose to return the expiration date of a Domain name. I used the getExpiration() but it keeps returning 0 for any site that I plug in. EX: www.google.com expires 2020-09-13, but when I run my code it returns 0 meaning it's not known. Does anyone know of any other methods to get the expiration date of a Domain name? Any help would be greatly appreciated. try {...


java - Auto expiration of messages in Camel

I have a system implementing Camel and ActiveMQ for communication between some servers. I would like to know if there is a way to automatically expire and clear-out messages sent to a queue after X period of time. Since the originating server (filling the queue) wont know if anyone is picking up the messages, I don't want my queue to grow until its so large that something crashes. Bonus karma points to someone who can help...


java - Liferay: expiration date for messages (message board)

Am I just missing something obvious, or is there no reasonable or halfway feasible way to add an expiration date to messages in Liferay's message board? The first problem is how to enter the expiration date in the message editor. The most obvious solution is perhaps an expando attribute, but there seem to be no expando data type for dates (only date & time) and I find no way to set a calculated default value in...


java - Specifying Column Expiration with TTL in cassandra

when i insert value with TTL column expiration it gives me some unexpected output public static void setTTL() { try { Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver"); Connection con = DriverManager.getConnection("jdbc:cassandra://192.168.1.32/temp"); String qry = "INSERT INTO userscql3(user_name,password)VALUES('yogesh','temp@123') USING...


java - Absolute session expiration after N minutes even if user is using the system

I’m working on a grails web application with spring security. I have a requirement for forcing a session expiration after a fixed set of time even if the session is active. I think I can add filter and check for each request's last login time: if (CURRENT_TIME - LAST_LOGIN > ABSOLUTE_SESSIO EXPIRATION) then FORCE LOGOUT But the problem is that the session is still active on th...


java - How to manage HTTP cache expiration from a suite of REST services

I have 30 REST services implemented in Java on the server side of a web app. They all have hard coded cache expiration settings that are put into the HTTP response headers. What is the best practice to manage these settings? keep them hard coded? have a config file to manage the settings if they need to change? keep them in a DB table by service name? are there existing frameworks...


java - JRE Expiration Date

What is JRE Expiration Date set to 07/18/2013 in release notes of Java Runtime Environment version 7u21? JRE 7u21 release notes






Still can't find your answer? Check out these amazing Java communities for help...



Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)



top