javaspringosgispring-dmbnd

Spring OSGI service reference interfaces must be explicitly imported by consuming bundle?


I'm getting acquainted with Spring OSGI and Blueprint, but am having "classpath" difficulties (like many newbies).

I have two OSGI bundles - one that defines various beans (using Blueprint, not that it should matter) and exports them as services; and another bundle that references the service beans (using Spring OSGI) and plugs them into some Apache Camel routes.

The service-provider bundle's Blueprint looks something like this:

<service id="camelTsvDataFormat" 
    interface="org.apache.camel.spi.DataFormat"> 
    <bean class="org.apache.camel.component.flatpack.FlatpackDataFormat"/> 
</service> 

The service-consumer bundle's Spring context looks something like this:

<osgi:reference id="tsvDataFormat" 
    interface="org.apache.camel.spi.DataFormat" /> 

<camel:camelContext> 
    <route> 
        <from uri="vm:in"> 
        <setBody> 
            <constant>SELECT * FROM myTable</constant> 
        </setBody> 
        <to uri="jdbc:myDataSource" /> 
        <marshal ref="tsvDataFormat" /> 
        <to uri="file:/path/to/my/files/?fileName=out.tsv" /> 
    </route> 
</camel:camelContext> 

… But upon deployment, Spring "Cannot find class [org.apache.camel.spi.DataFormat]". I can add the interface to the Import-Package section of my Bnd instructions, but it seems redundant to have to manually list the class twice in separate locations.

An alternate choice is to extend the interface within my own project so Bnd will automatically pick it up, but this is approximately as much trouble.

I guess I'm expecting Spring to lookup services by interface name without having to actually resolve the interface class. Is this naïve? Or is there a way to have Bnd automatically import interfaces in my appContext's service references? If Bnd can do this (e.g. using plugins), is there a standard way to use the Bnd plugins with the Apache Felix bundle plugin for Maven?


Solution

  • As Holly suggests, bnd would normally find this package referenced from any bytecode inside your bundle that invokes it. It should also introspect Spring-DM XML files if they are in the right location. However I don't know if it yet supports Blueprint XML files in the same way, because they are not in the same bundle location. So it might be necessary to upgrade your version of bnd or use a plugin that supports Blueprint.

    However, I'm suspicious of this whole thing. If there are no bytecode references to the interface, then it seems you're not even using the service reference? In that case, why not just remove it?