Access beans defined in spring context files of other osgi bundles - spring

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"/>

Related

Spring transaction management and 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.

Camel - Using beans available in jar

I am using Spring's Application context for bean registry. I will be dependent on external jars for some services, which will be a part of routes.
Is there any way to let camel auto-register the beans that are available in the jar?
No, but you can call any java class from Camel using its bean component. You can specify a class name, and a method to invoke.
You can use the beanType attribute
<bean beanType="com.foo.MyClass" method="someNameHere"/>
Or in an uri
<to uri="bean:com.foo.MyClass?method=someNameHere"/>

akka-camel 2.2.1 route definition using Spring XML

I am using akka-camel 2.2.1 and need to configure routes to and away from Consumer and Producer actors, respectively. I am currently defining routes and adding them to the internal Camel context within the CamelExtension programmatically like so:
camel.context.addRoutes(new RouteBuilder {
def configure() = {
from("file:/tmp?include=whatever.*.log&noop=true&sendEmptyMessageWhenIdle=true")
.split(body(classOf[String]).tokenize("\n"))
.streaming()
.to("seda:input-route")
from("seda:update-route")
.to("bean:db-update-bean?method=process")
}})
I have an Actor that extends Consumer which reads from "seda:input-route" via its endPointUri, and another Actor that extends Producer that writes to "seda:update-route". The "db-update-bean" in defined in a Spring applicationContext.xml like so:
<bean id="db-update-bean" class="nz.co.whatever.DBUpdate">
<constructor-arg ref="jdbcTemplate"/>
<constructor-arg value="some_other_constructor_arg"/>
</bean>
The Spring context is loaded and started in a supervisor Actor started by akka.Main. However (and understandably), Camel is unaware of this Spring context, and thus went to great lengths to inform me that it had no clue what the "db-update-bean" was:
2013-10-11 08:55:09,614 [SedaConsumer ] WARN Error processing exchange. Exchange[Message: 1378642997698,27684,true,57.000000,0.750000,97]. Caused by:
[org.apache.camel.NoSuchBeanException - No bean could be found in the registry for: db-update-bean]
Of course, I could programmatically add the components to the akka-provided CamelContext, or else do something like this:
from("seda:update-route")
.bean(new DBUpdate(jdbcTemplate, "gps_temp_status"), "process")
but I would rather use Spring to define beans. Clearly, the CamelExtension needs to use the Spring-defined CamelContext rather than creating one of its own.
Furthermore, and more importantly, I would like to externalize the definition of the Camel routes into the same applicationContext.xml within a <CamelContext/> tag. Accoring to articles such as https://weblogs.java.net/blog/manningpubs/archive/2013/02/13/akka-and-camel, it seems the way to do so is to instantiate a "camel-service" bean and inject the Spring-defined CamelContext as so:
<camel:camelContext id="camelContext">
</camel:camelContext>
<akka:camel-service id="camelService">
<akka:camel-context ref="camelContext" />
</akka:camel-service>
Here is where the wheels come off. According to Roland Kuhn's reply in Why spring integration doc for akka exists only for 1.3.1 but not for next versions, the akka-spring library is not included in Akka 2.2.1, and thus there is no Spring namespace handler for akka, and I'm unable to instantiate this camel-service bean. Though not for lack of trying. Or cursing.
And so (finally), the question: How does one define Camel routes in Spring XML whose endpoints can be used by Consumer or Producer Actors using akka-camel 2.2.1 without akka-spring? Does one instantiate a Factory bean that produces a CamelService with a CamelContext injected or some other such witchcraft? Secondarily (but related) how can I use Spring to instantiate beans to be referenced in camel routes if I am forced to define them via a RouteBuilder?
Thanks in advance.

what is the difference between <osgi:reference> and <osgi:service> in spring DM

what is the difference between <osgi:reference> and <osgi:service> in the xml config file of spring DM.
<osgi:reference> can be used to get a reference to existing OSGi service so your bean can use it.
<osgi:service> can be used to export a bean as an OSGi service so it can be used by others.

Best way to enable timer on Glassfish web profile

I use web profile and it does not allow to use Java EE #Schedule functionality. So, I have several ways to solve the problem:
reinstall the server to use full profile. Problems: it's risky (functionality/performance) for my production and burdensome
Use other scheduling functionality like Spring. Problems: I don't know how to link Spring with JavaEE as I want to use CDI beans in my scheduler. Seam-spring module could help me (http://sfwk.org/Seam3/SpringModule) but its documentation is not available at the moment and I don't really know the status of it.
So, which is the best way to enable scheduling inside my glassfish app?
Thanks
We've had a lot of luck using the Quartz open source job scheduler within Spring on other projects so I can highly recommend it for scheduling. You can configure the scheduler to be started from a Servlet (into which CDI beans can be injected) and the scheduled job can call an EJB Stateless Session bean (into which you can also inject CDI beans).
Here are some links - hope this helps!
Initialze a Scheduler in a servlet container
Here's a great article on calling an EJB from Quartz
Ok, I managed to do this using spring module. Would be better to use embedded Scheduler J2EE functionality, but this is not included into Glassfish web profile, only to full (WTF??). As my project is in prod, I don't want to upgrade to full one, especially as there is no flexible way to do this upgrade. Only full server substitute. Very poor JavaEE....
So, first, we need to define some functionality, which will be run at schedule:
#Scope(value="application")
public class ClosePolisesTimer {
BusinessAttirbuteDAO attributeDAO;
#Scheduled(cron="0 0 0 * * *")
public void doCloseObsolete() {
// ...
}
}
Second, we should create the spring configuration file with the following configuration:
<bean id="businessAttributeDAOBean" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:global/KaskoCalculator/BusinessAttirbuteDAO" />
</bean>
<bean id="ClosePolisesTimer" class="com.rstk.kasko.bean.service.ClosePolisesTimer">
<aop:scoped-proxy />
<property name="polisDAO" ref="polisDAOBean" />
<property name="attributeDAO" ref="businessAttributeDAOBean" />
</bean>
<task:annotation-driven scheduler="closePolisExecutor"/>
<task:scheduler id="closePolisExecutor" pool-size="1"/>
That's all. I define EJB beans and use "aop:scoped-proxy" to initialize my scheduler by them. Spring schedule is included into core spring module, so only core spring dependency is necessary

Resources