tuscany-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Nash <n...@apache.org>
Subject Re: Get Contribution at runtime?
Date Thu, 29 Nov 2012 18:13:04 GMT
Millies, Sebastian wrote:
>> -----Original Message-----
>> From: Simon Nash [mailto:nash@apache.org]
>> Sent: Thursday, November 29, 2012 4:55 PM
>> To: user@tuscany.apache.org
>> Subject: Re: Get Contribution at runtime?
> 
> [snip]
> 
>> I think you can put the META-INF/services directory anywhere on the system
>> classpath.
>>
>>    Simon
> 
> I have solution of sorts, and will attempt to summarize it here, working in some of Simon's
> comments as well.
> 
> To re-iterate the problem: I want to set up my contributions, so that they can use
> different versions of third-party libraries than the Tuscany 1.6 runtime. My original
example
> was using recent versions of EMF, another example is using Tuscany with an Apache Solr
> 4.0 backend, which requires different Apache Http Components.
> 
> Some approaches have turned out to be infeasible:
> 1) patching the built-in ContributionClassLoader to use a parent-last strategy leads
to several
> errors in Tuscany tests and samples. The fault may lie with the tests being based on
wrong assumptions
> and bad-practices, but to correct them all is not a practical option. (Besides, it would
be contrary to the
> OASIS specs.)
> 2) The approach outlined in [1] is quite complicated, and I have not been able to get
it to work.
> 
> Instead, I have chosen to exploit the Tuscany extension mechanism in order to provide
a class loader
> of my choice as the contribution class loader. This solution will work when one follows
the recommended
> best practice of keeping contribution classes separate from the system classpath. The
new class loader is
> the delegation parent of the contribution class loader.
> 
> The approach has two limitations:
> 1) the contributions shouldn't pass any references to these overriding external libraries
to the Tuscany
> runtime (e. g. in the form of service parameters)
> 2) the extension mechanism is a applied globally rather than to specific contributions.
> 
> (Both these points do not worry me. With regard to the second one, the overriding classes
could be
> included in a nested jar in the contribution itself, so even if the mechanism is global,
any overriding
> could be kept strictly local, if desired. After all, it's my own class loader doing the
work.)
> 
> Finally, here's how it really works, without requiring any code changes in Tuscany itself.
> 
> 1) Define a class loader, e. g. EndorsedLibsClassLoader extends URLClassLoader
> 
> 2) Define a class loader provider, e. g. EndorsedLibsClassLoaderProvider implements ContributionClassLoaderProvider.
> This is the core of the solution. We inject the new class loader between the standard
contribution class loader and
> the app class loader:
>     public ClassLoader getClassLoader( Contribution contribution, ClassLoader parent
)
>     {
>         EndorsedLibsClassLoader endorsedLoader = new EndorsedLibsClassLoader( parent
);
>         return new ContributionClassLoader( contribution, endorsedLoader );
>     }
> 
> 3) Define a class loader provider extension point, e. g.
> PrioritizedContributionClassLoaderProviderExtensionPoint implements ContributionClassloaderProviderExtensionPoint
> 
> The reason for this is that Tuscany will look up ALL class loader providers, not just
your own, then put them in
> a HashSet, iterate over the set, and keep one provider per contribution type, whichever
one it happens to find
> last (clearly a bug, in my view). The PrioritizedContributionClassLoaderProviderExtensionPoint
allows
> class loader providers to have a "priority" attribute, and keeps the one with the highest
priority.
> 
> 4) Register the provider and the provider extension point in two files in a META-INF/services
directory. The file names
> are:
> org.apache.tuscany.sca.contribution.java.ContributionClassLoaderProvider
> org.apache.tuscany.sca.contribution.java.ContributionClassloaderProviderExtensionPoint
> 
> The latter just contains the FQCN of the extension point implementation. The former contains
the FQCN of the class
> loader provider, along with its attributes, e. g. like this:
> example.contribution.java.EndorsedLibsClassLoaderProvider;type=application/x-compressed,priority=10
> 
> 5) Put the META-INF directory on the system classpath. But not just anywhere: It must
come BEFORE the Tuscany
> runtime, because the tuscany-sca-all.jar will contain an analogous directory, and the
extension point is loaded
> only once, from the first text file with appropriate name that is found.
> 
> This is really quite simple, after all. It may not be the best of all possible solutions,
but it works for me.
> 
> -- Sebastian
> 
> PS: I'd like to share some example code (99,9% is original Tuscany code anyway...)
> I have put the text of this mail plus a zip archive into the JIRA that has occasioned
this entire exchange:
> https://issues.apache.org/jira/browse/TUSCANY-4073
> 
> [1] http://mail-archives.apache.org/mod_mbox/tuscany-user/201006.mbox/%3C4C164DD3.8090405@apache.org%3E
> [2] https://cwiki.apache.org/TUSCANYWIKI/classloading.html
> 
> 
> IDS Scheer Consulting GmbH
> Geschäftsführer/Managing Directors: Michael Rehm, Ivo Totev
> Sitz/Registered office: Altenkesseler Straße 17, 66115 Saarbrücken, Germany - Registergericht/Commercial
register: Saarbrücken HRB 19681
> http://www.ids-scheer-consulting.com
> 
Well done! :)

Would you like to create a new JIRA for the fault you discovered and needed to
work around by creating PrioritizedContributionClassLoaderProviderExtensionPoint?

   Simon

Mime
View raw message