I have a EAR package that contains a web module and EJB. The EJB is currently exposed its contains to local app client via Remote
interface
@Stateless
public class CoreEJB implements CoreEJBRemote {
@PersistenceContext(unitName = "CoreWeb-ejbPU")
private EntityManager em;
@Override
public void packageProcess(String configFileName) throws Exception {
//Process logics
}
@Override
public <T> T create(T t) {
em.persist(t);
return t;
}
@Override
public <T> T find(Class<T> type, Object id) {
return em.find(type, id);
}
...
}
The Remote
interface is not in EAR, and look like this
@Remote
public interface CoreEJBRemote {
public void packageProcess(java.lang.String configFileName) throws java.lang.Exception;
public <T extends java.lang.Object> T create(T t);
public <T extends java.lang.Object> T find(java.lang.Class<T> type, java.lang.Object id);
}
The Main
of the app client is below
public class Main {
@EJB
private static CoreEJBRemote coreEJB;
public static void main(String[] args) {
coreEJB.packageProcess("path/to/a/file");
}
}
Now i want to create an Local
interface for the EJB so that in the Managed Bean
of my web module, I can access the EJB via local invocation.
Do I just change CoreEJB
from public class CoreEJB implements CoreEJBRemote
to public class CoreEJB implements CoreEJBRemote, CoreEJBLocal
and create @Local
interface call CoreEJBLocal
inside EJB package
? Or will there be something extra? I want my Managed Bean code to be like this
@ManagedBean
@RequestScoped
public void testView{
@EJB
private CoreEJBLocal coreEJB;
public void add(Something something){
coreEJB.add(something); //Local invocation
}
}
Yes, this should be sufficient. Did you try? Did it fail? Keep in mind that local interfaces are pass-by-reference and remote interfaces are pass-by-value. If callers (or the bean) mutate state on the return value (or arguments, respectively), then you're going to get different behavior between the two. You must manage this careful in your API contract.