I agree about the classloader hacks ... though I am not sure if they are needed anywhere. The approach I showed will not suffer from this problem as you directly tell it to get a bean with an id.

Christian

On 02.02.2016 17:24, Brad Johnson wrote:
Christian,

Thanks for the constructive thoughts.  Theoretically if everything is set
up correctly then it will find everything in the OSGi registry.
Unfortunately, when it can't find things in the registry it will look for
it with the global class loader. That was happening to me.  It shouldn't
have found it because I didn't have something set up right. What I ended up
with is a non-proxied instance from one bundle running inside an instance
from another bundle.  When I'd switch from the test stub bundle to the
actual bundle and back it would cause all kinds of havoc because the bundle
didn't have a reference to an OSGi proxy it had a reference to a concrete
type and things blew up.

In reality though the classloader cheating should be disallowed or, at the
very least, disallowable.  A simple flag specifying that the OSGi registry
must be used would result in a hard error. You can imagine that there must
be more than one instance of Fuse/karaf running out there where non-proxied
services are running across bundles and developers aren't aware of it.  If
I hadn't been actively swapping bundles which implement the same interface
I wouldn't have found that it was breaking the bundle encapsulation.

On Tue, Feb 2, 2016 at 3:24 AM, Christian Schneider <ch...@die-schneider.net
wrote:
There is a much simpler way to use an OSGi service with blueprint.
Simply use the bean component of camel. It resolves beans against the
camel registry.
When you define your camel context using blueprint then the camel registry
automatically includes all blueprint beans.

So you can do this in java dsl:
to("bean:echo-service")

It will find the bean with this id in blueprint. In your case it will be
the service reference.

Christian


On 26.01.2016 23:11, Quinn Stevenson wrote:

When I use an OSGi Service registered using Blueprint from a Java route
(built using a Java RouteBuilder), the Camel route isn’t detecting the when
the service is not available, and it isn’t updating when the service
implementation changes.

The simple setup I’m using has a Java interface for the OSGi service in
one bundle, and implementation of that interface which uses Blueprint to
register the service in another bundle, and simple RouteBuilder that uses
the service in a third bundle.  The implementation of the service is
injected into the RouteBuilder using Blueprint, and the Camel context is
configured in Blueprint in a fourth bundle.

After all these bundles are installed and started in Karaf, the run and
the hashCode of service is logged every time the Camel timer fires and
triggers an exchange.  If I stop the bundle that registers the service
using Blueprint, the route continues to log the same hashCode when it calls
the OSGi service.  I would expect a ServiceUnavailableException after a
timeout.

Additionally, when I restart the bundle that registers the service
object, I continue to get the same hashCode.  I would expect to get a new
hashCode value.

Am I doing something wrong?  Do I need to do something different do get
the dynamic behavior I’m looking for?


The code looks like this:

Java Interface (service-interface bundle):
public interface Echo {
      String execute(String body);
}

Java Implementation:
public class EchoServiceOne implements Echo {
      Logger log = LoggerFactory.getLogger(this.getClass());

      @Override
      public String execute(String body) {
          log.info( "{}:{} -> execute", this.getClass().getSimpleName(),
this.hashCode() );
          return body;
      }
}


Blueprint Registering the service (service-one bundle):
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
             xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";>

      <service interface="com.pronoia.test.osgi.service.Echo" >
          <service-properties>
              <entry key="instance" value="one" />
          </service-properties>
          <bean class="com.pronoia.test.osgi.service.impl.EchoServiceOne"
/>
      </service>

</blueprint>

Java RouteBuilder (route-builder bundle):
public class VerySimpleBuilder extends RouteBuilder {
      Echo blueprintServiceReference;

      @Override
      public void configure() throws Exception {
          from("timer://very-simple-builder?period=5000").routeId(
"very-simple-route" )
                  .setBody( simple( "${exchangeProperty[" +
Exchange.TIMER_FIRED_TIME + "]}") )
                  .log("Calling Service via Reference: ${body}" )
                  .bean(blueprintServiceReference,false)
                  .to( "mock://result")
                  .log("Finished" );
      }

      public Echo getBlueprintServiceReference() {
          return blueprintServiceReference;
      }

      public void setBlueprintServiceReference(Echo
blueprintServiceReference) {
          this.blueprintServiceReference = blueprintServiceReference;
      }
}

Blueprint constructing the Camel context (camel-context bundle):
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
             xmlns:ext="
http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0";
             xsi:schemaLocation="
         http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
         http://camel.apache.org/schema/blueprint
http://camel.apache.org/schema/blueprint/camel-blueprint.xsd";
      <reference id="echo-service"
interface="com.pronoia.test.osgi.service.Echo" filter="instance=one"
timeout="2000" />

      <bean id="very-simple-route-builder"
class="com.pronoia.test.camel.builder.VerySimpleBuilder">
          <property name="blueprintServiceReference" ref="echo-service" />
      </bean>

      <camelContext id="very-simple-context" xmlns="
http://camel.apache.org/schema/blueprint";>
          <routeBuilder ref="very-simple-route-builder" />
      </camelContext>

</blueprint>




--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com




--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply via email to