Abhijit Panchal
Abhijit Panchal

Reputation: 1

Spring bean from one bundle is not accessible in camel route in another bundle

I have one jar file (connection.jar) which is an OSGI bundle with folder structure src/main/resources/META-INF/spring/mq-connect.xml following connectivity code is placed in the mq-connect.xml

<beans ...... >
    ....
    ....
    ....
    ....

    <!-- AMQ jms component -->
    <bean id="amqtx" class="org.apache.activemq.camel.component.ActiveMQComponent">
        <property name="connectionFactory" ref="amqPooledConnectFactory" />
        ...
        ...
        ...
        <property name="maxConcurrentConsumers" value="${concurrent.consumers}" />
    </bean>
</beans>

I have another osgi bundle (connection_impl.jar) which contains camel routes. I want to use "amqtx" bean as the component in the camel endpoint. Following is the code which I put in the camel-context.xml to access the "amqtx"

<beans ...... >
    <import resource="classpath*:mq-connect.xml"/>
        ...
        ...
        ...
        ...
    <camelContext trace="true" streamCache="true" autoStartup="true" xmlns="http://camel.apache.org/schema/spring">
             <route customId="true" id="TEST_AMQ">
                    <description>Test connectivity from another file</description>
                    <from uri="amqtx:INBOUND.QUEUE" />
                    <transacted ref="AMQ_PROPAGATION_REQUIRED" />
                    <to uri="OUTBOUND.QUEUE" />
                    <log message="Route completed successfully" />
                </route>
    </camelContext> 
</beans>

I am using jboss-a-mq-6.2.1 and deploying to Karaf container. OSGi bundle connection.jar deploys successfully but connection_impl fails to deploy. It gives following error in the A-MQ logs

Stack Trace:  
org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToCreateRouteException: Failed to create route TEST_AMQ: 
Route(TEST_AMQ)[[From[amqtx:INBOUND.QUEUE]] -> ... because of Failed to resolve endpoint: amqtx://INBOUND.QUEUE due to: No component found with scheme: amqtx

I tried the part in various ways but still amqtx is not accessible in another bundle.

Please suggest any missing import,export/wrong configuration so that amqtx component in connection.jar is accessible in connection_impl.jar

Upvotes: 0

Views: 813

Answers (2)

Matthew Fontana
Matthew Fontana

Reputation: 3870

I am in agreement with Christian. When you are using OSGI bundles are typically isolated unless you explicitly set exports for a library another bundle uses or you are exposing an OSGI Service. If you would like to setup an OSGI service my recommendation is doing it the Spring Framework way since its relatively clean. You can expose your Component via an interface. I'll show an example below.

Typically I like to have 3 bundles managing this. I usually have a bundle that contains just the interface that I will be exposing between separate bundles. A Bundle that is the implementation of the interface and a bundle that leverages the interface's injected implementation to accomplish a task.

//Interface bundle will expose an Interface and any Pojos associated. Ex:

public interface AlternateFacilityApi {
    public String getAlternateFacility(String facilityName);
}

//Implementation bundle will register an OSGI service based off of the implementation bean from your interface (yes the previous bundle is a dependency OSGI wires in)

public Class MyAlternateFacilityImpl implements AlternateFacilityApi {
    public String getAlternateFacility(String facilityName) {
        return "Bob's house";
    }

//camel context

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:osgi="http://www.springframework.org/schema/osgi"
    xmlns:ctx="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
       http://www.springframework.org/schema/osgi
       http://www.springframework.org/schema/osgi/spring-osgi.xsd">

    <osgi:service id="AlternateFacilityService" ref="alternateFacilityService" interface="com.world.api.AlternateFacilityApi" />

    <bean id="alternateFacilityService" class="com.world.service.MyAlternateFacilityImpl" 
/>
</beans>

//Ok and finally the Process looking to leverage the OSGI Service

public Class AlternateFacilityLookup {
    private AlternateFacilityApi apiLookupBean;

    public String getMyAlternateFacility(String facilityName) {
        return apiLookupBean.getAlternateFacility(facilityName);
    }

    //excluded setters and getters
}

//camel context

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:osgi="http://www.springframework.org/schema/osgi"
    xmlns:ctx="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
       http://www.springframework.org/schema/osgi
       http://www.springframework.org/schema/osgi/spring-osgi.xsd">

    <osgi:reference id="AlternateFacilityLookupService" interface="com.world.api.AlternateFacilityApi" />

    <bean id="MyAlternateFacilityBean" class="com.awesome.AlternateFacilityLookup">
        <property name="apiLookupBean" ref="AlternateFacilityLookupService" />
    </bean>

Upvotes: 2

Christian Schneider
Christian Schneider

Reputation: 19606

Not sure if you can make this work at all but it is definitely not recommended to import a spring xml in another bundle.

Better export the bean as a service in the first bundle and refer it as a service in the second. This will also decouple your bundle in a better way.

Upvotes: 2

Related Questions