jxmapviewer2
jxmapviewer2 copied to clipboard
Cache Input Stream can leak resources
When running offline, panning and zooming causes tiles to try and load however connection.getInputStream()
throws an UnknownHostException. If the user keeps trying to load new tiles eventually it throws a SocketException - too many open files (even if the network later comes back online, tiles no longer load and throw this exception, see below). I suspect url.openConnection() needs to be closed (closing the input stream does this automatically).
Some info from the web suggests casting the URLConnection to HttpURLConnection, and checking that a call to its getResponseCode() method == HTTP_OK. Also in any case a finally clause to its disconnect() method.
java.net.SocketException: Too many open files
at java.base/java.net.Socket.createImpl(Socket.java:546)
at java.base/java.net.Socket.connect(Socket.java:647)
at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:290)
at java.base/sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:173)
at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:182)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:474)
at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:569)
at java.base/sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:265)
at java.base/sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:372)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:177)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1194)
at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1082)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:163)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1595)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1523)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:224)
at org.jxmapviewer.viewer.AbstractTileFactory$TileRunner.cacheInputStream(AbstractTileFactory.java:433)
As it turns out, this is not a bug per se, but occurs because the java.net.Socket is opening a native resource (socket handle) and apparently it does not release the native resource until it is garbage collected. In my case I guess the GC was not running often enough to avoid the issue.
My solution is to keep track of a count of tiles that fail to load. When it reaches some threshold I call System.gc()
. I know its not advisable to be calling this but it does solve the problem.
Similar issue posted here: https://stackoverflow.com/questions/15917383/java-net-unknownhostexception-and-java-net-socketexception-too-many-open-files/64344960#64344960