JavaEE 6: #EJB(beanInterface="") - annotations

Could someone help me understand the use of beanInterface parameter of #EJB annotation in JavaEE 6?
I have a situation in which I have an EJB and I want it to be accessed locally and remotely as well.
I have a MyBaseInterface and then both MyEJBLocalInterface and MyEJBRemoteInterface extending MyBaseInterface. Now I have MyEJB which is implementing both MyEJBLocalInterface and MyEJBRemoteInterface.
Now I have a situation in which I want only to access MyEJB locally.
Could I achieve the same with the following?
#EJB(beanInterface=MyEJBLocalInterface.class)
private MyBaseInterface instanceOfLocallyAccessedMyEJB;
Could someone help me understand the use of beanInterface parameter of #EJB attribute?
Thanks.

the beanInterface attribute of the #EJB annotation is used for different purposes depending on the EJB version you are using:
In EJB 3.X you can use it to specify whether you want to use the remote of local reference of the EJB you are referring to, which is your case.
In EJB 2.X it is used to specify the Home/LocalHome interface of the session/entity bean
To sum up, yes. You should be able to use it to inject the desired interface.
This might not be supported in older versions of JBoss though.

Related

What are the limitations of #Transactional in CDI?

I am trying to use a #Transactional method inside a CDI class, instead of an EJB:
#javax.inject.Named
// fails #javax.enterprise.context.ApplicationScoped
// fails #javax.enterprise.context.SessionScoped
// works #javax.ejb.Singleton
// works #javax.ejb.Stateless
public class SomeClass {
#javax.persistence.PersistenceContext
private EntityManager em;
#javax.annotation.PostConstruct
#javax.transaction.Transactional
public void someMethod() {
em.persist(someEntity);
}
}
When I annotate SomeClass with #Singleton or #Stateless, everything works.
When I annotate SomeClass with #ApplicationScoped or #SessionScoped, WildFly 13 displays the following error message:
Transaction is required to perform this operation (either use a transaction or extended persistence context)
I was under the impression that #Transactional works with CDI since Java EE 7. Have I been mistaken? Or am I simply missing some additional configuration?
I'll try to give a short list of things to look when trying to make #Transactional work with CDI, so as to give the answer a bit more value than the comment:
We are discussing javax.transaction.Transactional, not javax.ejb.TransactionAttribute, which works for EJBs!
It does NOT work out-of-the-box in non-JEE applications!
And by JEE applications we mean those running a full JEE application server; Tomcat out-of-the-box does NOT support it!
Beware of classpath problems, specifically make sure no jar containing the annotation javax.transaction.Transactional exists e.g. in WEB-INF/lib, when running in a full JEE application server. If you want to utilize it in a non-full-JEE environment, you will need to have it in the classpath.
#Transactional is implemented as a CDI interceptor by the latest JTA specifications. As such:
It's not there in JEE < 7!
It has the same limitations as any interceptor. E.g. it cannot be called for initializer methods - #PostConstruct [THIS WAS THE PROBLEM IN THIS QUESTION], and it is NOT activated when invoking methods of this object, BEWARE!!!
I am quite confident that more errors may exist!!!

CDI Bean-Injection failed at Hazelcast map-store class

I'm using JBoss AS 7.1 and leveraging Contexts and Dependency Injection. There is no spring involved here.
My question is how can i inject a dependency into a hazelcast MapStore implementation? Might there be a programmatic way? Any help is appreciated.
For instance
public class ClientRepositoryCache implements MapStore<Integer, ClientItem> {
#Inject
ClientRepository repository;
#Override
public ClientItem load(Integer clientNumber) {
return repository.getClientById(clientNumber);
}
}
At the moment Hazelcast supports dependency injection using only Spring. Instead you can use MapStoreFactory which gives ability to create your own MapStore instance.
See a related Hazelcast group post;
MapStore/MapLoader configuration
...
To integrate with Guice, for example, you can supply the name of a singleton MapStoreFactory implementation that is statically injected with enough information to implement newMapStore(String name, Properties properties) with Injector-aware logic.
If you use programmatic configuration, as I do, you can avoid the static injection by passing an already-injected factory to MapStoreConfig.setFactoryImplementation.
-Tim Peierls-
See also MapStoreFactory and MapStoreConfig javadocs.
https://github.com/hazelcast/hazelcast/issues/440
This works very well! Integration with CDI done with a CDI Extension.

changing anotations from JBoss Seam to CDI (JEE6)

We are migrating our App from JBoss Seam to CDI (JEE6), so we are changing some anotations like #In and #Out, there's a lot of information that we have found helpful, but we have some troubles trying to find out how to replace anotations with particular patterns:
For #In anotation
#Name("comprobantes")//context name
...
#In(create=false,value="autenticadoPOJO",required=false)
private UsuarioPOJO autenticadoPOJO;
We can use #Inject from CDI, but how to set the name of the context variable for this case?.
For the #Out anotation
#Out(scope = ScopeType.SESSION, value = "autenticadoPOJO", required = false)
I have read some blogs and they say that I can use #Produces in CDI, how we can set the scope, before or after adding this anotation?
I appreciate any help or any helpful documentation.
I'm afraid there is no such thing like a 1:1 compatibility for #Out.
Technically, #Out in Seam 2 was realized by an interceptor for all method invocations - this turned out to be quite a performance bottleneck.
In CDI, most managed beans are proxied, this makes it technically impossible to implement outjection in the Seam 2 way.
What you can do (well, what you actually have to do) is going through all usages of #Out and replace it individually with some #Producer logic. Have a look at this official example here. In Seam 2, you would have outjected the authenticated user to the session-scope, in CDI a little producer method does (almost) the same.
That should hopefully give you a good start, feel free to ask further questions :)
http://docs.jboss.org/weld/reference/1.0.0/en-US/html/producermethods.html
8.1. Scope of a producer method
The scope of the producer method defaults to #Dependent, and so it will be called every time the container injects this field or any other field that resolves to the same producer method. Thus, there could be multiple instances of the PaymentStrategy object for each user session.
To change this behavior, we can add a #SessionScoped annotation to the method.
#Produces #Preferred #SessionScoped
public PaymentStrategy getPaymentStrategy() {
...
}

several EARs, JPA and interfaces

I have working app1.ear, containing:
JPA entity, MyObjectImpl, implementing interface MyObject from api.jar
api.jar with MyObject interface and EJB Remote interface
ejb.jar with EJBs providing methods to access and modify JPA Entities
Second app2.ear is supposed to communicate with app1.ear using ONLY interfaces in api.jar. Everything works fine when passing Java basic types between ears.
But when app2.ear tries to retrieve from app1.ear instance of MyObject - CORBA MARSHAL exception is raised, saying that MyObjectImpl class can not be found:
"IOP00810257: (MARSHAL) Could not load class com.zzz.MyObjectImpl"
Placing MyObjectImpl in app2.ear solves the issue, but I don't want to expose JPA implementation to other ear applications.
Am I missing something or my approach is wrong? Please advise what to do or where to dig.
Many thanks in advance!
PS: Server GF 3.0.1, no GF-specific deployment descriptors, both ears running on the same JVM
The impl classes are required during deserialization. Another approach would be to use XML or JSON or protobuff, if you doesn't want to expose the impl classes.

Using an EJB inside a JAX-RS resource class in RestEasy?

I would like to have the following kind of resource class work when deployed under RestEasy in JBoss 6:
#Path("Something")
public class Foo {
#EJB
private SomeService service
#GET
public Object frobnicate() {
assert service != null;
// JBoss blows up here
return result;
}
}
Two questions:
It is a limitation of RestEasy, not of the Java EE specification, right, that RestEasy can't inject anything annotated with #EJB?
What have people done to work around this limitation?
My developers are about to surge forward with hard-coded JNDI lookups (e.g. context.lookup(someHardCodedNameHere)) because no one can find a workaround to this specification violation at the present time. I really want to avoid this.
Lastly, I've looked at using CDI, but the story here isn't much better as RestEasy and CDI still aren't talking to each other.
Thanks in advance for any pointers.
The JBoss guys tell me this is being worked on on the trunk. So as of JBoss 6 milestone 3 this is impossible.