Bug 190654 - [ecf.protocols] prevent URL stream handler registration conflicts
Summary: [ecf.protocols] prevent URL stream handler registration conflicts
Status: NEW
Alias: None
Product: ECF
Classification: RT
Component: ecf.protocols (show other bugs)
Version: 1.1.0   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: ecf.core-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-06-02 12:44 EDT by Scott Lewis CLA
Modified: 2008-03-07 13:58 EST (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Scott Lewis CLA 2007-06-02 12:44:12 EDT
Currently, any plugin can use the OSGi platform URLStreamProtocolHandler service to register protocol handlers...and plugins can easily step on one anothers registration in doing so.  Introduce some mechanism (e.g. extension point) and/or conventions to coordinate platform management of protocol handlers.  

ECF currently has two relevant extension points org.eclipse.ecf.filetransfer.urlStreamHandlerService (which allows plugins to register url protocol handlers declaratively) 

and org.eclipse.ecf.filetransfer.provider.fileTransferProtocol (which declaratively registers ecf filetransfer API provider implementations).
Comment 1 Thomas Hallgren CLA 2007-06-03 02:53:08 EDT
Scott, how do you do this? Do you register a proxy handler with the JVM for each URL protocol extension that is found so that the real handler can be activated on demand?

How do we go about coordinating available handlers? I guess that is a more general question. I.e. how to avoid multiple providers of some given extension from overriding each other. Does Eclipse have a policy for that our do we invent something of our own?
Comment 2 Scott Lewis CLA 2007-06-03 12:24:47 EDT
(In reply to comment #1)
> Scott, how do you do this? Do you register a proxy handler with the JVM for
> each URL protocol extension that is found so that the real handler can be
> activated on demand?

We use the OSGi URLStreamHandlerService, which essentially does what you describe above for OSGi.  For each protocol defined in extensions for extension point org.eclipse.ecf.filetransfer.urlStreamHandlerServer, we call the following code:

Hashtable properties = new Hashtable();
					properties.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] { protocol });		context.registerService(URLStreamHandlerService.class.getName(), svc, properties);


> 
> How do we go about coordinating available handlers? I guess that is a more
> general question. I.e. how to avoid multiple providers of some given extension
> from overriding each other. 

Yes, I agree.

>Does Eclipse have a policy for that our do we
> invent something of our own?

Not yet...AFAIK.  I think this is the thing to do...provide some coordination/conventions...at least for 'standard' protocols so that conflicts can be avoided (or at least made known).



Comment 3 Thomas Hallgren CLA 2007-06-03 13:29:47 EDT
(In reply to comment #2)
> 
> properties.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] { protocol });  
>         context.registerService(URLStreamHandlerService.class.getName(), svc,
> properties);
> 
I assume that 'svc' in this case would be an instance of the actual handler and not a proxy? If so, that means that you activate the bundle even if the protocol is never used. I was thinking of a proxy that would instantiate the real handler on first use, thereby deferring the initialization of the providing bundle.
Comment 4 Scott Lewis CLA 2007-06-03 15:48:13 EDT
(In reply to comment #3)
> (In reply to comment #2)
> > 
> > properties.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] { protocol });  
> >         context.registerService(URLStreamHandlerService.class.getName(), svc,
> > properties);
> > 
> I assume that 'svc' in this case would be an instance of the actual handler and
> not a proxy? 

It's an instance of org.osgi.service.url.AbstractURLStreamHandlerService which has abstract method URLConnection openConnection as it's primary method (i.e. the URLConnection subclass is the place where nearly all the code exists for protocol handlers).


If so, that means that you activate the bundle even if the
> protocol is never used. I was thinking of a proxy that would instantiate the
> real handler on first use, thereby deferring the initialization of the
> providing bundle.

A reasonable notion, but I'm not sure how much savings would result, as the AbstractURLStreamHandlerService instance already sort of acts like a proxy...(i.e. I don't think all of the associated impl code would be actually loaded until first call to AbstractURLStreamHandlerService.openConnection.

Comment 5 Thomas Hallgren CLA 2007-06-04 02:19:42 EDT
(In reply to comment #4)
> A reasonable notion, but I'm not sure how much savings would result, as the
> AbstractURLStreamHandlerService instance already sort of acts like a
> proxy...(i.e. I don't think all of the associated impl code would be actually
> loaded until first call to AbstractURLStreamHandlerService.openConnection.
> 
My concern is that the bundle that provides the handler needs to be activated when you instantiate the handler class. Our cvs protocol handler for instance, would trigger the activation of our cvs bundle. That bundle is dependent on the Eclipse cvs bundle, which in turn requires the team bundle, etc.

An implementer could probably avoid such activation by denoting that the handler class should not activate the bundle. I don't think that is ideal for a class triggered by an extension though, since extensions normally relieve you from such responsibilities.

Comment 6 Michael Valenta CLA 2007-06-04 11:29:52 EDT
It's interesting to note that the Eclipse File System already has the characteristic that a file system implementation is only loaded when it is accessed. EFS has an extension registry that associates a URI scheme with a file system implementation. My understanding is that OSGi declarative services will provide this ability as well but this feature is not available in Eclipse 3.3.

It is probably also worthwhile to note that the CVS feature in Eclipse provides an EFS implementation for accessing files from a CVS repository. File identification is done using a URI format that is not compatible with the URL format but uses the scheme identifier "cvs". I suspect that having two forms of identifying resources in cvs will cause confusion in the log run. I think this is worth mentioning here because this problem is not specific to CVS but is general to any protocol that may want to provide a URL handler and an EFS implementation (i.e. I view this as a conflict between a URL hander and an EFS implementation).
Comment 7 Scott Lewis CLA 2007-06-10 14:07:32 EDT
Hi Michael,

(In reply to comment #6)
> It's interesting to note that the Eclipse File System already has the
> characteristic that a file system implementation is only loaded when it is
> accessed. EFS has an extension registry that associates a URI scheme with a
> file system implementation. My understanding is that OSGi declarative services
> will provide this ability as well but this feature is not available in Eclipse
> 3.3.

Right...thanks.

Two other points...about relationship between ECF and EFS:

1) The ECF filetransfer API was designed to be simpler than the EFS APIs...to 

a) provide asynchronous file transfer (only) 
a) only use CDC 1.0/Foundation 1.0 classes to support smaller Equinox-based runtimes (e.g. eRCP).  So, for example, URI is not supported on CDC 1.0/Foundation 1.0
b) support only file transfer rather than all normal file system operations (e.g. directory access and navigation, etc)

2) the ECF filetransfer API has a provider that uses EFS to implement asynchronous file transfer.  This plugin is org.eclipse.ecf.provider.efs and is not yet deployed with the rest of ECF, but is in /cvsroot/technology/org.eclipse.ecf/plugins.  This allows/supports URLs of the form:

efs:ftp://ftp.eclipse.org/file.name

and, in fact will support

efs:<any efs URI>

to be used with the ECF filetransfer API, and at file transfer time the appropriate EFS protocol implementation will be loaded and used.  This allows the ECF FT API to benefit from all protocols added to EFS (e.g. cvs, etc) and expose them via an asynchronous API.





Comment 8 Scott Lewis CLA 2008-03-06 16:28:14 EST
I would like to request some input about an issue for ECF that is similar to this one.

Currently, ECF has an extension point:  

org.eclipse.ecf.provider.filetransfer.retrieveFileTransferProtocolFactory.  This is used to decide which provider to use to implement a call like:

IRetrieveFileTransferContainerAdapter.sendRetrieveRequest(IFileID,IFileTransferListener,Map);

The IFileID instance passed in requires an URL, and so the protocol factory must be registered via the ECF extension point (e.g. http, https, torrent, etc) so that the actual handling of this call will be done by the correct provider (i.e. some other plugin...like apache httpclient provider).

This is similar to this bug in the sense that there is potential for conflict...i.e. if multiple protocol factories try to register for 'http' the ECF extension point impl must somehow either a) prevent the registration of more than one, or b) choose among them at runtime.  

As for this bug...I don't think the 'b' strategy would work...because there cannot be more than one url stream handler registered with the platform.

But, my question is this:  For the ECF retrieveFileTransferProtocolFactory how should a conflict be prevented or resolved?  

I've thought that perhaps it would be good to introduce a 'priority' property that allows plugins that create extensions for this extension point to define their relative priority via an optional priority attribute...e.g.

      <retrieveFileTransferProtocolFactory
      class="org.eclipse.ecf.provider.filetransfer.httpclient.HttpClientRetrieveFileTransferFactory"
            protocol="http"
            priority="100">
      </retrieveFileTransferProtocolFactory>

and then choose the one with the highest priority at runtime.

Are there other strategies that people would suggest? 

I would like to have something in place for ECF filetransfer by M6/API freeze if at all possible.

Thanksinadvance for the input.




Comment 9 Thomas Hallgren CLA 2008-03-06 18:14:50 EST
I think using a numeric priority is the right way to go. At least for now.

In general I think using a priority is pushing the problem one step away in that it requires an implementor to have knowledge of all other implementors. It also assumes that a priority is applicable. For instance, how would Buckminster choose between Subversive and Subclipse? They both extend our readerType extension point using the id 'svn'. I want it to be up to the user to decide.

I'll take the opportunity to do some lobbying for a support I think is lacking in the Eclipse runtime. It would be great if it was possible to mark extension implementations as mutually exclusive.

The eclipse runtime could support the notion of a 'singleton extension point' such that it would be an error to try to install two bundles that extended it using some primary key (in ECF's case the URL scheme).

The user could be forced to make a selection in case of a conflict. This could be done in the update manager or its successor. The user should also be able to change that selection using preferences later on.

Perhaps this is in motion already?
Comment 10 Scott Lewis CLA 2008-03-06 18:23:22 EST
(In reply to comment #9)
<stuff deleted>

Thanks Thomas for comments.  I think I will go with priority system for now (unless something else materializes here very soon)...but am fully aware of the problems you identify.

> The eclipse runtime could support the notion of a 'singleton extension point'
> such that it would be an error to try to install two bundles that extended it
> using some primary key (in ECF's case the URL scheme).
> 
> The user could be forced to make a selection in case of a conflict. This could
> be done in the update manager or its successor. The user should also be able to
> change that selection using preferences later on.

This seems like a very good idea to me.

> 
> Perhaps this is in motion already?
> 

Hopefully Pascal will jump in now and say that p2 already does this :).

Comment 11 Scott Lewis CLA 2008-03-07 13:58:02 EST
(In reply to comment #10)

I've created a separate bug 221896 to track and address this related-but-different issue specific to ECF extension points.