Integration Akka with Spring and OSGI (No configuration setting found for key 'akka') - spring

I'v added one Akka actor to my app that works with Spring and OSGI.
I try to use Actor from Spring #Component bean like this:
private final ActorSystem system = ActorSystem.create("actor-system");
private ActorRef managerActorRef = system.actorOf(Props.create(ManagerActor.class), "ldapManagerActor");
When I start the app it throws an exception (No configuration setting found for key 'akka'):
Instantiation of bean failed; nested exception is org.springframework.
beans.BeanInstantiationException: Could not instantiate bean class [com.myconpany....ByBean]: Constructor threw exception; nested exception is com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'akka'
I've look at this: doc. And seems the root of my problem is related to class loader that I should pass to/for akka-system and application.conf file that describes this.
But I could not find appropriate stets to make it all working so far.
Could someone help?
My tries:
Flowing this article.
When I put:
<bean id="actorSystem" class="akka.actor.ActorSystem" factory-method="create" scope="singleton"></bean>
I have the similar error:
Could not autowire field: private akka.actor.ActorSystem
com.typesafe.config.ConfigException$Missing: No configuration setting fou
nd for key 'akka'

If you just want to use Akka actors you don't need to pass in application.conf settings. You can just use the default. Make sure you have the config library on your class path.
You didn't mention what version of Akka youre using, however if you grab the latest Akka 2.2 RC you can use an IndirectActorProducer to handle the spring wiring.
See this article on how to do that; http://blog.nemccarthy.me/?p=272
You should also tell Spring to call shutdown on the ActorSystem to cleanly shutdown. There is also an updated guide on how to integrate the ActorSystem into Spring or a web app here

Related

Spring Boot + Spring Integration Java DSL + AOP : Fails to proxy the Gateway interface

Hi I have a spring boot application, which starts a spring integration flow, through a gateway interface, using Java DSL. Everything works fine on its own. I added AOP to capture exceptions, with #EnableAspectJAutoProxy(proxyTargetClass = true)
At this stage, it gives the error:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jobInitiator': Post-processing of
FactoryBean's singleton object failed; nested exception is
org.springframework.aop.framework.AopConfigException: Could not
generate CGLIB subclass of class [class com.sun.proxy.$Proxy54]:
Common causes of this problem include using a final class or a
non-visible class; nested exception is
java.lang.IllegalArgumentException: Cannot subclass final class class
com.sun.proxy.$Proxy54
When I remove the proxyTargetClass = true, it works but the advices are not triggered.
Any help? Is there a way to start the spring integration flow without a gateway?
There is no class associated with the gateway Proxy so you can't advise it.
Is there a way to start the spring integration flow without a gateway?
Instead of using the gateway, declare a bean of type MessagingTemplate and use template.sendAndReceive(someMessage) or template.convertSendAndReceive(somePojo) instead. See here.
(The gateway uses a MessagingTemplate internally; the gateway unwraps a MessagingException and throws the cause, the template does not).
It also does not support an error channel.
To get closer to the gateway functionality, you can subclass MessagingGatewaySupport and invoke its sendAndReceive() method(s).

How to use inject resource from server (like ManagedExecutorService) in Junit-Test of Spring

I use ManagedExecutorService for concurrency in my code like this:
#Resource
private ManagedExecutorService defaultManagedExecutorService;
It works fine if I build them and deploy them on my server, because the i reference the resource ManagedExecutorService on the server:
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" core-threads="5" max-threads="25" keepalive-time="5000"/>
But I have my Junit test based on Spring. And to run this test I don't need any server. So I got the following exception:
Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.enterprise.concurrent.ManagedExecutorService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#javax.annotation.Resource(mappedName=, shareable=true, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)}
It seems that the spring can not find my resource from the server.
What can I do now?
Thank you!
You need to "mock" that functionality, meaning simulate the real deal with a similar implementation that doesn't actually go to the server and retrieve the JNDI resource, but uses a fake result.
There is a package in Spring that offers some functionality for testing JNDI resources, you can find its source code here.
To get started with using classes in that package, I would look at Spring's own testing classes where those JNDI mocking classes are used. For example, see here how those classes are used to test a JTA transaction manager.
I haven actually used this, but I would try something like this:
import static org.mockito.BDDMockito.*;
....
ManagedExecutorService mes = mock(ManagedExecutorService.class);
ExpectedLookupTemplate jndiTemplate = new ExpectedLookupTemplate();
jndiTemplate.addObject("java:jboss/ee/concurrency/executor/default", mes);
...
Or you can take a look at this for another testing class that needs to mock a ManagedExecutorService.

How can I access Spring bean from Message-driven bean in JBoss AS 7

I want to make a call to a Spring bean (a #Component) from my message-driven bean (MDB) but have problems getting a reference to it. I've tried with a class implementing org.springframework.context.ApplicationContextAware which stores the Spring ApplicationContext in a static field in a class MyAppContext. The static field in MyAppContext is then accessed from the MDB. But MyAppContext is loaded from different classloaders. The Spring application context is correctly set in the web module classloader context, but in the MDB's classloader context, it's null.
Can I somehow instruct JBoss to use the same classloader for the web app and the MDB?
Or is there a better way than storing the Spring application context in a static field?
Thanks for any advice!
A static holder for the context is not really a good idea. To make your beans available to other applications in a Java EE environment, you should consider making use of JNDI.
Unfortunately, there is no plain JNDI exporter available out of the box, but it's fairly easy to write one yourself, as shown in this blog post: http://maestro-lab.blogspot.ro/2009/01/how-to-export-spring-managed-bean-to.html
There is however a JndiRmiServiceExporter that you may want to look at.
Once your beans are bound to names in JNDI, they can be referenced using standard CDI in your message bean without worrying about class loading issues.
Why not use "ClassPathXmlApplicationContext" to load and look up for the Spring bean you require in your MBean?

Autowire annotation in JAX-RS and Spring

I am trying to add REST support to my Spring 3 + Hibernate application.
I have created the REST support using the wizard from Netbeans, at it has put a #Autowire annotation (not #autowired) above my Resource class. Getting the #Autowire annotation from Spring causes the error
incompatible types
found : org.springframework.beans.factory.annotation.Autowire
required: java.lang.annotation.Annotation
Getting #Autowire from JAX-RS should be only for Spring 2.5 as far as I understand from here. I get the following error if I include it, which I think is related to Spring 2.5 being loaded:
SEVERE: Exception while loading the app : java.lang.IllegalStateException:
ContainerBase.addChild: start: org.apache.catalina.LifecycleException:
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception
parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml];
nested exception is java.lang.NoSuchMethodError:
org.springframework.beans.MutablePropertyValues.add(Ljava/lang/String;Ljava/lang/
Object;)Lorg/springframework/beans/MutablePropertyValues;
Could someone point me on how to add this annotation, and make JAX-RS work with Spring? Also, I was using a SessionFactory and the autogenerated code refers to a entityManagerFactory in the applicationcontext. Can those be used interchangingly?
PS: Allow me to say that I hate Java EE with a passion so far in my three week journey with the platform, major stumbling blocks at every level, sorry for the rant.
You are using the wrong Autowire. The 'Netbeans REST wizard' looks like it would be using com.sun.jersey.api.spring.Autowire (last image, very bottom of page), and from your message above, you are using org.springframework.beans.factory.annotation.Autowire which appears to be an Enum used in Spring 2.0.
From what I can tell, this may be a specific thing to Spring 2.0 anyways. Perhaps you should take a look at doing the REST JAX-RS stuff yourself (using Jersey), as it is not that difficult.

Spring, using new ClassPathXmlApplicationContext and getting error being unable to find applicationContext.xml and others?

I am trying to follow this tutorial: http://www.vogella.de/articles/SpringDependencyInjection/article.html to use annotation dependency injection in my application. I set up the bean, etc like in the tutorial and then am trying to get an instance of the bean within my MainController class (a controller class that handles generating a specific page for my spring web mvc app).. I keep getting
SEVERE: Servlet.service() for servlet spring threw exception
java.io.FileNotFoundException: class path resource [WEB-INF/applicationContext.xml] cannot be opened because it does not exist
I am doing this in my MainController:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanFactory factory = context;
BeanIRPlus beanirPlus = (BeanIRPlus) factory
.getBean("BeanIRPlus");
IRPlusInterface irPlus = beanirPlus.getIRPlus();
I have searched and searched on this and yet to find an answer that fixes my problem. My applicationContext in in webapp/WEB-INF/ and my spring app seems to be working otherwise as it was handling requests, etc before this. I have tried putting the applicationContext.xml in WEB-INF classes but still nothing. Is there any workaround to make this not search the path this way as I think its doing a relative path search. Thanks for any advice
Not a direct answer, but here goes.
The tutorial you have referred is for dependency injection in a standalone application and not a web application. In case of web application, spring automatically loads the context files and initializes the beans. So you would not need any of the lines specified in the MainController.
Instead, you could do something like this to use beanIRPlus bean in your controller.
#Autowired
private BeanIRPlus beanIRPlus;

Resources