You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Peter Jones <pe...@sun.com> on 2007/01/16 22:26:05 UTC

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

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