Just wanted to check this one before I raise a JIRA, in case it's known
and/or already been fixed or being worked on.
In one of our models we provision our application over WebStart, which
causes bundles to be loaded over HTTP. Occasionally we get a Stream
Closed exception being thrown from the Jetty HTTP server (the server
serving up the code is also running under Felix).
What seems to happen is a double close of the input stream - which
throws an error. I've include the notes below from our developer who
found this.
It's a pretty simple mod to ignore the exception on second close
(highlighted red below) - assuming everyone is happy this is an ok approach.
-- Rob
===
/It turns out the problem was arising when caching the VersaTest jar
files. Whilst they are coming across via WebStart ok, an error was being
thrown because the stream used to read them was being closed multiple
times and at some point the close operation causes an exception that
isn't caught so stops the load. This error occurs in Felix in the
JarRevision class, in the initialize() method. I put a simple fix in
that ignored the error on close. So in the code below, a close on the
input stream was being called in the //BundleCache.copyStreamToFile(is,
m_bundleFile) and in the bottom finally block (you can see below where
I put in that disregarding catch. (Note, I suspect that also the input
stream could be closed in the //((HttpURLConnection) conn).disconnect()
//as well. But it is explicitly closed in the copyStreamToFile.)////
///
if (!byReference)
{
URLConnection conn = null;
try
{
if (is == null)
{
// Do it the manual way to have a chance to
// set request properties such as proxy auth.
URL url =
BundleCache.getSecureAction().createURL(
null, getLocation(), null);
conn = url.openConnection();
// Support for http proxy authentication.
String auth = BundleCache.getSecureAction()
.getSystemProperty("http.proxyAuth", null);
if ((auth != null) && (auth.length() > 0))
{
if ("http".equals(url.getProtocol()) ||
"https".equals(url.getProtocol()))
{
String base64 =
Util.base64Encode(auth);
conn.setRequestProperty(
"Proxy-Authorization", "Basic " + base64);
}
}
is = BundleCache.getSecureAction()
.getURLConnectionInputStream(conn);
}
// Save the bundle jar file.
BundleCache.copyStreamToFile(is, m_bundleFile);
}
finally
{
// This is a hack to fix an issue on Android, where
// HttpURLConnections are not properly closed.
(FELIX-2728)
if ((conn != null) && (conn instanceof
HttpURLConnection))
{
((HttpURLConnection) conn).disconnect();
}
}
}
}
}
finally
{
if (is != null)
{
try
{
is.close();
} catch (IOException ioe)
{
/* Catch and disregard exception on close as could
already have been closed,
either in the disconnect or in the
copyStreamToProfile
*/
}
}
}
--
Ascert - Taking systems to the edge
[email protected]
www.ascert.com