I need to inject a Spring bean into a Seam context. Unless I declare the spring bean as a EJB, I cannot get it injected into other seam-managed components. But when I do this, all the spring injected fields are usless cause Seam creates new instances at run-time.
I also tried to add the <seam:component/> element to the spring bean definition and tried to inject it in the container with the #In("beanId") annotation in the target class but I always end up with a NullpointerException...
EDIT:
I read the online articles and did as they say. My spring component is also added to the seam context (I can tell, cause when I define one with the same ID in seam, it complains). Looks like #In is not picking up....
Have you read this chapter? It should tell you exactly what to do.
Raoul,
Although i do not use Seam along with Spring, chapter 15 of Seam In Action books talks about Spring integration. It is free and is updated.
You have said
I also tried to add the element to the spring bean definition and tried to inject it in the container with the #In("beanId")
Seam in Action book says
The EL expression used in the #In annotation, #{tournamentManager}, resolves to an equivalently named bean in the Spring container, courtesy of the delegating variable resolver
Do you have to use #In("#{beanId}") instead of #In("beanId"), do not ?
I have seen
By default, <seam:component/> will create a STATELESS Seam component with class and name provided in the bean definition.
<bean id="someSpringBean" class="SomeSpringBeanClass" scope="prototype">
<seam:component/>
</bean>
And
The scope attribute of <seam:component/> may be used if you wish the Spring bean to be
managed in a particular Seam scope. The Spring bean must be scoped to prototype if the
Seam scope specified is anything other than STATELESS.
Have you done as above ?
I have a project using Seam + Spring and I have to set #In(create=true) when I want to inject a Spring bean into my Seam component otherwise I get a NullPointerException, you should try it.
I got the same problem as yours. I followed strictly the "Chapter 27. Spring Framework integration" in seam ref. document. But my spring bean was never got injected to seam component. And finally, I found out I had the #BypassInterceptors in my seam component. By removing that annotation, my spring bean was successfully injected. Then I realized that, dependency injection is handled by seam BijectionInterceptor. Thus, the #BypassInterceptors will effectively bypass this filter :)
Related
I know that Quarkus does dependency injection at build-time. The problem is the following:
Let's say I have a bean which has some of its fields annotated with certain annotation. I want to do something with this bean before it gets injected in other beans. Is there a workaround for this or not? Where should I start?
In Spring (Boot) I would probably use BeanPostProcessor, but I coudln't find anything like this in Quarkus
Using Spring Boot 1.5.12, we create scoped proxies for #ConfigurationProperties beans. We do this so that we can effectively have property values that are scoped to the user/session/etc. We use a BeanFactoryPostProcessor to register a scoped proxy created by ScopedProxyUtils.createScopedProxy and change the scope of the target bean definition to our custom scope.
This worked great in Spring Boot 1.5.12. However, in Spring Boot 2, the introduction of the Binder API has made this stop working. This is because when Spring Boot binds #ConfigurationProperties in its ConfigurationPropertiesBindingPostProcessor, it uses Bindable.of(type).withExistingValue(bean) passing in a type (e.g. org.example.Foo) and the bean which is an instance of ScopedProxyFactoryBean. Bindable checks that bean is an instance of type which it's not and things blow up.
Does anyone know of a general way to accomplish this? Specifically, to replace the #ConfigurationProperties bean definition with a proxy while still allowing the properties to bind to the instance? I've considered delaying the creation of the proxy until after the target has already been bound by ConfigurationPropertiesBindingPostProcessor (i.e. in my own BeanPostProcessor). However, at this point the bean is instantiated and my proxy can only replace the bean. It can't really leave the original bean in the context as a target. So I'm struggling with how to do this using a BeanPostProcessor.
EDIT: I've created a simple example project that demonstrates the issue (with the ability to check out code that works on Spring Boot 1 and fails on Spring Boot 2).
I'm testing my application using junit and OpenEJB container to provide context for my beans. It's finding all beans from classpath and starting them. Unfortunatelly there are some beans I would like to remove from context, so I can replace those beans with other implementations, mocking certain functionalities.
I'm aware of openejb.deployments.classpath.exclude property.
I even tried to use it as follows properties.put("openejb.deployments.classpath.exclude", ".*/CommonCache.*"); as it was sugested in this SO question.
OpenEJB sees this property but bean is still starting as shown in logs below.
Using 'openejb.deployments.classpath.exclude=.*/CommonCacheBean.*'
Auto-deploying ejb CommonCacheBean: EjbDeployment(deployment-id=CommonCacheBean)
Jndi(name="java:global/ejbs/CommonCacheBean!my.package.ICommonCache")
Created Ejb(deployment-id=CommonCacheBean, ejb-name=CommonCacheBean, container=Default Stateless Container)
So there is my question. Is there a way to exclude single bean(s) from OpenEJB context? It doesn't matter to me if it will be achieved this config way or by manual operations in java code.
If anyone is interested i didn't manage to remove beans from context. Although there is an unbind() method in context it does not seem to work on OpenEJB context.
I succeded in replacing beans manually with rebind() but it was too late because they were already injected into another beans.
They way i solved my problem was by using annotaion #Alternative on mock implementation. I also had to add entries in beans.xml to show container those beans and change the way I inject them from #EJB to #Inject.
This question already has answers here:
When is it necessary or convenient to use Spring or EJB3 or all of them together?
(2 answers)
Closed 3 years ago.
I need some clarification. I know how to work with JSF and its corresponding session beans, but i am getting confused with EJB. What is the difference between the beans introduced with EJB and the session beans used with JSF (for ejb i know about the stateless/full session beans and entity beans, entity manager, etc.). What i just dont get is when to use EJB and when to use jsf beans. Aside from the entity beans, both the ejb stateful/less session beans seem similar to the jsf session beans. I've read about injection ejb's into jsf, but why not just use ejb in conjunction with jsf beans? I hope you can understand my confusion. Thank you.
First of all, we need to know about the difference between JSF and EJB beans.
JSF beans are POJO classes which used to read the component value of JSF. There are two type of beans in JSF:
Managed bean is about how a java bean is created and initialized. As you know, JSF uses the Lazy initialization model. It means that the bean in the particular scope is created and initialized not at the moment when the scope is started, but on-demand, i.e. when the bean is first time required.
Backing bean is about the role a particular managed bean plays. This is a role to be a server-side representation of the components located on the page. Usually, the backing beans have a request scope, but it is not a restriction.
EJB Bean is a server-side component that encapsulates the business logic of an application. The business logic is the code that fulfills the purpose of the application.
Mainly, there are three types of session beans:
1.Statefull session bean
2.Stateless session bean
3.Singleton session bean(ejb 3.1)
There is indeed some confusion between the different types of managed beans in Java EE. To add to the confusion, Java EE 6 has introduced a third kind of managed bean: a CDI bean.
In this answer I try to explain the differences and similarities a little: How do CDI and EJB compare? interact?
Briefly said, JSF managed beans mainly don't offer support for transactions, which is something you often need when working with business logic and especially JPA.
Also note that the term session as in session scoped managed beans is a completely different kind of session than the one the term in stateless and statefull session beans refers to.
There is another gread answer on the site where the differences of CDI and EJB are explained. It helps a great deal when you finally grasp the whole picture. Where to use EJB 3.1 and CDI?
I want to use an EJB3 from within my Tapestry Page class, I can do JNDI lookup for it, but it will me much convenient to use EJB injection or Tapestry IoC. Is that possible?
Of course! You can either contribute your EJBs via Tapestry's IOC container, so you would do the JNDI lookup in your build methods instead of all over your code (see the manual for information).
Or you could wire up your EJBs as Spring beans (see the Spring EJB documentation for details), and use Tapestry-Spring to allow injecting them into your components via #Inject.