You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by Guillaume Nodet <gn...@gmail.com> on 2009/09/18 08:36:36 UTC

OSGi plugin discovery (was Re: svn commit: r816444 - in /activemq/trunk: ./ activemq-core/ activemq-core/src/main/java/org/apache/activemq/util/ activemq-core/src/main/java/org/apache/activemq/util/osgi/)

On Fri, Sep 18, 2009 at 04:49,  <ch...@apache.org> wrote:
> Author: chirino
> Date: Fri Sep 18 02:49:21 2009
> New Revision: 816444
>
> URL: http://svn.apache.org/viewvc?rev=816444&view=rev
> Log:
> - refactored FactoryFinder so that it Implementation is pluggable.
> - made an OSGi friendly strategy for it using a BundleActivator (needs testing)
>
>
> Added:
>    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/
>      - copied from r816369, servicemix/smx4/specs/trunk/locator/src/main/java/org/apache/servicemix/specs/locator/
> Removed:
>    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/OsgiLocator.java
> Modified:
>    activemq/trunk/activemq-core/pom.xml
>    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/FactoryFinder.java
>    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java
>    activemq/trunk/pom.xml
>

<snipped>

>
> Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java
> URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java?rev=816444&r1=816369&r2=816444&view=diff
> ==============================================================================
> --- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java (original)
> +++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java Fri Sep 18 02:49:21 2009
> @@ -14,17 +14,22 @@
>  *  See the License for the specific language governing permissions and
>  *  limitations under the License.
>  */

<snipped>

> +    private boolean isImportingUs(Bundle bundle) {
> +        try {
> +            // If that bundle can load our classes.. then it must be importing us.
> +            return bundle.loadClass(Activator.class.getName())==Activator.class;
> +        } catch (ClassNotFoundException e) {
> +            return false;
> +        }
> +    }

This won't work in OSGi for several reasons.  In OSGi, class
visibility is controlled per package, not per bundle.  So for a bundle
to see the Activator class, it would have to explicitely import the
org.apache.activemq.util.osgi package, else a ClassNotFoundException
would be thrown.  This looks like an unnecessary constraint to put on
the bundles.

As I said in the other thread, I think we should defer that for 5.4
and discuss that a bit more.

For plugins, I think the best way would be to use the OSGi service
registry for importing such plugins.  i.e. a plugin would be
registered in the OSGi registry with the interface it is supposed to
implement (for example org.apache.activemq.transport.TransportFactory
and with a property associated to the service which represents the
name of the tramsport.  This would then allow the FactoryFinder to
find the transport in the OSGi registry.  Also, using OSGi services
would ensure class compatibility (i.e. if the plugin uses a different
activemq version, activemq-core would not use it).

We then have two problems to solve.  The first one is to allow plugins
 to not have to deal too much with OSGi, and also not impose any
constraints on people that write plugins that are not OSGi aware.   So
the registration of plugins can be done by a different bundle: this
bundle would listen for newly started or stopped bundles and would
register / unregister the plugin service accordingly.

Last, we need to think about how we want to handle OSGi dynamics.  The
OSGi environment is really dynamic and bundles can come and go at any
time.  Thus we need to be prepared for:
   * starting a broker if some transports / discovery plugins are not
available yet
   * react on the fact that a used plugin has just been stopped / uninstall

One possible solution would be to use the same solution has done in
blueprint / spring-dm.  i.e. for a mandatory dependency, we first wait
until the dependency is satisfied.   One it is, we create a proxy for
the OSGi service.  If the OSGi service is unregistered and the proxy
need to satisfy an invocation, we wait until a new service is
available.  Wait has a configurable timeout.  This allow updating one
transport for example without shutting down the whole broker.

I don't have enough knowledge of activemq's internal, so maybe using
proxies does not make sense at all (because all the plugins maintain a
state that would be lost and cause data corruption or such things).
So maybe this is not the solution, but we need to be prepared for such
things, hence a solution must be discussed and found.

> +
> +    private static class BundleWrapper {
> +        private final Bundle bundle;
> +        private final ArrayList<String> cachedServices = new ArrayList<String>();
> +
> +        public BundleWrapper(Bundle bundle) {
> +            this.bundle = bundle;
>         }
>     }
>  }
>
> Modified: activemq/trunk/pom.xml
> URL: http://svn.apache.org/viewvc/activemq/trunk/pom.xml?rev=816444&r1=816443&r2=816444&view=diff
> ==============================================================================
> --- activemq/trunk/pom.xml (original)
> +++ activemq/trunk/pom.xml Fri Sep 18 02:49:21 2009
> @@ -401,6 +401,13 @@
>       </dependency>
>
>       <dependency>
> +        <groupId>org.osgi</groupId>
> +        <artifactId>org.osgi.core</artifactId>
> +        <version>4.1.0</version>
> +        <scope>provided</scope>
> +      </dependency>
> +
> +      <dependency>
>         <groupId>org.apache.hadoop.zookeeper</groupId>
>         <artifactId>zookeeper</artifactId>
>         <version>3.0.0</version>
>
>
>



-- 
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com

Re: OSGi plugin discovery (was Re: svn commit: r816444 - in /activemq/trunk: ./ activemq-core/ activemq-core/src/main/java/org/apache/activemq/util/ activemq-core/src/main/java/org/apache/activemq/util/osgi/)

Posted by Hiram Chirino <ch...@gmail.com>.
Yeah.  I guess we need to setup a couple of use cases / usage scenarios in
an integration test env.  Would love it if someone more familiar /w OSGi
could setup a module like that.
hint. hint. ;-)


On Fri, Sep 18, 2009 at 2:36 AM, Guillaume Nodet <gn...@gmail.com> wrote:

> On Fri, Sep 18, 2009 at 04:49,  <ch...@apache.org> wrote:
> > Author: chirino
> > Date: Fri Sep 18 02:49:21 2009
> > New Revision: 816444
> >
> > URL: http://svn.apache.org/viewvc?rev=816444&view=rev
> > Log:
> > - refactored FactoryFinder so that it Implementation is pluggable.
> > - made an OSGi friendly strategy for it using a BundleActivator (needs
> testing)
> >
> >
> > Added:
> >
>  activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/
> >      - copied from r816369,
> servicemix/smx4/specs/trunk/locator/src/main/java/org/apache/servicemix/specs/locator/
> > Removed:
> >
>  activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/OsgiLocator.java
> > Modified:
> >    activemq/trunk/activemq-core/pom.xml
> >
>  activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/FactoryFinder.java
> >
>  activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java
> >    activemq/trunk/pom.xml
> >
>
> <snipped>
>
> >
> > Modified:
> activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java
> > URL:
> http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java?rev=816444&r1=816369&r2=816444&view=diff
> >
> ==============================================================================
> > ---
> activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java
> (original)
> > +++
> activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/osgi/Activator.java
> Fri Sep 18 02:49:21 2009
> > @@ -14,17 +14,22 @@
> >  *  See the License for the specific language governing permissions and
> >  *  limitations under the License.
> >  */
>
> <snipped>
>
> > +    private boolean isImportingUs(Bundle bundle) {
> > +        try {
> > +            // If that bundle can load our classes.. then it must be
> importing us.
> > +            return
> bundle.loadClass(Activator.class.getName())==Activator.class;
> > +        } catch (ClassNotFoundException e) {
> > +            return false;
> > +        }
> > +    }
>
> This won't work in OSGi for several reasons.  In OSGi, class
> visibility is controlled per package, not per bundle.  So for a bundle
> to see the Activator class, it would have to explicitely import the
> org.apache.activemq.util.osgi package, else a ClassNotFoundException
> would be thrown.  This looks like an unnecessary constraint to put on
> the bundles.
>
> As I said in the other thread, I think we should defer that for 5.4
> and discuss that a bit more.
>
> For plugins, I think the best way would be to use the OSGi service
> registry for importing such plugins.  i.e. a plugin would be
> registered in the OSGi registry with the interface it is supposed to
> implement (for example org.apache.activemq.transport.TransportFactory
> and with a property associated to the service which represents the
> name of the tramsport.  This would then allow the FactoryFinder to
> find the transport in the OSGi registry.  Also, using OSGi services
> would ensure class compatibility (i.e. if the plugin uses a different
> activemq version, activemq-core would not use it).
>
> We then have two problems to solve.  The first one is to allow plugins
>  to not have to deal too much with OSGi, and also not impose any
> constraints on people that write plugins that are not OSGi aware.   So
> the registration of plugins can be done by a different bundle: this
> bundle would listen for newly started or stopped bundles and would
> register / unregister the plugin service accordingly.
>
> Last, we need to think about how we want to handle OSGi dynamics.  The
> OSGi environment is really dynamic and bundles can come and go at any
> time.  Thus we need to be prepared for:
>   * starting a broker if some transports / discovery plugins are not
> available yet
>   * react on the fact that a used plugin has just been stopped / uninstall
>
> One possible solution would be to use the same solution has done in
> blueprint / spring-dm.  i.e. for a mandatory dependency, we first wait
> until the dependency is satisfied.   One it is, we create a proxy for
> the OSGi service.  If the OSGi service is unregistered and the proxy
> need to satisfy an invocation, we wait until a new service is
> available.  Wait has a configurable timeout.  This allow updating one
> transport for example without shutting down the whole broker.
>
> I don't have enough knowledge of activemq's internal, so maybe using
> proxies does not make sense at all (because all the plugins maintain a
> state that would be lost and cause data corruption or such things).
> So maybe this is not the solution, but we need to be prepared for such
> things, hence a solution must be discussed and found.
>
> > +
> > +    private static class BundleWrapper {
> > +        private final Bundle bundle;
> > +        private final ArrayList<String> cachedServices = new
> ArrayList<String>();
> > +
> > +        public BundleWrapper(Bundle bundle) {
> > +            this.bundle = bundle;
> >         }
> >     }
> >  }
> >
> > Modified: activemq/trunk/pom.xml
> > URL:
> http://svn.apache.org/viewvc/activemq/trunk/pom.xml?rev=816444&r1=816443&r2=816444&view=diff
> >
> ==============================================================================
> > --- activemq/trunk/pom.xml (original)
> > +++ activemq/trunk/pom.xml Fri Sep 18 02:49:21 2009
> > @@ -401,6 +401,13 @@
> >       </dependency>
> >
> >       <dependency>
> > +        <groupId>org.osgi</groupId>
> > +        <artifactId>org.osgi.core</artifactId>
> > +        <version>4.1.0</version>
> > +        <scope>provided</scope>
> > +      </dependency>
> > +
> > +      <dependency>
> >         <groupId>org.apache.hadoop.zookeeper</groupId>
> >         <artifactId>zookeeper</artifactId>
> >         <version>3.0.0</version>
> >
> >
> >
>
>
>
> --
> Cheers,
> Guillaume Nodet
> ------------------------
> Blog: http://gnodet.blogspot.com/
> ------------------------
> Open Source SOA
> http://fusesource.com
>



-- 
Regards,
Hiram

Blog: http://hiramchirino.com

Open Source SOA
http://fusesource.com/