JEE6 : Alternative EJB declaration - ejb-3.0

I'm using JBoss 7.1.1 with CDI.
I've got a Stateless bean named ServiceAccount in JNDI. This is the real service implementation.
I've got another Statelss bean named ServiceAccountMock which is a Mock service.
The both herited from the same interface and are packaged in a service.ear.
What I want to do is to declare the mock service as alternative in bean.xml, redeploy my services ear, and then all the client see the mock version (without changing anything on client side).
When I deploy my service.ear, JBoss says :
java.lang.IllegalArgumentException: JBAS011046: A component named 'ServiceAccount' is already defined in this module
This is true, both services are declared the same way (#Stateless(name="ServiceAccount")).
If I change the name of the mock version, I have to change on client side which EJB is used (and I don't want to do that).
Does anyone know how to do that ?

I don't think you will be able to deploy 2 beans with the same name in the same application.
If the clients of the bean are only local, you should use CDI type injection selection.
Remove the name of the beans or put different name if you realy need a name (The mock will have a different name that the real implementation).
Keep the #Alternative annotation on the mock.
At the injection point, use the interface as the type of variable (and probably using the #Inject annotation instead of the #EJB one may help).
The EJB specification and CDI aren't yet completly aligned. EJB has some element like the name that need to be unique over the application and is not taken into account in the CDI alternative functionaltity.
So I don't think you will be able to mix EJB name injection selection and CDI alternative injection selection.

First you need to annotate ServiceAccountMock with #Alternative, to tell the container not to use it if not instructed to.
#Stateless(name="ServiceAccount")
#Alternative
public class ServiceAccountMock{
....
}
Then in beans.xml you need to tell the A/S to pick the mock implementation:
...
<alternatives>
<class>xx.yy.ServiceAccountMock</class>
</alternatives>
...

Related

Spring managed vs non-managed beans

I have a simple Result data holder object that gets returned from a method.
I'm confused on what the right way of using or creating this object using Spring boot.
Should this class be marked with #Component annotation?
Can I just create this object using 'new Result()' or should I autowire and use it?
If I use 'new Result()' then this instance will not be managed by Spring. Is that understanding correct? What are the advantages or disadvantages of managed vs non-managed beans.
Thanks,
Sudha
If I use 'new Result()' then this instance will not be managed by Spring. Is that understanding correct? What are the advantages or disadvantages of managed vs non-managed beans.
Well the greatest difference is the Inversion Of Control IoC (aka Dependency Injection DI). If Result is managed by spring, you can autowire other spring beans (like services, components, repositories and so on) Moreover you can autowire the Result bean in other spring beans. More details can be found here
Can I just create this object using 'new Result()' or should I autowire and use it?
Well it depends on your scenario. For example if you have a JSON response in a Spring controller, well in this case it's better to use a classic POJO and create it because it depends on your business logic.
On the other side id your bean is a kind of service who can be used in other points of your project because it offers some methods, well in this case I guess it's good to autowire it and make it as a spring bean
Should this class be marked with #Component annotation?
Well as I said earlier it depends on your scenario. In the case you described (result of a method) maybe it's better to use a classical POJO. But you didn't provide enough information

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?

Dynamic dependency injection in jsf 2 or spring 3

I have 3 implementations of an interface, and in order to instantiate one of them I need to check a parameter from the database.
I was planning to do it with the factory pattern, but since I'm using JSF 2 dependecy injection in the rest of my application I was wondering if
there's a way to do that, is it possible to do the dependency injection dinamically?
can I indicate somehow a method or something to pick up the correct implementation at each moment?
For the backend I'm using spring core, so a way to do that with the spring context would work to.
I'm using Annotations for everything (#Autowired for Spring, #ManagedProperty for JSF).
EDIT: The project will be deployed on a Tomcat server.
I suggest you to use CDI in your JSF project, you can then use programmatic injection.
You should start with adding CDI Qualifiers to your interface implementations (you will basically create custom annotation for each implementation - tutorial). Then you can use something like
#Named //similar to ManagedBean
#RequestScoped
public Bean {
#Inject
#Any
Instance<YourInterface> yourInterface;
public void someMethod() {
if(someCondition) {
InterfaceImpl impl = yourInterface.select(new SomeOfYourQualifiers()).get();
}
}
}
Source
Also you you don't have to use Autowired in favour of Inject. I am also sure that there is some Spring way how to to this but I will leave that to some Spring expert here:-)
EDIT
According to this answer is really possible to run CDI on Tomcat. You will also find some tutorials like this one. And Spring approach could be using AutowireCapableBeanFactor but as I say, I don't know Spring much so it's just a wild gues:-)

Dependency Injection Failover in Spring

Is it possible to specify another bean to inject in case that the first intended bean to be injected fails?
Lets say we have Bean1, Bean2, and Bean3. Bean1 requires Bean2 but if Bean2 fails to be injected for some reason, then I want Bean3 to be injected instead. But each time Bean1 is retrieved from the container, it should always try to inject Bean2 first before attempting to inject Bean3. Is this possible? If not, what are my options?
Per me the question is flawed. In normal circumstances, Spring is supposed to be used for injecting the beans declaratively. So as pointed out by #Don Roby, #Adrian Shum the problem you are trying to solve is not for Spring.
Spring is not designed to resolve the dependency for you dynamically like a Service Locator.

integrating spring 2.5.6 and Struts 1.3.8

I want to clear some moments about integrating spring and struts. I have only one action class per application extended from MappingDispatchAction. So, actually my app when doing something uses not Action objects, but methods from my action. All I want from spring is to initialize this action and all for now. Just simply set DAO object. I looked through documentation, but I don't understand following:
We use action path from struts-config.xml as a name of bean in action-servlet.xml. Okay, but am I supposed to write beans in action-servlet.xml for every path name and set this poor DAO ref or what ?
The Struts 1 config file will use the DelegatingActionProxy class as the type attribute for all action configurations.
The Spring config file will contain the bean definitions of each action implementation. I don't know what DAO you're talking about, but actions that require DAO or service injection need to have them listed, yes--that's what Spring configuration is.
You may also be able to use annotations if you're not interested in using XML configuration, or use bean inheritance if many beans share the same DAO/service/etc. property values.

Resources