OpenEJB - exclude single beans - java

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.

Related

What's the relation between CDI and JNDI service?

As far as I understand "pre-CDI" EJB and resources injection solutions (#EJB, #Resource and others, to be clear) use the JNDI service to locate objects "known" to the container by virtue of being JNDI registered, and then inject them where requested.
CDI, instead, relies on bean-discovery-mode parameter (ALL or ANNOTATED) to discover beans that need to be managed. But how is this process actually performed? A runtime scan of... what? Is JNDI not involved at all?
I have the feeling I'm getting something wrong about the whole mechanism...
The bean discovery process is described in detail in the CDI specification. Basically, the CDI container scans bean deployment archives for classes with certain annotations.
JNDI is not involved at all. Unlike EJBs, CDI beans cannot be looked up via JNDI in general.
Only the BeanManager itself can be looked up under the name of java:comp/BeanManager, but this is almost never required, unless you need to access managed beans from unmanaged code.

How to use #Resource annotation in servlet (or in any other Java class)?

I am experimenting with Java Dependency Injection. Many questions here on SO talk about jndi resources being wired. But I think, a java class can be wired using #Resource annotation. I have a simple servlet in which I have two properties to be wired using CDI. I am using Tomcat6, Servlet 2.5, and Weld configuration.
The servlet code:
#Inject
private HikariConnectionProperties hikariConnectionProperties;
#Resource(name = "connectionProvider")
private IConnectionProvider connectionProvider;
However I get the code compiled, deployed. But, when there is a request for the corresponding servlet I get javax.naming.NameNotFoundException: Name connectionProvider is not bound in this Context.
But, I have #Named annotation for the ConnectionProvider class. The same configuration works with #Inject for both the fields.
So, my first question is how can I fix this issue? And is there any way that I can specify scope for a particular injection(using only annotations of JSR) without using Spring's #Scope? Any example is a great help as I am a newbie to CDI.
#Resource only works in Tomcat when you set up a resource in your container. Here's a reference for your own sake: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
It expects that you're binding a JNDI entry called "connectionProvider" in Tomcat. CDI does not bind elements to JNDI, it has its own internal mapping of objects to scopes. #Inject works here as you likely have not setup a resource for this class in your resource configuration.

Update spring beans dynamically. Is it possible?

Is there a way to update a Spring bean dynamically if the spring beans configuration changes?
E.g. assume that I have a spring bean with boolean property x and the spring beans has the value true when the application starts.
So spring creates the bean with the property x set to true.
Is there a way so that if I changes the property to x (while the application is running) that the property will be updated e.g. to false?
Calling the setter for x setX() method will do that.
But it should not be a prototype bean.
it is possible with the jrebel-spring integration. it monitors your configuration and TRIES to re-wire your beans at runtime.
Though i would not use it in production...only for playing around, testing etc
Spring reads configuration files at startup. If you really need to update configs while application running, you should manually implement all the chain: detecting config changes, validating config, detecting changed beans, updating beans in context.
Spring beans can be initialized using applicationContext.xml or even programatically. In your case; you will need to remove configurations from xml and add into java program. You can get some idea from How to programmatically create bean definition with injected properties? . Other good links were also available on google.

How do I Spring enable a Tomcat valve

I wrote a Tomcat valve and configured it in server.xml.
So far so good. However, I want one of the valve's data members to be a Spring managed bean.
So, how can I make the valve also be Spring managed so that I can have Spring's IoC inject that dependency into the valve?
Valves aren't associated with an application, while spring contexts are. So you can't have a spring-managed bean in a Valve.
You can, of course, instantiate the spring context in the Valve constructor, and use context.autowireBean(this) there, but this will be a separate spring context, not one from any of the contexts available.
Technically, you have access to the contexts from the Valve, but afaik it is from the request, so you can obtain the ApplicationContext for each servlet context, and from there - get a reference to a bean, but that sounds odd.

How to inject a Spring bean into a Seam context?

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

Categories

Resources