Fetching latest commit…
Cannot retrieve the latest commit at this time.
|Failed to load latest commit information.|
================================================================================ Arkadiko ================================================================================ Spring's dependency injection framework is the picture of ubiquity in the java world. As such it aims to drive developers toward declarative, component driven design and lose coupling. But, it is largely a static container. The class space is flat and once started there is little means for dynamic change. OSGi is "the" modularity framework for java. It supports dynamic change via strict classloader isolation and packaging metadata. It also aims to drive developers toward modular design. But although it is very powerfull it is also complex and learning it's intricacies can be daunting. These two paradigms have recently undergone a merge or sorts in such that within OSGi frameworks one can use the declarative nature of Spring (via Spring DM and more recently standardised as Blueprint) to configure and wire together the interdependencies of components as they come and go from the OSGi framework. So how does _this_ project, Arkadiko come into play? First allow me to explain briefly the current state of the world as I understand it (this is my personal assessment). Given the vast number of Spring based projects and the most recent up-surge in the desire to benefit from OSGi's dynamic modularity it has become clear that there is a understandable difficulty in moving projects of any complexity to OSGi from a pure Spring architecture. The issue is that there are some design changes that must be made in moving traditional java applications, including Spring based ones, to OSGi. OSGi has a puritanical solution to a vast number of problems caused by the traditional architectures, but in order to gain from those solutions a considerable amount of redesign has to be done. What to do? There are several well known projects and individuals promoting methodologies and best practices to help undertake the considerable amount of work that such a migration could potentially involve. A recent presentation by BJ Hargrave (IBM) and Peter Kriens (aQute) (http://www.slideshare.net/bjhargrave/servicesfirst-migration-to-osgi) defines the concept of "services first" migration methodology. This methodology suggests that the first steps in the migration is to re-design the existing architecture such that it's based on a services oriented design. They offer some insight into how that is accomplished paraphrased over several different articles about μservices (micro-services) and I won't go into detail here about all that. Suffice it to say that once this has been accomplished it becomes far simpler to isolate portions/groupings of code that form logical components into modules which use or publish services in well defined manner to subsequently be turned into OSGi bundles. Also, a core developer of the Apache Felix project, Karl Pauls, has recently released a library called PojoSR (http://code.google.com/p/pojosr/) based on some of the Apache Felix project code that itself does not implement a full OSGi framework container, but essentially provides an active registry which scans the class space for recognizable "services" and effectively tries to wire those together or a the very least provide a central access point for those services. I have no in-depth knowledge on either of those two topics but I highly suggest taking some time to review both because they present options for anyone entertaining the notion for undertaking such a migration to OSGi, and several options are always welcome. Finally we come to Arkadiko! Arkadiko is a small bridge between Spring and OSGi. Arkadiko is an attempt to provide an new migration option, and borrows ideas from both of the above and tries to marry into those the concept of "quick wins" (such as immediate access to OSGi features) and "time to evolve". Quick Wins: Often the light at the end of the tunnel seems awfully far away. When reviewing the scope of the migration, it may seem like an eternity before the benefits will pay off. So, Arkadiko gives you OSGi right now! How does it do that? It simply provides a means to wire an OSGi framework into your current spring container. But that in itself doesn't help and so it also dynamically registers all your beans as services and at the same time registers a OSGi ServiceTracker for each one. It does this so that if matching services are published into the OSGi framework they are automatically wired in place of those original beans. You get OSGi right away! It also means that the OSGi framework has access to all your beans and can use those as regular services. Time to Evolve: The other benefit is that you now have time to evolve your platform into OSGi as you see fit, and as time allows, moving components slowly from outside the OSGi framework, into the OSGi framework as re-design is completed by component. Also, those nasty libraries which have yet to be ported or are still known to not live happily inside of OSGi framework can remain outside thr framework, consumed and wired in from within the container, until such a time as they evolve their own OSGi solutions. Licensed under the LGPL 2.1 or later (see LICENSE). Arkadiko is very small and very simple! It only comprises 5 classes in total (one is an exception, one is constants, one is a util class, the real work is done by two classes). Adding Arkadiko to your existing spring configurations is as simple as adding a single bean: <bean class="com.liferay.arkadiko.BridgeBeanPostProcessor"> <property name="framework"> <!-- some factory to get an instance of org.osgi.framework.launch.Framework --> </property> </bean> Below is a full example spring configuration file that explains all the properties available. Hopefully they prove flexible enough to be enduring. If not, as this is an open source project, we can always add more. <beans default-destroy-method="destroy" default-init-method="afterPropertiesSet" xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" > <bean class="com.liferay.arkadiko.BridgeBeanPostProcessor"> <!-- -- classLoader (Optional): Will use -- Thread.currentThread().getContextClassLoader(); -- if none is provided. -- --> <!-- <property name="classLoader"> <bean class="com.liferay.portal.kernel.util.PortalClassLoaderUtil" factory-method="getClassLoader" /> </property> --> <!-- -- framework (Required): Provide the Framework to be bridged. --> <property name="framework"> <bean class="com.liferay.portal.osgi.service.OSGiServiceUtil" factory-method="getFramework" /> </property> <!-- -- ignoredBeanNames (Optional): Provide a list of bean names that -- should be ignored. Names may be prefixed or suffixed with a * for -- simple matching. --> <!-- <property name="ignoredBeanNames"> <list> <value>com.liferay.portal.kernel.util.PortalClassLoaderUtil*</value> <value>*Advice</value> </list> </property> --> <!-- -- ignoredClassNames (Optional): Provide a list of class names that -- should be ignored. Names may be prefixed or suffixed with a * for -- simple matching. --> <!-- <property name="ignoredClassNames"> <list> <value>com.liferay.portal.cluster.*</value> <value>com.liferay.portal.dao.jdbc.*</value> <value>com.liferay.portal.dao.orm.*</value> <value>com.liferay.portal.kernel.cluster.*</value> <value>com.liferay.portal.kernel.util.PortalClassLoaderUtil</value> <value>com.liferay.portal.search.lucene.PerFieldAnalyzerWrapper</value> <value>com.liferay.portal.util.HttpImpl</value> <value>java.lang.*</value> <value>java.util.*</value> <value>org.apache.lucene.*</value> <value>org.springframework.*</value> </list> </property> --> <!-- -- proxyFactory (Optional): Provide the class name of a proxy factory -- class with a static method matching the signature of -- "newProxyInstance" method of java.lang.reflect.Proxy. If none is -- provided java.lang.reflect.Proxy is used. --> <!-- <property name="proxyFactory"> <value type="java.lang.Class">com.liferay.portal.kernel.util.ProxyUtil</value> </property> --> </bean> </beans>