Is PersistStateMachineHandler in spring-statemachine-recipes thread safe? - spring

I decleared PersistStateMachineHandler as a field in #Component Class in Spring Boot project. Which means method of class could be call concurrently.
However I found PersistStateMachineHandler#handleEventWithState or newer PersistStateMachineHandler#handleEventWithStateReactively stop, set state, then restart the state machine without any synchronization/locks. Is this method thread safe?

Related

How to verify #Blocking annotatio is working for quarkus

We are using quarkus framework and https://quarkus.io/guides/getting-started-reactive mentions that we can use #Blocking on a method, class to instruct Quarkus to invoke this method on a worker thread.
But how exactly can we verify it is using a worker thread?
You can call io.quarkus.runtime.BlockingOperationControl.isBlockingAllowed() to see if blocking on the thread is allowed.
If you have used #Blocking correctly, the call should return true

JPA transactional proxy within a thread issue

In my Controller I have injected (#Autowired) this Service, which implements Runnable (I need multi-threading) and I call it like so:
Thread t = new Thread(service);
t.start();
t.join();
Then, in my Service's run() I call this Repository (simple JPARepository), which is injected in Service also with #Autowired:
repository.save(someEntity);
The problem is that it doesn't persist the entity with id=1. The transactional proxy (and Hibernate connection pool) is initialized after the unsuccessful saving of the first entity. After that, it works fine.
Can anyone point me to the right direction with my issue: how to force the Thread to initialize the Hibernate transactional proxy before persisting the first entity?
You should consider to start the thread after Spring context is refreshed. This is safer because all your beans may be in an inconsistent state.
#EventListener(ContextRefreshedEvent.class)
public void handleContextStart() {
// ...
}

Jersey Exception Java 1.8

I am calling a REST service and the provider has supplied a client. Client's specification is to use Jersey 2.18. So i have used the below jersey dependencies
Jersey-client-2.18.jar
Jersey-common-2.18.jar
Jersey-entity-filtering-2.18.jar
Jersey-guava-2.18.jar
jersey-media-json-jackson-2.18.jar
I am making calls using scheduledThreadPoolExecutor and my application is running in tc server and JDK 1.8. Sporadically i get the below exception. I tried searching this exception in google but no luck. But i see the below for almost everytime
Cannot create new registration for component type class > org.glassfish.jersey.client.authentication.HttpAuthenticationFeature
Exception
java.lang.NullPointerException at
org.glassfish.jersey.model.internal.CommonConfig.configureFeatures(CommonConfig.java:694)
at
org.glassfish.jersey.model.internal.CommonConfig.configureMetaProviders(CommonConfig.java:644)
at
org.glassfish.jersey.client.ClientConfig$State.configureMetaProviders(ClientConfig.java:365)
at
org.glassfish.jersey.client.ClientConfig$State.initRuntime(ClientConfig.java:398)
at
org.glassfish.jersey.client.ClientConfig$State.access$000(ClientConfig.java:88)
at
org.glassfish.jersey.client.ClientConfig$State$3.get(ClientConfig.java:120)
at
org.glassfish.jersey.client.ClientConfig$State$3.get(ClientConfig.java:117)
at
org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:340)
at
org.glassfish.jersey.client.ClientConfig.getRuntime(ClientConfig.java:726)
at
org.glassfish.jersey.client.ClientRequest.getConfiguration(ClientRequest.java:285)
at
org.glassfish.jersey.client.JerseyInvocation.validateHttpMethodAndEntity(JerseyInvocation.java:126)
at
org.glassfish.jersey.client.JerseyInvocation.(JerseyInvocation.java:98)
at
org.glassfish.jersey.client.JerseyInvocation.(JerseyInvocation.java:91)
at
org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411)
at
org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:307)
I resolved this issue. My implementation was wrong. The client object was defined as a class level variable and it was initialized during every method call. During parallel call. every thread concurrent call attacks the same class level object and tries to modify and hence the object was not properly initialized. Now i fixed it by injecting the class from spring so that it is not modified during every call.

Where should i store thread dependent data within a receiving rabbitListener component in a multithreaded environment?

I'm using the annotation based approach of spring amqp in a multithreaded environment (i have multiple consumers => multiple rabbit listener containers).
#RabbitListener(queues = "tasks")
public void receiveMessage(#Payload Task task) {
// usage of httpClient here with its own httpContext (would be fine)
// this method gets called from different listenerContainers / threads
}
My component which contains the annotated receiveMessage() method needs to do some http calls with the apache http client. Since i'm working with multiple consumers at the same time, this method gets called from different threads and the apache http client documentation says that i should create a httpContext for each thread to be thread safe. Since all threads are calling the same component method i can't put the httpContext into the component.
Is there something like a listener container context for each listener container where i can put the httpClientContext? Or does somebody have an idea how to solve this easy? I thought about ThreadLocal or a central registry for httpContexts but it would be fine if this would be more easy.
There is nothing like that provided by the framework; the simplest solution is to store them in something like a LinkedBlockingQueue and check one out, use it, and put it back in the queue when you're done (creating one as necessary if the queue is empty).
ThreadLocal will work too, but I prefer to use a pool.

Exception BeanFactory must be set on AnnotationAsyncExecutionAspect to access qualified executor

I created a public method with #Async and I also have a bean for that class in which this method is created. But when I am calling it , it is not behaving async and getting blocked. Then I created a executor in application-bean and used #Async(value = “executorname”), even this is not working and on every call I am getting “beanFactory must be set on AnnotationasyncExecutionAspect to access qualified executor”.
in my application bean.xml I have
there are then few executors and schedulers and I want to use one new executor.
Please tell me how to get away with this error and get async behaviour
Thanks in advance
I was experiencing exactly the same issue and find out a solution I hope works for you (https://jira.spring.io/browse/SPR-10276).
Apparently if you unabled Spring's AspectJ aspects into your project (by using aspectj-maven-plugin, for instance), Spring's Async mechanism can be placed twice in your bean, one by aspectj and other by proxy. But, since it doesn't know it, AnnotationAsyncExecutionAspect will not be injected with a BeanFactory and you will see the assertion exception you had.
To fix it, you must instruct Spring's Async mechanism to use the AspectJ support. Do this incluing this in your Application Context.
<task:annotation-driven mode="aspectj"/>
I hope I could be of any help.
For annotation based configuration you can use #EnableAsync(mode = AdviceMode.ASPECTJ)

Resources