I have a .ear that imports a .jar and a .war modules. I'm trying to inject a EJB on my war that exists in jar, and I'm getting a null pointer exception when I call it. Here's the code.
WAR PACKAGE
Controller
This property "private AutenticacaoBean authBean;" is getting a null pointer exception. I don't really know if I need to use #remote in any place, because I'm using different packages, but in the same ear.
public class LoginController extends AbstractController {
#EJB
private AutenticacaoBean authBean;
public void execute() {
//code
}
}
JAR PACKAGE
Bean
#Stateless
#LocalBean
public class AutenticacaoBean {
#EJB
private UsuarioDAO usuarioDao;
//code
}
Implementation
#Stateless
public class UsuarioDAOImpl implements UsuarioDAO {
public UsuarioDAOImpl() {
//code
}
//code
}
Interface
#Local
public interface UsuarioDAO {
//code
}
Any help would be great. Thank you for your time!
EJB 3.1 dropped the requirement for local interfaces and you are using AutenticacaoBean without the interface, but probably your Application Server is not compliant about EJB 3.1 and you cannot perform the injection in this way:
#EJB
private AutenticacaoBean authBean;
You could try to create an interface (AutenticacaoLocal for example) for your AutenticacaoBean with the needed methods and then inject this one in your LoginController:
#EJB
private AutenticacaoLocal authBean;
Exactly as you did for UsuarioDAOImpl.
Related
In Spring project I can use #Autowired annotation.
#Service
public class DefaultUserService implements UserService {
...
#Autowired
private UserDao userDao;
But I don't understand how do it in JavaEE project. I found:
#Inject
private AvayaDao avayaDao;
But my avayaDao is NULL. I tried add annotation
#Default
public class AvayaService {
...
#Inject
private AvayaDao avayaDao;
but not helped. It id my Dao:
public interface AvayaDao extends BaseDao<AvayaSdr> {
List<AvayaSdr> getAll();
void insertCdr(AvayaSdr avayaSdr);
}
It is My Service:
#Default
public class AvayaService {
private static AvayaService instance;
#Inject
private AvayaDao avayaDao;
public synchronized static AvayaService me() {
if (instance == null) {
instance = new AvayaService();
}
return instance;
}
public Set<String> selectAllLoadedAVAYAcmCDRFiles() {
Set<String> result = new HashSet<>();
List<AvayaSdr> resultList = avayaDao.getAll();
for (AvayaSdr avayaSdr : resultList) {
result.add(avayaSdr.getHashValue());
}
return result;
}
public void insertCdr(String fileHash) {
AvayaSdr avayaCmCdr = new AvayaSdr("", fileHash, 0);
avayaDao.insertCdr(avayaCmCdr);
}
java.lang.NullPointerException
Either the AvayaDao must be an EJB and annotated with #Stateless or #Singleton or you use CDI injection and an empty beans.xml file is needed (http://docs.oracle.com/javaee/6/tutorial/doc/gjbnz.html) if you are using Java EE 6. In Java EE 7 the attribute bean-discovery-mode="all" must be set (https://docs.oracle.com/javaee/7/tutorial/cdi-adv001.htm).
UPDATE 1:
Enterprise Java Beans are POJOS annotated with #Stateless, #Statefull or #Singleton, that are managed by the EJB container inside the application server. They are able to access container specific services like the TimerService, the security context and aspects like transaction support and monitoring. Stateless enterprise java beans are also pooled by the application server.
UPDATE 2:
#Tiny Your right, but if AvayaDao is no EJB and your application contains a beans.xml file, where interceptors or other CDI specific POJOS are registered the default bean-discovery-mode is 'annotated' and the injection will not work with not annotated POJOS and explicitly setting the 'all' value is needed (http://www.adam-bien.com/roller/abien/entry/when_your_di_breaks_bean). Another option would be using no beans.xml if you explicitly know, that your application is only deployed in JAVA EE 7 environments.
I have two gwt RemoteServiceServlet in my project which has use GWT framework as below
#RemoteServiceRelativePath("AuthService")
public interface AuthService extends RemoteService {
}
public class AuthServiceImpl extends RemoteServiceServlet implements AuthService
{
#Autowired
private StoredService storeService;
}
#RemoteServiceRelativePath("webService")
public interface WebService extends RemoteService
{
}
public class WebServiceImpl extends RemoteServiceServlet implements WebService
{
#Autowired
private LogService logService;
}
Both the #Autowired of StoreService and LogService are work. But when I try to autowired WebService in AuthService, it will be null at runtime.
The interface and implements are in different package, which is com.test.client.service and com.test.server.service respectively.
I have confirm my SpringApplication-context.xml has below declare:
<context:component-scan
base-package="com.test.client.service, com.test.server.service
>
Also try to add #Service, #Component or #Configurable on WebServiceImpl, but still not works.
Override the init() of WebServiceImpl is also not work either.
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
WebApplicationContextUtils.getWebApplicationContext(config.getServletContext())
.getAutowireCapableBeanFactory().autowireBean(this);
}
Is that because the RemoteService cause the autowired not work correctly?
Any help is appreciated.
Thanks
I use the following to integrate GWT-RPC into Spring. I wrote it 6 years ago and never saw the need to change it. It is old-school and it works. It models GWT-RPC services as Spring MVC controllers, which they are. You can autowire anything into those controllers.
I mentioned it in a different answer, so I'll just post a link: https://stackoverflow.com/a/30838630/4982193
I am newbie with EJB and Injections...
I am currently using Vaadin framework with CDI
I have been trying to using injection but i have not could do it...
In my Vaadin UI class MyVaadinUI i have tried...
CDIUI("")
#SuppressWarnings("serial")
public class MyVaadinUI extends UI {
#EJB
UserController userController;
#Override
protected void init(VaadinRequest request) {
System.err.println("desde controller "+userController.getAll().size());
}
}
UserController
#Stateless
public class UserController {
#EJB
IUserDAO userDao;
public List<User> getAll() {
return userDao.findAll();
}
}
and it works!!
but when I do not inject UserController, it does not work... In other words when I instance the class UserController the injection in this class does not work...
Code does not work
CDIUI("")
#SuppressWarnings("serial")
public class MyVaadinUI extends UI {
#Override
protected void init(VaadinRequest request) {
UserController userController = new UserController();
System.err.println("desde controller "+userController.getAll().size());
}
}
Somebody can explain me why?
Thanks
Nicolas
Only in injected objects will have its dependencies injected. If you create an object with new all field having #inject, #ejb or #resource will not be injected.
In your case you create UserController like this:
UserController userController = new UserController();
and so this field will not be injected:
#EJB
IUserDAO userDao;
And therefore getAll() will throw a NullPointerException.
I use vaadin and cdi for projects. I'd recommend to use injection for almost everything or not at all. I inject my uis, views, own components... (and do not create them with new) so it is possible to inject ejb beans or other things into them. If you are using it only sometimes you are ending up with am mixture of injection and normal object creation and will have to pass around injected objects to other object you instantiated yourself. In another project of mine this happened and got really problematic for future changed in the code.
I am learning Java EE and JSP. I have created an Enterprise Application project in NetBeans.
I have the EJB project where all beans are and a WAR project where all web/client stuff is.
My problem is that the annotation #EJB does not instantiate my Bean in the WAR application. Can I use #EJB outside the EJB application?
In the EJB project, I have these files:
CustomerRemote.java
#Remote
public interface CustomerRemote {
public Customer createCustomer();
public Customer getCustomer(int customerId);
public void removeCustomer();
}
CustomerBean.java
#Stateless
public class CustomerBean implements CustomerRemote {
#PersistenceContext(unitName="testPU")
private EntityManager entityManager;
#Override
public Customer createCustomer() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void removeCustomer() {
}
#Override
public Customer getCustomer(int customerId) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
In the WAR project, I have a file that my JSP page uses to communicate with the EJB stuff. The problem is that the CustomerRemote object is never instantiated. #EJB annotation does not seem to work because customerRemote always is null. But when instantiating it with the lookup method, it works! So why does not #EJB work?
public class CustomerProxyBean {
#EJB
private CustomerRemote customerRemote;
public CustomerProxyBean() {
// try {
// InitialContext context = new InitialContext();
// customerRemote = (CustomerRemote)context.lookup("java:app/SimpleShop-ejb/CustomerBean");
//
// } catch (NamingException ex) {
// Logger.getLogger(CustomerProxyBean.class.getName()).log(Level.SEVERE, null, ex);
// }
}
#EJB annotation will work only in cases where your class is container-managed, that is EJB, servlet, JSP... In your case you put it into plain old Java object (POJO) so injection will not work, as you have experienced. Write your CustomerProxyBean as a stateless session bean, and you'll see the change.
Alternatively, if you want to avoid JNDI for some reason, you can use CDI and #Inject annotation to inject EJB and achieve wished behaviour, even in POJO:
#Inject
private CustomerRemote customerRemote;
I got some propably trivial question.
If I got defined EJB3+ interface, lets say it's remote like that:
#Remote
public class FooServiceRemote {
void foo();
}
and one implementation
#Stateless
public class FooService implements FooServiceRemote {
void foo() { ... }
}
How does the application server by default resolves what implementation to use (and call via proxy) if he knows only #EJB annotation for dependency injection like on interface:
public class SomeClass {
#EJB
private FooServiceRemote fooService;
}
Is it done by reflection (shortening name of interface)? Or he scans possible implementations of such interface, choosing one. Or.. ? And what if I want to create more implementations of one interface, is it possible and how to specify what implementation should be instantiated (maybe it is possible via some argument of annotation).
Thanks:-)
In the rare case that you need to have two beans implementing the same interface (not a good practice), you can name them and choose which one you want by name.
#Stateless(name="FooService1")
public class FooService1 implements FooService { }
#Stateless(name="FooService2")
public class FooService2 implements FooService { }
public class SomeClass {
#EJB(beanName="FooService1")
private FooService fooService;
}
Other possible approaches are looking it up using JNDI or the mappedName property.
See the javadoc for EJB annotation here: http://download.oracle.com/javaee/6/api/javax/ejb/EJB.html
Just a fix,
#Remote
interface FooServiceRemote {
void foo();
}
#Stateless
public class FooService implements FooServiceRemote {
void foo() { ... }
}
With this, application server knows which classes implements the specified interface.
If you have two classes, you must specifify which class do you need.