I am having some issues trying to inject a stateless EJB into an Application Client Project. Both the App Client and the EJB are in the same EAR. Using JNDI, I am able to retrieve an instance of the EJB, but I'm not sure how should I do it with the #EJB annotation. I've tried using #EJB(name="something"), #EJB(mappedName="something"), but all I get is a null. Here is my code:
#Remote
public interface TimerEjbTestService {
public void testMethod();
}
#Stateless(mappedName="TimerEjbTestService")
public class TimerEjbTestBean implements TimerEjbTestService{
public void testMethod() {
System.out.println("Inside EJB.");
}
}
With JNDI I'm able to get the instance as follows:
Context ctx = new InitialContext();
TimerEjbTestService timerEjbTestService = (TimerEjbTestService) ctx.lookup("TimerEjbTestService#myejb.timerejbtestservice.services.TimerEjbTestService");
Any ideas on how can I do this?
You can do something like this:
#EJB
private TimerEjbTestService myBean;
In this way, the container injects the bean.
Also, since it is in the same ear (thus ran by the same JVM) the annotation for the interface should be #Local not #Remote.
Related
I'm trying to look up my stateless bean using the annotation class #EJB, but fails. I'm using WildFly 10 as EE container. The stateless bean interface looks as follows:
#Local
public interface T1Service {
String sayHi();
}
The implementation class:
#Stateless
public class T1ServiceImpl implements T1Service {
#Override
public String sayHi() {
return "Hi!";
}
}
In my controller I want to inject the service:
#EJB(lookup = "javaee/T1ServiceImpl")
private T1Service t1Service;
Make the call:
t1Service.sayHi();
But it fails with a NullPointerException (t1Service is null).
What am I missing?
Note, the JNDI bindings are:
java:global/javaee/T1ServiceImpl!p1.T1Service
java:app/javaee/T1ServiceImpl!p1.T1Service
java:module/T1ServiceImpl!p1.T1Service
java:jboss/exported/javaee/T1ServiceImpl!p1.T1Service
java:global/javaee/T1ServiceImpl
java:app/javaee/T1ServiceImpl
java:module/T1ServiceImpl
The controller where you want to inject the T1Service is also a #Stateless Bean? If it is runnning in the same application you can omit the definition of property lookup.
I would also suggest to use CDI (#Inject) in case that you are using Java EE 6/7/8. (see here for more information)
I am new to the Struts2 framework and to EJB as well. I have a class LoginDAO which implements checkUser method of an interface LoginDAOLocal. I don't understand why I see different behavior for the following scenarios:
If I use an EJB (LoginDAO is stateless session bean) as follows, method call works perfectly without any error.
#EJB
private LoginDAOLocal loginDao;
loginDao.checkUser(userName,password);
If I use Struts2 as follows, it gives a Null pointer exception for the method call.
public class LoginAction extends ActionSupport {
// Getters setters for userName and password)
private LoginDAOLocal loginDao;
loginDao.checkUser(this.userName,this.password);
}
If I use a simple Java application (no EJB or Struts2), the method call creates a compile time error saying loginDao is not initialized
public static void main(String[] args) {
LoginDAOLocal loginDao;
loginDao.checkUser(userName,password);
}
Can someone explain why this different behavior ?
Without getting too much into the Java EE spec: EJBs are managed by an EJB container that exists in J2EE servers (JBoss \ Websphere etc..). The container takes control of bean lifecycle and is responsible for creating \ destroying beans according to the application needs.
When running out of container (simple java application) your beans won't get initialized and you don't have a JNDI context to get beans from, even if you add #EJB annotation to the field member.
We can say that there are two ways to manage the beans, using the container (managed by the container), or by another component (managed by a servlet, listener or filter).
Using components managed by the container, the container injects the references. e.g.:
#WebServlet("/test")
public class MyServlet extends HttpServlet {
#Resource(lookup = "jdbc/TestDS")
private DataSource testDS;
}
By contrast, a component managed by a bean, e.g.:
#Namespace("/User")
#ResultPath(value = "/")
#Result(name = "success", location = "pages/login.jsp")
public class LoginAction extends ActionSupport {
}
is managed by the filter org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter. The latter should be responsible for performing dependency injection. Spring, for example, takes care of injecting all necessary dependencies.
I have 2 EJB module projects and I want from one of the projects to call a stateless no-interface bean from another project. I want to inject the bean to be called using the EJB annotation. The problem is the injection doesn't work(I use NetBeans 7.4 if that is relevant).
The stateless no-interface EJB being called:
package standalonepackage;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
#Stateless
#LocalBean
public class StandaloneBean {
private static final String message="Greetings!";
public String returnMessage(){
return message;
}
}
The interface of the bean that calls the bean above(this ejb resides in another ejb module project)
#Local
public interface ExampleBeanLocal {
public String getMessage();
}
The implementation of the interface:
#Stateless
public class ExampleBean implements ExampleBeanLocal {
#EJB
private StandaloneBean standaloneBean;
#Override
public String getMessage() {
return String.format("Me - and the second message %s", standaloneBean.returnMessage());
}
}
I also have a main class that just calls the ExampleBean getMessage method(MainClass is located in the second ejb module project):
public class MainClass {
private static ExampleBeanLocal instance = new ExampleBean();
public static void main(String[] args) {
System.out.println(instance.getMessage());
}
}
What am I missing?
First of all if you want to access your business logic as EJB then first you will need to deploy the EJB in an application server. During the deployment process the application server will create something called the JNDI name which is like a gatepass to access your business logic.
Secondly, there are two ways you can invoke an EJB.
1. Creating ContextLookup using JNDI name
2. Using Context Dependency Injection CDI (only within the same Container)
You cannot invoke an EJB using CDI from a POJO ( since it is not contained in any container and the EJB your accessing is in a different JVM ). If you want to access an EJB from a POJO you'll need to use #Remote and use the ContextLookup way of accessing an EJB, you can find more information here
http://wiki.netbeans.org/CreatingEJB3UsingNetbeansAndGlassfish
You need application server with EJB container to run this. Have a look at JBoss, Apache TomEE or something else.
you can use this way to run your jar GLASFISH_HOME/bin/appclient -client app.jar
before compiling your maven project mvn assembly:assembly
and add your main class in your pom.xml
I want to add a dependency to an EJB. How do I do this using Spring? The dependent object is a general service object. Based on code below I want to wire myDependency without having to use 'new'.
The EJB runs in weblogic.
#Stateless(mappedName = "MyBean")
public class MyBean implements MyBeanRemote, MyBeanLocal {
#EJB(name = "MyOtherBean")
private MyOtherBean myOtherBean;
private MyDependency myDependency;
...
}
This is well described in the Spring documentation:
For EJB 3 Session Beans and Message-Driven Beans, Spring provides a
convenient interceptor that resolves Spring 2.5's #Autowired
annotation in the EJB component class:
org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.
This interceptor can be applied through an #Interceptors annotation in
the EJB component class, or through an interceptor-binding XML element
in the EJB deployment descriptor.
#Stateless
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class MyFacadeEJB implements MyFacadeLocal {
// automatically injected with a matching Spring bean
#Autowired
private MyComponent myComp;
// for business method, delegate to POJO service impl.
public String myFacadeMethod(...) {
return myComp.myMethod(...);
}
...
}
Stateless EJBs and Spring beans, however, offer more or less the same possibilities. Mixing them together seems like unnecessary complexity.
Is it possible to use #EJB inside another EJB? I'm trying to do this now, and my EJB is ending up null. I'll outline my problem in an example.
#Stateless
#LocalBean
#Local(LoginServiceLocal.class)
public class LoginService implements LoginServiceLocal {
public void createLogin(String email, String password) { ... }
}
#Stateless
#LocalBean
#Local(AccountServiceLocal.class)
public class AccountService implements AccountServiceLocal {
#PersistenceContext(unitName = "accounts")
private EntityManager accountEntityManager;
#EJB
private LoginServiceLocal loginService;
public void createAccount(Account account, String email, String password) {
accountEntityManager.persist(account);
loginService.createLogin(email, password);
}
}
Is this type of thing supposed to be possible? I should also mention that I'm using an embedded container (via EJBContainer), and I'm looking up the AccountService using JNDI, however when I try and call loginService.createLogin in the AccountService, the loginService is null (not being initialized by #EJB).
Is what I'm trying to do possible?
Thanks.
Yes, it's possible.
The #LocalBean annotation, enables an EJB to expose a no-interface client view, so that you won't need to define a Local interface.
On the other hand, the #Local annotation defines a bean's local client interface.
Choose one of the above configuration options not both.
If you choose to use the #LocalBean annotation, drop the #Local annotation, remove the implements keyword and inject the bean class name with the #EJB annotation.
If you choose to use the #Local annotation, drop both #Local and #LocalBean annotations and inject the bean with the #EJB annotation using the interface name.
Yes, I was just working on some of my code that does just that. It might be an issue with how you're creating the EJB. I have only done it using injection and not a jndi lookup.
If you are used EJB3.1 you can also use #Inject from CDI