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

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).

Related

#EnableAutoConfiguration(exclude =...) on tests failed in Spring Boot 2.6.0

I tried to upgrade my data-mongo example project to Spring Boot 2.6.0. There is a test designed to run against Testcontainers, I also included the embedded mongo dep for other tests, so I have to exclude the AutoConfiguration for embedded mongo to make sure this test working on Docker/testcontainers.
The following configuration worked well with Spring Boot 2.5.6.
#DataMongoTest
#ContextConfiguration(initializers = {MongodbContainerInitializer.class})
#EnableAutoConfiguration(exclude = EmbeddedMongoAutoConfiguration.class)
#Slf4j
#ActiveProfiles("test")
public class PostRepositoryTest {}
But after upgrading to Spring Boot 2.6.0 and running the application, I got the exception like this.
[ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: o
rg.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'embeddedMongoServer' defined in class path resource [org/springframework/boot/autoconfig
ure/mongo/embedded/EmbeddedMongoAutoConfiguration.class]: Unsatisfied dependency expressed through method 'embeddedMongoServer' parameter 0; nested exception is org.springframework.bea
ns.factory.BeanCreationException: Error creating bean with name 'embeddedMongoConfiguration' defined in class path resource [org/springframework/boot/autoconfigure/mongo/embedded/Embed
dedMongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.flap
doodle.embed.mongo.config.MongodConfig]: Factory method 'embeddedMongoConfiguration' threw exception; nested exception is java.lang.IllegalStateException: Set the spring.mongodb.embedd
ed.version property or define your own MongodConfig bean to use embedded MongoDB
Obviously, #EnableAutoConfiguration(exclude =...) did not affect the context in tests when upgrading to Spring Boot 2.6.0.
Update: Temporarily resolved it, see my answer below.
Just add:
#TestPropertySource(properties = "spring.mongodb.embedded.version=3.5.5")
annotation before your Unit Test and it will start working.
#Henning's answer has a good explanation of why you need this.
As of Spring Boot 2.6, the property spring.mongodb.embedded.version must be set to use the auto-configured embedded MongoDB. It's mentioned in the release notes: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#embedded-mongo
This is also what the error message you posted, advises to do: Set the spring.mongodb.embedd ed.version property or define your own MongodConfig bean to use embedded MongoDB
The annotation #DataMongoTest is meta-annotated with #ImportAutoConfiguration and #AutoConfigureDataMongo, and is designed to trigger auto-configuration of MongoDB unless explicitly disabled as you do in the working configuration examples.
In your first configuration example, the annotation #EnableAutoConfiguration(exclude = EmbeddedMongoAutoConfiguration.class) does not override this effect of #DataMongoTest.
With Spring Boot 2.5.6, the auto-configured MongodConfig bean is most likely also part of the application context but not effectively used. But this depends on the rest of the code and in particular on the MongodbContainerInitializer.
Use #ImportAutoConfiguration(exclude = ...) or #DataMongoTest(excludeAutoConfiguration = ...) on test classes to overcome this barrier when upgrading to Spring Boot 2.6.0.
#DataMongoTest
#ImportAutoConfiguration(exclude = EmbeddedMongoAutoConfiguration.class)
//other config are ommitted
public class PostRepositoryTest {}
//or
#DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
public class PostRepositoryTest {}

Hazelcast throwing exception in spring boot application with vaadin 8 using openfeign

We have a web application with Vaadin 8, Spring Boot 2.1.3 and Open Feign.
Now Hazelcast should be integrated for session replication.
I was following this article.
The Problem: with Open Feign an exception is thrown in the InvocationHandler: NotSerializableException, so I implemented my own InvocationHandlerFactory setting my own InvocationHandler that is implementing the Serializable interface.
Now in the InvocationHandler the same exception is thrown:
com.hazelcast.nio.serialization.HazelcastSerializationException: Failed to serialize 'org.springframework.session.MapSession'**
com.hazelcast.nio.serialization.HazelcastSerializationException: Failed to serialize 'org.springframework.session.MapSession'
Caused by: java.io.NotSerializableException: java.lang.reflect.Method
The problem is: java.io.NotSerializableException: java.lang.reflect.Method
Method is final so it cannot be made serializable.
Is there a way to tell Hazelcast not to try to serialize certain classes?
Any workaround?
I already tried to use the ApplicationContext to avoid serialization of open feign classes but it´s not possible because the open feign clients need to be session scoped.
You are probably injecting a Feign client in a UI component, right? If so, the same happened to me when I implemented that example and I solved it by creating the Services class you can see in the article. Instead of directly injecting beans that are Feign clients or that have references to them, you can call the static methods in the Services class.

Spring boot rabbitmq integration problems

i am attempting to do this tutorial on springboot with rabbitmq integration.When i declare the receiver bean i cannot Autowire the AnnotationConfigApplicationContext bean making my whole receiver class unusable as i declare it as a bean in the main method class.
The whole tutorial is in the link below.
https://spring.io/guides/gs/messaging-rabbitmq/
Thanks..

Dependency Injection With Factory Methods

I'm fairly new to the the Spring and I'm trying to move our legacy code to spring.I'm trying to auto inject all the dependencies by using #Autowired.
My Bean has a factory method as follows:
public static Service getInstance(Registration registration) throws Exception {
Service service = null;
switch(registration.getType()) {
case XServer :
service = new XServer(); break;
case YServer :
service = new YServer(); break;
default :
service = new XServer(); break;
}
service.setRegistration(registration);
return service;
}
But when I use new in the factory method all the dependencies in the new class remains uninitialized. Also if I use appContext.getBean('beanname') it throws following exception:
Requested bean is currently in creation: Is there an unresolvable circular reference?
Can some one help me understand how to do it correct.
If I understand you right, then you are trying to instantiate the factory manually via the new command. But the Spring framework must register the beans, when you are trying to use them in the ApplicationContext. You have to create a Factory Bean which provides the creation of common other objects. These objects also have to be registered to the
Spring config of your application.
Have a look at the Spring documentation
That means you have to define somewhere in your application beans of following types: XServer, YServer and the type of your Factory Bean. Furthermore you should have a look at Method Injection, because you are trying to create beans with different scopes.
I've had a similar problem, but found this question helpful: Inject spring dependency in abstract super class.
It's not exactly the same, but it handles the point of inheritance. Note that it's using XML instead of annotations.

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

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

Resources