You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Mark Brouwer <ma...@cheiron.org> on 2007/01/09 20:48:25 UTC

Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

One of the next features of Seven I'm working on is the ability of a
service to keep access to all download JAR files as seen be a service
during its life-time, including restarts of the service and/or container.

This should lead to:

   - increased reliability of codebase annotations, especially handy when
     persisting marshalled objects;
   - faster startup times (also see Gregg's requirements for vhttp);
   - less bandwidth usage;
   - statistics about the usage of downloadable code by a service;
   - if you ever want to move a service from one container to another
     you can move its downloadable code dependencies with it.

This works because Seven uses specialized jar protocol handlers that are
used for all the class loaders created by PreferredClassProvider, it
also works for each protocol used in codebase annotations.

So far this work nice, there is however one spoiler and that is the
current implementation of net.jini.loader.pref.PreferredClassLoader as
this one performs always a direct check against the first URL to see
whether the there is a PREFERRED.LIST for reasons as stated by inline
comments:

   * First determine if the JAR file exists by attempting to
   * access it directly, without using a "jar:" URL, because
   * the "jar:" URL handler can mask the distinction between
   * definite lack of existence and less definitive errors.
   * Unfortunately, this direct access circumvents the JAR
   * file caching done by the "jar:" handler, so it ends up
   * causing a duplicate request of the JAR file on first
   * use.  (For HTTP-protocol URLs, the initial request will
   * use HEAD instead of GET.)

First can somebody shed me light how a typical jar: handler can mask the
distinction between definite lack of existence and less definite errors.

I'm not that concerned about the performance implications though the
current implementation defeats "increased reliability of codebase
annotations", I don't have a solution in mind yet, but I would like to
see a way to be able to get what I want without completely overriding
the protected method isPreferredResource(String, boolean).
-- 
Mark

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Mark Brouwer <ma...@cheiron.org>.
Hi Dan,

Dan Creswell wrote:
> Hi Mark,
> 
> Not sure I understand exactly where you are going so how about one of my
> patent-pending dumb questions:
> 
> How is this different from me ensuring that each service I deploy has,
> in the same JVM an http server to serve the .jars on it's codebase?

I try to implement reliability features in Seven that work independent
of the way the (external) service used by other services/clients
deployed in Seven are implemented/deployed. Although the speed increase
I experienced with some tests over the Internet made me a very happy
person :-)

Also deploying an internal JAR file server as part of the same JVM as
your service is deployed within has its own drawbacks, as that JAR file
server might have served JAR files that are being used for other
purposes than just remote communication with a service. Bringing your
JVM down will also harm those that have created dependencies on those
JAR files [1], and don't forget about that just wipe JAR files once
served from their file system.

> Essentially, that would mean that if I could reach the service, I could
> get it's .jars.  If I can't do that, I have to go get some other service.

While that is indeed a common approach, sometimes you have a reference
to a service that you can't easily swap for another, e.g. when you are
in the middle of a 2-phase transaction and something happens.

> Does it just come down to .jar caching in clients/other services for
> purposes of speed etc?

Nope, I hoped that was clear from my listing of benefits from this
approach, the posting is mainly with regard to reliability.

But to add some more language, though will keep it short. We all know
that downloadable code is a gift and a curse at the same time. I'm
trying very hard with Seven to solve some of the problems associated
with that by making evolution of services possible over a long time span
for some use cases. Although not everything will be possible due to some
of the problems outlined by Michael Warres' "Class Loading Depression in
Java™ RMI and Jini Network Technology".

But a case I've run into often is that we persisted object in marshalled
form, e.g. an object that represents a specialized proxy to a
transaction service and that we had failures due to codebase unavailability.

Assume the transaction server is down for whatever reason as well as its
codebase server. Upon retrieval of the specialized proxy I will get a
ClassNotFoundException without the cache, and the specialized proxy with
the cache in place assuming a different implementation of
PreferredClassLoader.

The ClassNotFoundException I will likely see as a definite exception and
that means I have a much bigger problem than with a specialized proxy in
my hand that throws a ConnectException [2].

[1] the next feature I'm working on is prefetching of download JAR files
that are listed in the Class-Path entry of the MANIFEST.MF to increase
reliabilty for those JAR files that have not been requested by the class
loader as result of the usage at runtime.

[2] another request to increase reliability in certain scenarios I will
post shortly, as often I've been confronted by a NoSuchObjectException
what many people consider a definite exception for which I would have
liked to throw a different exception under some conditions.
-- 
Mark

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Dan Creswell <da...@dcrdev.demon.co.uk>.
Hi Mark,

Not sure I understand exactly where you are going so how about one of my
patent-pending dumb questions:

How is this different from me ensuring that each service I deploy has,
in the same JVM an http server to serve the .jars on it's codebase?

Essentially, that would mean that if I could reach the service, I could
get it's .jars.  If I can't do that, I have to go get some other service.

Does it just come down to .jar caching in clients/other services for
purposes of speed etc?

Interesting,

Dan.

Mark Brouwer wrote:
> One of the next features of Seven I'm working on is the ability of a
> service to keep access to all download JAR files as seen be a service
> during its life-time, including restarts of the service and/or container.
> 
> This should lead to:
> 
>   - increased reliability of codebase annotations, especially handy when
>     persisting marshalled objects;
>   - faster startup times (also see Gregg's requirements for vhttp);
>   - less bandwidth usage;
>   - statistics about the usage of downloadable code by a service;
>   - if you ever want to move a service from one container to another
>     you can move its downloadable code dependencies with it.
> 
> This works because Seven uses specialized jar protocol handlers that are
> used for all the class loaders created by PreferredClassProvider, it
> also works for each protocol used in codebase annotations.
> 
> So far this work nice, there is however one spoiler and that is the
> current implementation of net.jini.loader.pref.PreferredClassLoader as
> this one performs always a direct check against the first URL to see
> whether the there is a PREFERRED.LIST for reasons as stated by inline
> comments:
> 
>   * First determine if the JAR file exists by attempting to
>   * access it directly, without using a "jar:" URL, because
>   * the "jar:" URL handler can mask the distinction between
>   * definite lack of existence and less definitive errors.
>   * Unfortunately, this direct access circumvents the JAR
>   * file caching done by the "jar:" handler, so it ends up
>   * causing a duplicate request of the JAR file on first
>   * use.  (For HTTP-protocol URLs, the initial request will
>   * use HEAD instead of GET.)
> 
> First can somebody shed me light how a typical jar: handler can mask the
> distinction between definite lack of existence and less definite errors.
> 
> I'm not that concerned about the performance implications though the
> current implementation defeats "increased reliability of codebase
> annotations", I don't have a solution in mind yet, but I would like to
> see a way to be able to get what I want without completely overriding
> the protected method isPreferredResource(String, boolean).


Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Peter Jones <pe...@sun.com>.
On Tue, Jan 23, 2007 at 12:16:06PM +0100, Mark Brouwer wrote:
> Peter Jones wrote:
> 
>> The biggest concern that I can think of right now, which would argue
>> for this approach being only optionally enabled, is that it would
>> deoptimize (with respect to the current implementation) the case of
>> the first URL in the codebase pointing to a JAR file that definitely
>> does not exist, which (as previously described) is not intended to
>> necessarily result in an overall class/resource loading failure.  Not
>> that the importance of that case is obvious...
> 
> I think you shouldn't have made that last remark ... It will be hard to
> tell the overall effect but for now I make it optionally. If somebody
> else has a take on this please mention it.

My wording and ellipsis were admittedly vague-- I was actually about
to write that it didn't seem worthwhile to me to bother making the
proposed behavior conditional on a system property, and then I thought
of the above case and decided to mention it for the record.  But even
though it is "the biggest concern that I can think of right now", I'm
not currently seeing it as big enough to worry about.

-- Peter

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Gregg Wonderly <gr...@wonderly.org>.
Mark Brouwer wrote:
> Peter Jones wrote:
> 
>> Ah, OK, now I understand your proposal.
> 
> 
> I'm glad Peter :-)
> 
>> The biggest concern that I can think of right now, which would argue
>> for this approach being only optionally enabled, is that it would
>> deoptimize (with respect to the current implementation) the case of
>> the first URL in the codebase pointing to a JAR file that definitely
>> does not exist, which (as previously described) is not intended to
>> necessarily result in an overall class/resource loading failure.  Not
>> that the importance of that case is obvious...
> 
> I think you shouldn't have made that last remark ... It will be hard to
> tell the overall effect but for now I make it optionally. If somebody
> else has a take on this please mention it. I will create a JIRA issue
> for this improvement soon.

I think that the behavior of fallback URLs is useful.  Given the framework that 
exists, I think that the current implementation is applicable.  But, I also 
think that making this a more described behavior in a new platform 
RMIClassLoaderSPI implementation with different annotations would also be 
something to investigate.  That SPI would perhaps be incompatible with existing 
MarshalledObject annotation formats, so it would be equivalent to using a custom 
URL protocol handler from the perspective that you'd have to have support for it 
everywhere that your codebase URLs went.

Gregg Wonderly

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Gregg Wonderly <gr...@wonderly.org>.
Mark Brouwer wrote:
> Gregg Wonderly wrote:
>> Let me try with different words...
>
> Ok I understand where you want to go to, however there was a thread
> during the Davis project which I'm unfortunately can't refer to as the
> archives have been closed, where I also referred to the current
> semantics for having the requirement of PREFERRED.LIST in the first JAR
> file. I attached my post and the responses of Peter and Laird Dornin for
> completeness.
> 
> There is an issue in the Sun bug database
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4302427 that suggest
> that the fallback behavior you are referring to in itself is a bug.

The failover behavior, is something that I desire to be possible.  The current 
"glib" as Laird put it behavior of URLClassLoader, is probably not the right way 
to do it, considering the case where you've purposely put a codebase component 
in front of another to avoid using classes in the following component.  In other 
cases, where you might compose

	http://host1:8090/jarv2-dl.jar http://host1:8090/jarv1-dl.jar

to say you prefer the use of v2, but if it's not present than v1 is okay, and 
then in a deployment, delete v2 because the customer hasn't paid for the upgrade 
  yet, that, is a different issue.

I'm all for improvements.  I just don't think that the simple string annotation 
structure that we have now, is capable of documenting the deployers true intent.

Making alterations to limit exploitations as I've enumerated above, would be 
acceptable to me because I don't do any of these things, because I don't find 
the behavior dependable.

It's that dependable behavior that I think would be something to create, if 
anything really needs to be done with annotations.

Gregg Wonderly

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Mark Brouwer <ma...@cheiron.org>.
Gregg Wonderly wrote:
> Mark Brouwer wrote:
>> Gregg Wonderly wrote:
>>> I think that the behavior of fallback URLs is useful.  Given the 
>>> framework that
>>> exists, I think that the current implementation is applicable.  But, 
>>> I also
>>
>> I've a bit of a problem positioning your language Gregg due to the words
>> fallback and framework, but are you suggesting the new behavior should
>> be conditionally. Note that as far as I can tell the only
>> de-optimization is the one Peter will be remembered for the rest of his
>> life.
> 
> Let me try with different words...

Ok I understand where you want to go to, however there was a thread
during the Davis project which I'm unfortunately can't refer to as the
archives have been closed, where I also referred to the current
semantics for having the requirement of PREFERRED.LIST in the first JAR
file. I attached my post and the responses of Peter and Laird Dornin for
completeness.

There is an issue in the Sun bug database
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4302427 that suggest
that the fallback behavior you are referring to in itself is a bug.

Based on the current semantics of PreferredClassLoader the proposed
change doesn't alter its behavior.

> If there are multiple URLs in the codebase, and two or more actually 
> points at the same content, then one of those URLs can be considered 
> "fallback" URLs. I.e. if one URL is not accessible, the client will 
> hopefully be able to load code from another.  Thus, the failure handling 
> associated with "JAR not accessible" as opposed to "PREFERRED.LIST" not 
> present is important.  Also, the location that the PREFERRED.LIST comes 
> from is important.

> You are familiar with XML based configuration.  Imagine that you could 

Is that a complement Gregg ;-) I think we should start a separate thread
on improvements of codebase annotation for it seems you just want to
have a complete new protocol handler Gregg that solves many issues
around mobile code, but I think I leave it up to others who have done
their fair share of research/thinking to comment on this first.
-- 
Mark


Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Gregg Wonderly <gr...@wonderly.org>.
Mark Brouwer wrote:
> Gregg Wonderly wrote:
>> I think that the behavior of fallback URLs is useful.  Given the 
>> framework that
>> exists, I think that the current implementation is applicable.  But, I 
>> also
>
> I've a bit of a problem positioning your language Gregg due to the words
> fallback and framework, but are you suggesting the new behavior should
> be conditionally. Note that as far as I can tell the only
> de-optimization is the one Peter will be remembered for the rest of his
> life.

Let me try with different words...

If there are multiple URLs in the codebase, and two or more actually points at 
the same content, then one of those URLs can be considered "fallback" URLs. 
I.e. if one URL is not accessible, the client will hopefully be able to load 
code from another.  Thus, the failure handling associated with "JAR not 
accessible" as opposed to "PREFERRED.LIST" not present is important.  Also, the 
location that the PREFERRED.LIST comes from is important.

You are familiar with XML based configuration.  Imagine that you could send an 
XML document at the codebase which said something like:

<codebase>
     <entry>
	<source path="/reggie-dl.jar" host="srv1" port="8090"
		protocol="vhttp,http"
		preferredSource="true"/>
	<source prefurl="vhttp://srv2:8090/reggie-dl.jar"
		alturl="http://srv2:8090/reggie-dl.jar"
		preferredSource="true"/>
     </entry>
     <entry>
         <!-- Never prefer these classes, but make them available for
              loading if needed -->
	<source prefurl="http://srv1:8090/jsk-dl.jar"
		/>
	<source prefurl="http://srv2:8090/jsk-dl.jar"
		/>
     </entry>
</codebase>

The above is an example of different formats to just show structure and 
potential options, not to indicate what should happen in practice.  By creating 
a structured specification, we could ammend the codebase annotation over time so
that specific application needs might be customized with interoperability still 
allowed.  The issues that I'm thinking about are:

o  Where should a preferred list be found?
o  Can we specify multiple urls with different protocols to provide for
    different qualities of service?
o  What order are the codebase entries searched?
o  How do you specify backup/fallback codebase entries?

There's other types of things that I've mulled over too.  This is basically what 
I was thinking about in my original comment.

As soon as the codebase has some kind of structure like this, then an 
appropriate RMIClassLoaderSPI will have to be present on the receiving end in 
particular, to deal with this.  Because of my use of vhttp: in codebase URLs, I 
understand the issue of having special setup required on all ends to make use of 
such customizations.

Gregg Wonderly

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Mark Brouwer <ma...@cheiron.org>.
Gregg Wonderly wrote:

> I think that the behavior of fallback URLs is useful.  Given the 
> framework that
> exists, I think that the current implementation is applicable.  But, I also

I've a bit of a problem positioning your language Gregg due to the words
fallback and framework, but are you suggesting the new behavior should
be conditionally. Note that as far as I can tell the only
de-optimization is the one Peter will be remembered for the rest of his
life.

> think that making this a more described behavior in a new platform
> RMIClassLoaderSPI implementation with different annotations would also be
> something to investigate.  That SPI would perhaps be incompatible with 
> existing
> MarshalledObject annotation formats, so it would be equivalent to using 
> a custom
> URL protocol handler from the perspective that you'd have to have 
> support for it
> everywhere that your codebase URLs went.

One thing at a time Gregg ;-) but if I interpreted the above correct I
think this change has no impact on whatever protocol handler will be
used in the future as it is really tied to the "jar:" protocol handler.
-- 
Mark

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Gregg Wonderly <gr...@wonderly.org>.
Mark Brouwer wrote:
> Peter Jones wrote:
> 
>> Ah, OK, now I understand your proposal.
> 
> 
> I'm glad Peter :-)
> 
>> The biggest concern that I can think of right now, which would argue
>> for this approach being only optionally enabled, is that it would
>> deoptimize (with respect to the current implementation) the case of
>> the first URL in the codebase pointing to a JAR file that definitely
>> does not exist, which (as previously described) is not intended to
>> necessarily result in an overall class/resource loading failure.  Not
>> that the importance of that case is obvious...
> 
> I think you shouldn't have made that last remark ... It will be hard to
> tell the overall effect but for now I make it optionally. If somebody
> else has a take on this please mention it. I will create a JIRA issue
> for this improvement soon.

I think that the behavior of fallback URLs is useful.  Given the framework that
exists, I think that the current implementation is applicable.  But, I also
think that making this a more described behavior in a new platform
RMIClassLoaderSPI implementation with different annotations would also be
something to investigate.  That SPI would perhaps be incompatible with existing
MarshalledObject annotation formats, so it would be equivalent to using a custom
URL protocol handler from the perspective that you'd have to have support for it
everywhere that your codebase URLs went.

Gregg Wonderly


Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Bob Scheifler <Bo...@Sun.COM>.
> It will be hard to
> tell the overall effect but for now I make it optionally. If somebody
> else has a take on this please mention it. I will create a JIRA issue
> for this improvement soon.

An intentionally non-existent first URL doesn't seem like an important
use case to me, I'd be inclined to avoid a new system property.

- Bob

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Mark Brouwer <ma...@cheiron.org>.
Peter Jones wrote:

> Ah, OK, now I understand your proposal.

I'm glad Peter :-)

> The biggest concern that I can think of right now, which would argue
> for this approach being only optionally enabled, is that it would
> deoptimize (with respect to the current implementation) the case of
> the first URL in the codebase pointing to a JAR file that definitely
> does not exist, which (as previously described) is not intended to
> necessarily result in an overall class/resource loading failure.  Not
> that the importance of that case is obvious...

I think you shouldn't have made that last remark ... It will be hard to
tell the overall effect but for now I make it optionally. If somebody
else has a take on this please mention it. I will create a JIRA issue
for this improvement soon.

What would a decent property name be for this one given the current
naming convention of the Jini team.
-- 
Mark

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Peter Jones <pe...@sun.com>.
On Wed, Jan 17, 2007 at 10:13:54AM +0100, Mark Brouwer wrote:
> 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.

Ah, OK, now I understand your proposal.

> 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.

The biggest concern that I can think of right now, which would argue
for this approach being only optionally enabled, is that it would
deoptimize (with respect to the current implementation) the case of
the first URL in the codebase pointing to a JAR file that definitely
does not exist, which (as previously described) is not intended to
necessarily result in an overall class/resource loading failure.  Not
that the importance of that case is obvious...

>> 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.

OK, thanks for the evaluation.

-- Peter

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Mark Brouwer <ma...@cheiron.org>.
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

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Peter Jones <pe...@sun.com>.
On Thu, Jan 11, 2007 at 11:02:42PM +0100, Mark Brouwer wrote:
> Bob Scheifler wrote:
>>> First can somebody shed me light how a typical jar: handler can mask the
>>> distinction between definite lack of existence and less definite errors.
>> 
>> Peter may need to correct me, but I believe the problem is that you
>> can't rely on being able to use the IOException thrown to determine
>> the category (vs getPreferredConnection using the actual HTTP
>> response code to make the category distinction).
> 
> Thanks for responding Bob,
> 
> I see, what would be the problem with checking against the JAR file
> itself first through a URL such as:
> 
>    jar:http://host/download.jar!/
> 
> In case the URLConnection returned for this URL throws *no* IOException
> you can assume (?) the JAR file is localy available [1]. A next check
> could be whether there is an entry named PREFERRED.LIST by creating a
> URLConnection for the URL:
> 
>   jar:http://host/download.jar!/META-INF/PREFERRED.LIST
> 
> Probably I still miss something in the bigger picture that explains the
> current implementation.

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.

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).
The PreferredClassLoader logic in question was added as part of the
fix for the following bug (this was back when PreferredClassLoader was
still transitioning out of JDK 1.4 itself):

	http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408449

(although the text of that bug report doesn't necessarily illuminate
the particular issues behind that logic).

-- Peter

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Mark Brouwer <ma...@cheiron.org>.
Bob Scheifler wrote:
>> First can somebody shed me light how a typical jar: handler can mask the
>> distinction between definite lack of existence and less definite errors.
> 
> Peter may need to correct me, but I believe the problem is that you
> can't rely on being able to use the IOException thrown to determine
> the category (vs getPreferredConnection using the actual HTTP
> response code to make the category distinction).

Thanks for responding Bob,

I see, what would be the problem with checking against the JAR file
itself first through a URL such as:

    jar:http://host/download.jar!/

In case the URLConnection returned for this URL throws *no* IOException
you can assume (?) the JAR file is localy available [1]. A next check
could be whether there is an entry named PREFERRED.LIST by creating a
URLConnection for the URL:

   jar:http://host/download.jar!/META-INF/PREFERRED.LIST

Probably I still miss something in the bigger picture that explains the
current implementation.

[1] I think the assumption that any remote JAR file will be locally
cached is fair
-- 
Mark

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Gregg Wonderly <gr...@wonderly.org>.
Bob Scheifler wrote:
>> First can somebody shed me light how a typical jar: handler can mask the
>> distinction between definite lack of existence and less definite errors.
> 
> 
> Peter may need to correct me, but I believe the problem is that you
> can't rely on being able to use the IOException thrown to determine
> the category (vs getPreferredConnection using the actual HTTP
> response code to make the category distinction).

I'd guess that there is no distinction in what FileNotFoundException means.  It 
might mean that the Jar is not there, but can also mean that a resource in the 
jar is not there.

Is that what you are referring to Bob?

Gregg Wonderly

Re: Change for PreferredClassLoader its way of determining the existence of PREFERRED.LIST ?

Posted by Bob Scheifler <Bo...@Sun.COM>.
> First can somebody shed me light how a typical jar: handler can mask the
> distinction between definite lack of existence and less definite errors.

Peter may need to correct me, but I believe the problem is that you
can't rely on being able to use the IOException thrown to determine
the category (vs getPreferredConnection using the actual HTTP
response code to make the category distinction).

- Bob