You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@brooklyn.apache.org by Svetoslav Neykov <sv...@cloudsoftcorp.com> on 2015/01/13 19:39:00 UTC
OSGi-fying Clocker
Hi list,
While working with @sjcorbett troubleshooting problems caused by loading clocker as a bundle, an interesting case arose. When loading clocker through the standard classpath approach only one version of the code is present. If loading it through OSGi though it’s possible to have multiple versions registered at once, even running multiple infrastructure instances on different versions. All docker locations will use the same docker: prefix, so how do we know which version of DockerResolver should be handling the requests from other entities?
My proposal to solve the problem is to:
* Introduce an API for programmatically registering and unregistering LocationResolver with a corresponding prefix. It is possible even now to register with BasicLocationRegistry.registerResolver, but not exposed in the public API.
* Change the prefix for docker locations, current format is docker:<infrastructure entity id>, change it to docker-<infrastructure entity id> - have the infrastructure id as part of the prefix
* Register a separate DockerResolver for each infrastructure instance, unregister it on stopping
Other issues caused by loading clocker as an OSGi bundle, should be interesting to others creating bundles with their entities:
* There are a number of Brooklyn dependencies which are not OSGi bundles. When the maven-bundle-plugin generates the manifest for downstream projects it may import the packages of those dependencies even if the source doesn’t use them directly.
The long term solution is to contribute OSGi support to those projects, currently known are io.airlift:airline, google http client, com.maxmind:geoip2. Until then we can manually exclude those packages from the manifest, see [1]
* Same package in multiple bundles. This will lead to ClassNotFoundException, because only one of the bundles will be searched for the class. The best solution is to rename one of the packages so they don’t match. If that’s not feasible then see [2]
* Using ServiceLoader when the provider is in a bundle. There’s a solution which can expose the implementation, see [3] and [4], but registering multiple versions of the bundle will lead to unexpected results
* When passing classpath://… URLs to the API, even though the contextObject for loading them is the entity which has access to resources in the bundle, the code still fails to find them. This should be easily addressable as there’s a TODO for this case in AbstractManagementContext (see inside the addClassLoaderProvider call). Additionally we can support java.net <http://java.net/>.URL as arguments - they will go through the bundle classloader to load the correct resources.
Svet.
[1] https://github.com/brooklyncentral/clocker/pull/85/files#diff-08740066c64337d38cccd84991ac0912R93 <https://github.com/brooklyncentral/clocker/pull/85/files#diff-08740066c64337d38cccd84991ac0912R93>.
[2] http://wiki.osgi.org/wiki/Split_Packages <http://wiki.osgi.org/wiki/Split_Packages>
[3] http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html <http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html>
[4] http://aries.apache.org/modules/spi-fly.html <http://aries.apache.org/modules/spi-fly.html>