Spring transaction management and OSGi - osgi

I'm new to OSGi and I have an application that I would like to migrate to OSGi.
I've created one bundle that only consists of DAO interfaces. This bundle represents my DAO services.
I've also created a second bundle that provides implementations of the DAO interfaces using JDBC. This bundle registers one service per interface using Apache Felix Dependency Manager. This way, my services are accessible from other components.
My DAO implementation classes were annotated with the #Repository annotation for automatic classpath scanning, but now I use the OSGi service registry for service registration. Therefore, the services may be obtained by client code directly using Apache Felix Dependency Manager.
The methods of my DAO implementation classes are also annotated with the #Transactional annotation for transaction management. The issue is that the #Transactional annotations will not have any effect since the DAOs are not registered in any Spring container.
What is the right way for handling transactions when using OSGi? I don't want to use Spring programmatic transaction management.
Thanks,
Mickael

Take a look at Aries Blueprint with Aries JPA and JTA. You can configure it with blueprint like the following:
<bean id="jpaDao"
class="my.jpa.JpaDao">
<jpa:context property="em" unitname="persistence" />
<tx:transaction method="*" value="Required" />
</bean>
you'll also find a working sample at my github, the sample is at line 12 in the blueprint.xml.

Related

Is there an annotation equivalent to the Spring AOP aop:include configuration for autoproxies

When specifying the XML configuration below:
<aop:aspectj-autoproxy>
<aop:include name="myBean" />
</aop:aspectj-autoproxy>
We all know that the #EnableAspectJAutoProxy annotation is the equivalent to the aspectj-autoproxy XML configuration but is there a java-based annotation equivalent for the aop:include XML configuration? I searched extensively and could not find.
Normally you tell Spring that you are using a particular feature, like Transaction management and it will create the proxies needed.
For instance #EnableTransactionManagement will cause Spring to create proxies for Components (services, controllers and repositories) which use #Transactional, you don't need to declare this, Spring automatically finds the beans that need to be proxied.
It works the same way with #EnableScheduling causing Spring to detect #Scheduled methods, and #EnableCaching to detect #Cached method.

Access beans defined in spring context files of other osgi bundles

How can we access beans defined in Spring context files of one bundle into another?
Example might be ActiveMQ poolable connection factory: it doesn't make sense to define ActiveMQ connection factory in all the bundles.
One solution is to use OSGI service but Spring DM is decommissioned.
I guess you are looking for Gemini Blueprint: https://www.eclipse.org/gemini/blueprint/documentation/reference/1.0.2.RELEASE/html/index.html
Publish a service:
<osgi:service id="myService" ref="simpleService"
interface="org.xyz.MyService" />
Fetch a service:
<osgi:reference id="myService" interface="org.xyz.MyService"/>

Dependency injection with Spring (JSR 330 annotations) in WebSphere 7 is not working

I have an enterprise application built with Java 6, Spring Framework 3.1.2 and Mule-ESB 3.3.0, among other libraries not related to this question.
Our beans and services are all declared with #Named and #Inject JSR-330 annotations, respectively for automatic component scanning and for dependency injection (no EJBs, only service beans). When deployed into JBoss 4.2.3 (our test environment) everything works fine. However, when deployed into WebSphere 7, the JSR-330 annotations seem not to be working. The beans marked with #Named are just not detected, at all.
I can assure everything is configured right (since it is working in JBoss). Specifically, the <context:component-scan /> has the base-package attribute correctly defined and the scope-resolver attribute correctly configured to use Jsr330ScopeMetadataResolver (we tried without it too).
I am aware WebSphere 7 (7.0.0.23) may not support such kind of annotations. I am yet to test it with #Component and #Autowired Spring equivalents. Unfortunately, we would very much like to use JSR 330 annotations so our classes wouldn't directly depend on Spring, even though we're using Spring Framework under the hood.
Nevertheless, although I'd spent one full work's day looking for a definite statement that WebSphere 7 does not support JSR 330 annotations, I haven't found anything so far.
Further, I can't see why it would not work, since I'm assuming Spring Framework is the one doing all the work, through the <context:component-scan /> directive in the application-context.xml file.
Can anyone bring some light into this issue?
Is there a way to activate dependency injection via annotations in WebSphere 7?
If I switch back from the JSR 330 #Named / #Inject annotations to Spring's own #Component and #Autowired is it likely to work?
In a desperate attempt, can I extend Spring's ComponentScanBeanDefinitionParser so it will detect JSR 330 annotations even in WebSphere 7?
If nothing works, I will eventually fall back to plain XML configuration. That is highly undesirable, however, because there will be hundreds of beans to be manually configured in the XML.
WebSphere 8 seems to be the correct version to use; it supports EE6 (WebSphere 7 is EE5), which in turn contains CDI 1.0 (hence JSR 299).
Below is a snippet from DeveloperWorks that summarises relationship between WebSphere versions, JSR 299 and JSR 300
Dependency injection is a technology that has surfaced in various
implementations many times before making it into the Java EE world.
The Spring Framework and the Google Guice library are popular
implementations. In JSR 330, an attempt was made to include these
capabilities into the J2SE platform. JSR 299 is a specification that
used the APIs defined in JSR 330 and added more capabilities to
support Java EE needs. IBM WebSphere Application Server V8 and V8.5
(non-Liberty profiles) are fully compliant Java EE 6 containers and
implement JSR 299.
I eventually came up with a workaround by extending both Component Scan and Autowire features of Spring Framework.
First, I added an inclusion filter to the Component Scanner so that #Named annotations were also considered eligible for detection and registration to the Spring Container:
<context:component-scan base-package="com.mycompany.mysystem">
<context:include-filter type="annotation" expression="javax.inject.Named" />
</context:component-scan>
Following that, I also added a bean definition to org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcesso‌​r, extending the autowiring eligibility to #Inject annotations:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
<property name="autowiredAnnotationType" value="javax.inject.Inject" />
</bean>
Initially, this worked fine as to "reactivating" the #Named and #Inject annotations. However, I still had some problems of conflicting beans on the autowire candidates resolution process. This was due to the differences in the default resolution process of Spring and of JSR-330. This was no big issue, since only a few beans fell into that scenario. They were all solved by adding some strategically placed #Qualifier annotations.
Now everything is working fine and elegantly, with few extra configurations. Nevertheless, I still don't understand why this happened. All I know is that the following 3 lines do appear when I deploy the application into JBoss 4.2.3. On the other hand, they don't appear in WebSphere:
INFO [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] JSR-330 'javax.inject.Named' annotation found and supported for component scanning
and
DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
INFO [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
I still have no clue as to why this happens, since, as #Dreamer said, this should be a Spring's responsibility, and thus, out of WebSphere business.
If someone do have such a clue, please enlighten us. Im sure it would be wonderfully clarifying to everyone participating in this discussion.
Agree with duffymo, it should work on WS 7. As Spring is on top of Websphere so Spring annotation is out of webshere's business(sort of).
One thing you probably need to check on WS 7(even though you said every configuration is correct as it works on JBoss) is click your application -> click Class loading and update detection, make sure the Classes loaded with local class loader first (parent last) is checked. That would make the server to take your application's library come first followed by websphere's library.

How to inject service in JSF managed bean without using Spring IOC

Typically if I have to inject a service in Spring I use
<bean id="mycontroller" class="com.MyController">
<property name="myService" ref="myService" />
and
<bean id="myService" class="com.MyService"></bean>
How to do the same when using JSF? I dont want to use two IOC containers for the beans and rather keep it in faces context itself. I have seen links such as
JSF 2 inject Spring bean/service with #ManagedProperty and no xml
and A problem about injecting spring bean into jsf bean . They talk about injecting Spring managed bean into JSF context.
What I am trying to do must be really simple but am not able to find any relevant info. Am a newbie and will appreciate any help.
I think you may be confused by the word "bean".
The thing is, the "service" you are talking about is also a Spring bean, right?
You probably have it as a service cause it has some additional features (probably transaction management) added by Spring, according to your configuration.
The JSF IoC container is very simplistic, it does not allow you to configure its lifecycle to include transaction management, AOP and things like that. Those things you have to do with Spring (or EJB, in a Java EE environment).
So, when using JSF with Spring, you usually have two choices:
Either you put the backing beans for the JSF pages in the JSF container, annotating them with #ManagedBean, #RequestScoped, #ViewScoped, etc; and injecting any necessary Spring bean with #ManagedProperty in a property (a setter is required)
Or skip the JSF container and put the backing beans along with all others in the Spring container, and use the Spring scopes of request/session, annotating them with Spring's annotations #Component, #Scope("request"), #Scope("session") and injecting with #Autowired, #Qualifier and the like.
Personally, faced with that choice I'd go with the first choice, cause it gives you #ViewScoped and some other niceties. It's true it makes use of two IoC containers but then, which Java EE app does not?
If you want to go the second route anyway, you may also add a view scope for Spring beans, backed by JSF viewMap.
What Spring calls a "Service" is in Java EE terms an "EJB". EJB is out the box available in Java EE web profile containers like Glassfish, JBossAS and TomEE.
To create a stateless EJB service, just use #Stateless on the class:
#Stateless
public class SomeService {
public void doSomething() {
// ...
}
}
And to inject it in a JSF managed bean, just use #EJB on the property-to-be-injected:
#ManagedBean
#ViewScoped
public class SomeController {
#EJB
private SomeService service;
}
That's it. No getter/setter necessary. No XML boilerplate necessary.

Recommended way to access Spring beans in Apache Tomcat webapp?

I'm developing a web application on Apache Tomcat 6 with Hibernate and Spring, I'm using different XML configuration files to define my Spring beans (like the Hibernate DAO, Quartz scheduler and some other stuff). All these files are loaded at Tomcat start up via web.xml (ContextLoaderListener).
Now I'm not sure what is the recommended way to get access to my beans.
Should I write on class which provides the BeanFactory for all classes which should use a bean, or is it the better way to load the BeanFactory in each class.
BeanFactory bf = (BeanFactory) ContextLoader.getCurrentWebApplicationContext();
One of the core ideas of the spring framework is to minimize dependencies between classes. You'll get the most benefit by using this concept throughout your whole project. Each and every backend object should be defined as bean and can therefore use the dependency injection automatism.
If some of your Beans need to access the ApplicationContext directly (eg for requesting all Beans implementing some marker interface) you can implement the ApplicationContextAware interface, so still no factory is needed.
Use dependency injection instead. Create getters & setters in each controller class, and use your *-servlet.xml to inject the required beans via the <property> tag. No factory needed!

Resources