3

I have a data access module that provides implementations of repositories using Spring and JDBC.

Therefore, I define a Spring context as follows:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />

    <bean id="annotationTransactionAspect" factory-method="aspectOf" class="org.springframework.transaction.aspectj.AnnotationTransactionAspect">
        <property name="transactionManager" ref="transactionManager" />
    </bean>
</beans>

I also expose the repositories implementations as services using Declarative Services as follows:

<?xml version="1.0" encoding="UTF-8"?>
<component name="cdr-repository" enabled="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.osgi.org/xmlns/scr/v1.1.0 http://www.osgi.org/xmlns/scr/v1.1.0">

    <!-- Property and Properties -->
    <properties entry="OSGI-INF/myrepository-component.properties" />

    <!-- Service (optional) -->
    <service>
        <provide interface="com.example.osgi.dataaccess.api.MyRepository" />
    </service>

    <!-- Zero or more references to services -->

    <!-- Exactly one implementation -->
    <implementation class="com.example.osgi.dataaccess.jdbc.impl.MyRepositoryImpl" />
</component>

So, my services are created outside the Spring environment and therefore they are not fully configured (e.g. datasource is not injected).

I'm looking for the right way to integrate Spring with Declarative Services.

Thanks, Mickael

manash
  • 6,985
  • 12
  • 65
  • 125
  • If it is ok for you to leave spring out of the game, I can suggest a couple of configurable DS components that have the same functionality: DataSource, TransactionHelper, Transaction aware connection pool – Balazs Zsoldos Mar 13 '14 at 17:00
  • You could also have a look at Blueprint, which allows you to declare OSGi services using a Spring-style syntax. Using Apache Aries, it integrates with JPA and JDBC. – Holly Cummins Mar 14 '14 at 06:25

1 Answers1

3

Spring and Declarative services are not meant to be used together. So the approach you use will not work.Declarative services is a very simple framework that can only wire services into components and publish components as services. It has no capabilities regarding jpa. So I think DS will not be a good match if you want to use something like jpa with container managed persistence.

Like Holly mentioned blueprint supports that with the help of some other aries modules. I have created a tutorial that shows how to use this in a complete example. See: http://liquid-reality.de/pages/viewinfo.action?pageId=6586413

The blueprint approach is very different from how spring does jpa and container managed transactions. In spring you normally create the datasource in your context and inject it. In blueprint you work more like in standard jpa. There the datasource is referenced in persistence.xml and looked up using jndi. Aries jndi then bridges from jndi to OSGi services so another bundle can offer the datasource as an OSGi service.

The other option you have is to use spring dm to create jpa services the "spring way". But spring dm is not maintained and has a lot of problems in OSGi. So blueprint is currently the best way to go.

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64
  • Thanks for your answer, I used Eclipse Gemini (previously Spring DM) until now but I've heard many rumors like it's not maintained and doesn't handle well service tracking. So, I've started looking at DS and I encountered an integration issue with Spring. I asked on the Eclipse Gemini forums and they say it is maintained and they are closed to release 2.0.M3. I used it until now and I didn't see any issue. Also, Apache Aries doesn't seem to be more active. – manash Mar 16 '14 at 07:29
  • I somehow doubt that gemini blueprint is still active. See http://git.eclipse.org/c/gemini.blueprint/org.eclipse.gemini.blueprint.git/stats/?period=q&ofs=10 Not sure how active aries blueprint is. – Christian Schneider Mar 16 '14 at 08:34
  • @ChristianSchneider I believe your link is not working http://liquid-reality.de/pages/viewinfo.action?pageId=6586413 – Gamby Jul 26 '17 at 14:27