Here are some intermediate results on using the FactorySPI pattern in an OSGi 
environment:

- I've verified that it works as expected as long as you do not use wrapped 
JARs in your bundles and configure buddy classloading appropriately.

- OSGifying all of Geotools will be harder than expected due to a considerable 
number of split packages in Geotools.

The whole story is a bit longer, and this mailing list is probably not the best 
place to keep track of the results. I'm thinking of writing an article in the 
Geotools wiki to summarize the results and give some code examples and links to 
relevant documentation elsewhere, if that would be ok for the Geotools 
community - of course I don't want to act against project policies.

For the time being, let me just give an overview of what I tried to do. It took 
me longer than I had hoped, but after a while I realized that I was trying to 
solve too many problems at once. My initial plan was to

0) Identify a minimal self-contained subset of Geotools libraries to show that 
the FactorySPI pattern works with OSGi, simply by changing the corresponding 
POMs to build OSGi bundles instead of plain old JARs.

When I got stuck with the split packages, I realized that it would help to deal 
with the following issues one after another:

1) Manually convert a subset of Geotools libraries to OSGi bundles to show that 
FactorySPIs work in OSGi.

2) Change the POMs to turn the generated JARs into OSGi bundles by inserting 
handcrafted MANIFEST.MF files.

3) Replace Import-Bundle by Import-Package in the manifests, or in fact let the 
maven-bundle-plugin do this automatically.

Having split the original problem into these steps, it was fairly 
straightforward to solve step 1, and this was the main issue anyway. 

Step 3) could be equally straightforward if Geotools would take care to avoid 
split packages. (A split package is a Java package occurring in more than one 
OSGi bundle, e.g. org.geotools.factory in gt-main AND in gt-metadata). There 
are ways of dealing with split packages both in OSGI and in the 
maven-bundle-plugin and I'm about 95 % convinced that you could make it work 
after careful analysis of the package structure and some manual work in the 
POMs, but it would probably be a lot easier to simply make package names 
globally unique within Geotools. 

I don't know if this is an option, considering backward compatibility, so I 
left it at that.

Step 2) is not of much value in itself, I only see it as a fallback solution if 
it turns out that Geotools packages cannot be refactored, and that the 
split-package mechanisms do not work. The drawback would be that you'd have to 
use bundle instead of package dependencies (Import-Bundle vs. Import-Package).

Some more details about step 1):

I started off with the following subset of geotools libraries from the Geotools 
svn trunk

gt-api
gt-cql
gt-main
gt-metadata
gt-referencing

taking org.geotools.filter.expression.Function as an example of Factory SPI 
usage, invoking CommonFactoryFinder.getFunctions(null). If you only use 
gt-main, gt-metadata and gt-api, you get 139 functions from gt-main. If you add 
gt-cql and its dependency gt-referencing, you get another function from gt-api, 
thus a total of 140 functions. 

These 5 Geotools libraries have a number of external dependencies:

jai-codec
jai-core
commons-beanutils
commons-collections
commons-logging
commons-pool
jdom
geoapi
jsr-275
jts
log4j
junit4
vecmath
osgi

I turned each of these dependencies into a separate OSGi bundle - actually, I 
found osgified versions for most of them in the SpringSource Enterprise Bundle 
Repository.

I ran a full Maven build of all of Geotools from the command line to get hold 
of the required generated sources (JAXB, JavaCC).

Then I forgot about Maven and used Eclipse PDE to manually create my 5 Geotools 
bundles such that bundle org.geotools.xxx corresponds to library gt-xxx. 

At first, I created a dedicated target platform, containing just the external 
dependency bundles listed above, and I configured my Eclipse workspace to use 
this target platform. Then I created the Geotools bundles as Plug-in projects, 
adding one or more source folders per project, including the generated sources 
produced by Maven. Using the PDE Manifest editor, I added the Import-Bundle 
statement via the "Required plug-ins" form.

The class which scans the META-INF/services resources is FactoryRegistry in 
bundle org.geotools.metadata. You need to make sure that this class will see 
the resources contributed by other bundles, which can be achieved by Eclipse 
buddy classloading. 

So I manually added 

Eclipse-BuddyPolicy: registered

to the org.geotools.metadata manifest,

and a matching

Eclipse-RegisterBuddy: org.geotools.metadata

to the manifests of org.geotools.main and org.geotools.cql (the bundles 
containing the META-INF/services resources).

Finally, I created a simple factoryclient bundle which invokes 
CommonFactoryFinder.getFunctions() in its bundle activator and prints out the 
number of registered functions.

This bundle only depends on bundles org.geotools.main, geoapi and package 
org.osgi.framework.

Now when I launch this bundle with an Eclipse OSGi framework launcher, I get 
the desired number of 139 or 140 functions, depending on whether or not the 
launch configuration includes the org.geotools.cql bundle.

QED

I hope this was sufficient to get the general idea, and I'm happy to provide 
more details on the Maven stuff for step 3 if required. Just let me know if 
this is of any value and how to proceed.

Regards,

Harald



-----Ursprüngliche Nachricht-----
Von:    [EMAIL PROTECTED] im Auftrag von Wellmann, Harald
Gesendet:       Di 02.09.2008 23:31
An:     Jody Garnett
Cc:     User-friendly Desktop Internet GIS
Betreff:        AW: AW: [udig-devel] External dependencies 
innet.refractions.udig.libs

My guess is this:

<quote>

If so that would be great news; what we really wanted to do is have a 
situation like:
- org.geotools.main plugin
-- contains gt-main-2.6-SNAPSHOT.jar
-- wants to process a factory SPI (looking for every jar with  a 
services file for "org.opengis.filter.Function")

</quote>

It seems you're trying to wrap a plain old JAR in an OSGi bundle. So you would 
deliver an org.geotools.main_2.6.SNAPSHOT.jar bundle (aka Eclipse plugin).  
When you unzip this outer JAR, you get the OSGi manifest and the plain old 
gt-main-2.6-SNAPSHOT.jar.

This wrapping is not really required - after all, an OSGi bundle is nothing but 
a JAR with some extra manifest headers.

If you simply add the extra headers to the MANIFEST.MF in gt-main*.jar, then 
your gt-main*.jar _is_ an OSGi bundle, and you won't even break anything for 
people putting this JAR on their plain old classpath.

The difference is that your META-INF/services/whatever is now a resource in a 
JAR and no longer hidden in a JAR within a JAR.


Ok, I'll give this a try with gt-main and gt-renderer, which may take a couple 
of days, but I'll get back to you on this.

Regards,

Harald 
 
*******************************************
innovative systems GmbH Navigation-Multimedia
Geschaeftsfuehrung: Edwin Summers - Kevin Brown - Regis Baudot 
Sitz der Gesellschaft: Hamburg - Registergericht: Hamburg HRB 59980 
 
*******************************************
Diese E-Mail enthaelt vertrauliche und/oder rechtlich geschuetzte 
Informationen. Wenn Sie nicht der richtige Adressat sind oder diese E-Mail 
irrtuemlich erhalten haben, informieren Sie bitte sofort den Absender und 
loeschen Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe 
dieser Mail ist nicht gestattet.
This e-mail may contain confidential and/or privileged information. If you are 
not the intended recipient (or have received this e-mail in error) please 
notify the sender immediately and delete this e-mail. Any unauthorized copying, 
disclosure or distribution of the contents in this e-mail is strictly forbidden.
*******************************************

<<winmail.dat>>

_______________________________________________
User-friendly Desktop Internet GIS (uDig)
http://udig.refractions.net
http://lists.refractions.net/mailman/listinfo/udig-devel

Reply via email to