ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stephen McConnell" <mcconn...@dpml.net>
Subject RE: Resource.getURL()
Date Sat, 23 Sep 2006 03:57:19 GMT
 

> -----Original Message-----
> From: Scott Stirling [mailto:scottstirling@gmail.com] 
> Sent: Friday, 22 September 2006 11:58 PM
> To: Ant Developers List
> Subject: Re: Resource.getURL()
> 
> DD asks:
> > > Does that play well with application containers that 
> often embed Ant?
> 
> Stephen McConnell replies, in part:
> > Something to keep in mind is that the creation of a URL is handled 
> > inside the system classloader.  As such when the JVM attempts to 
> > locate handler classes, it is limited to classes that exist 
> > within the system classloader or system extensions. 
> > Application normally deal with this constraint be ensuring 
> > that the jar file containing protocol handlers is included in 
> > system classloader or is installed as a JVM extension - 
> > however, an alternative is to deploy a JVM with 
> > a mutable system classloader.
> 
> What do you guys mean by "mutable system classloader?" This 
> is intriguing but also smells suspicious to me, having worked 
> with classloaders quite a bit over the years.

A URL is constructed using the java.net.URL class [1] using something like
new URL( path ).  This creates an instance of URL with the supplied
arguments as the instance state.  When a client invokes something like
url.openConnection() to establish the connection object (which is trigger by
things like url.getContent() and url.openStream()), the url implementation
has to locate a URLConnection [2] that knows about the url protocol.  If the
protocol is one of the standard protocols that ships with a JVM then
everything works as expected.  If the protocol is a custom protocol then the
JVM has to find a URLStreamHandler [3] class that will do the work of
creating the dedicated URLConnection instance.  If the
URLStreamHandlerFactory exists and the protocol is supported then again -
everything works as expected, otherwise a URLStreamHandler instance will be
instantiated based on the handler path and protocol name strategy I
mentioned earlier - in which case the class must exist in the system
classloader.

Normally the existence of a handler in the system classloader is not a
problem for an application because the system classloader is generally
configurable based on the application launch parameters, however, in the
case of Ant we need to deal with the possibility for the declaration of a
custom handler at the level of a build file.  In this scenario the classes
containing the protocol handler need to be added to the system classloader -
hence the requirement for dynamic mutation of system classloader state. 

Actual mutation of the system classloader can be handled with relative
safety in JRE 1.4 and later via a system property 'java.system.class.loader'
but Ant is backward compatible relative to JRE 1.2 which precludes the
possibility for using this approach. As a consequence the strategy used in
the examples I've seen on the dev list are focussed on reflective invocation
of the addURL method (and thereby bypassing the package protection on that
method which has a certain smell about it but the smell is understandable
given the 1.2 constraint).


> > > > Enabling the declaration of custom protocol 
> > > > handlers as a part of system classloader 
> > > > expansion would significantly simply things for 
> > > > applications such as Depot (which makes extensive 
> > > > use of custom handlers).
> 
> Custom protocol handlers can, I know because I've done it, be 
> handled in another way by building up support for them at the 
> application layer. For example (from a an XML file for 
> location metadata:
> 
> <map src="cp:maps/first-floor.png"
>          xSize="300" ySize="500" name="First Floor"/>
> 
> That src="cp:maps/first-floor.png" is handled in code that 
> interprets any src attribute value beginning with "cp:" as a 
> pointer to a resource that should be loaded from the 
> classpath (the cp). This was added to support loading maps in 
> a JUnit test context. When the "cp:"
> prefix is not present, the resource is interpreted as a file 
> system resource.
> 
> This is a simple example. My point is just that custom 
> protocol handlers could probably be handled as an application 
> layer enhancement, as alternative to leveraging the JVM 
> system settings, which is invasive and inconvenient to 
> deploy, especially in embedded contexts.

The above example is practical in the scenario where the code resolving the
uri knows about the 'cp:' protocol.  The downside of this approach is that
the 'cp' protocol is meaningless outside of that dedicated application.  For
example, if I asked you to replace 'cp:maps/first-floor.png' with
'artifact:png:maps/first-floor' the solution would not work (unless you also
provided a protocol to handler mapping and supporting framework), however,
if the solution were reworked to use the URL handling mechanism then it
would work providing that the 'artifact' [5] protocol handler was resolvable
by the JVM.

> > > > the combination of system classloader mutation plus support for 
> > > > custom URL handlers would contribute to a significant potential 
> > > > simplification of Depot's extensions to the Ant project 
> > > > model and task some task implementations.
> 
> What is Depot?, if you don't mind me asking, late to the discussion.

Depot [4] is a Java application that handles the automatic building of
multiple projects based on a centralized index of project definitions and
dependencies.  When building an individual project is deploys a plugin to
handle the actual build actions (compile, jar, text, etc).  Depot's default
builder is a plugin that constructs an embedded Ant project and delegates
execution to the Ant project instance. Depot used a number of custom
protocol handlers which enable things like the loading of a antlib using a
uri value, the importing of templates, etc. 


> > Custom handlers allow the introduction of alternative 
> > resource identification and retrieval mechanisms.  For 
> > example - data could be referenced using a query 
> > structure expressed as a url and the handler 
> > could use the url to interrogate a remote database.  
> > Another example is multiple remote data sources (as is 
> > the case of the 'artifact' protocol). In these example 
> > the custom URL enables the removal of logic concerning 
> > resource type and associated retrieval mechanics from 
> > application code.  This results in greater portability and 
> > easier long-term maintenance.
> 
> I think you're right. I remember a classic JavaWorld example 
> using the protocol handler API to create one for working with 
> the Windows registry. That said, in the embedded contexts 
> where Ant often runs (IDEs, installers, app servers, other 
> tools), it is arguably much more powerful for Ant to be able 
> to control such things in its application layer rather than 
> depending on system-level JVM configuration.

It is feasible to do this at the application level if Ant maintains a
registry of protocol schemes and associated handlers, and applying new URL(
context, spec, handler ) for all URL instance creation.  This would imply a
overhead on all Ant tools and extensions to use a common URL factory
provided in the Ant core.  The alternative is to use the existing JVM
configuration mechanisms.  Irrespective of the choice - the subject of
system classloader mutation is still a issue when building tasks that need
to customize system behaviour.  

> Where would these protocols appear from a user perspective? 

This is an interesting question.  The subject of this thread places focus on
the revision to the Resource class but raises the overall subject of support
within Ant for custom protocol handlers. My use of custom handlers is mainly
focussed around the loading of plugins (e.g. antlib plus classloader
information), templates, and any resource that is not within a particular
project codebase.  Due to the lack of support in Ant for custom protocol
handlers - there are lots of places in Depot where custom uris are resolved
into local file resources before being applied to Ant tasks (e.g. path
creation, imports, etc.).

> In build scripts? If that's the case, then I'd definitely say 
> consider letting Ant handle them and convert them to standard 
> URLs through a registry mechanism perhaps like the custom 
> task registry.

Ultimately I think there is much to be done in Ant related to moving away
from 'file-centric' towards 'stream-centric' logic and within this context
the subject of protocol handler declaration at the level of Ant should in
principal be nothing more than syntactic sugar over the existing JVM
mechanisms.

Cheers, Steve.

[1] http://java.sun.com/j2se/1.4.2/docs/api/java/net/URL.html
[2] http://java.sun.com/j2se/1.4.2/docs/api/java/net/URLConnection.html
[3] http://java.sun.com/j2se/1.4.2/docs/api/java/net/URLStreamHandler.html
[4] http://www.dpml.net/depot/concepts/index.html
[5] http://www.dpml.net/transit/technical/artifact.html


> > > I guess my position on these handlers depends on the ease 
> > > to install them to a running JVM, and the actual use 
> > > cases having them would 
> > > solves. --DD
> 
> Scott Stirling


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message