Peter Jones wrote:

What is not obvious from your above prescription is, in the event that
the attempt to retrieve the first URL throws an IOException, whether
PreferredClassLoader.isPreferredResource should return false or throw
an IOException.  If the failure indicates that that referenced JAR
file itself definitely does not exist (like because the HTTP server
responded with 404), then isPreferredResource should return false, so
that class loader delegation can proceed.  But if the failure is less
definite about the JAR file's existence, then isPreferredResource
should throw an IOException, because perhaps it was the deployer's
intention that the class or resource be preferred and thus it would be
wrong for class loader delegation to succeed just because of a
transient communication failure.

Thank Peter,

I agree with the current conclusions made by the code in
PreferredClassLoader so I don't want to change that behavior. What I
would like to add (and not replace) is some logic that would try first
to get a definite answer about the existence of a PREFERRED.LIST that
doesn't by-pass a JAR file cache (i.e. use the "jar:" protocol). If that
succeeds we are happy (see below), if it doesn't succeed we fall back to
the current logic.

Succeeding is defined as JarURLConnection.getManifest() for the URL
jar:http://host/download.jar!/ *not* throwing an IOException, result can
either be a Manifest object or null.

When JarURLConnection.getJarEntry() for the URL
jar:http://host/download.jar!/META-INF/PREFERRED.LIST throws a
FileNotFoundException we know for sure that there is no PREFERRED.LIST
(the first call succeeding that means the JAR file is locally available
as result of the caching behavior, that means that a
FileNotFoundException indicates the entry is missing).

I don't have any problem if this added logic is only activated through
the use of some system/security property, because in my environment
(Seven) I know the exact behavior of the "jar:" protocol handler as well
as behavior of the cache.

I don't recall the details offhand (is Laird subscribed to this
list?), but I believe that the general problem was that information
necessary to make this decision was not exposed when using a "jar:"
URL, at least for the JDK implementations of the time (early 1.4).

I just looked at my "jar:" protocol implementation and that one also
throws FileNotFoundException in both cases, i.e. when the JAR file can't
be found, or when the JAR file can be found but the entry is missing. I
believe this behavior is demanded by the semantics for JarURLConnection
as you are only allowed to return null for getJarEntry in case the JAR
URL points to a JAR file itself and not an entry. So it is safe to
assume that nothing happened since that day.
--
Mark

Reply via email to