6

I'm working on rest service and learning EJB at the same time. I just run my application with simple chain controller -> service -> DAO and my EJB hotelService is not injected -- it is null.

@Path("/hotels")
public class HotelsController {

@EJB
private HotelService hotelService;


@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getHotelsList(@QueryParam("startDate") String startDate,
                              @QueryParam("endDate") String endDate) {
    List<HotelsEntity> list = hotelService.getAll();
    return ResponseFactory.response(Response.Status.OK, list);
}
}

Service

@Stateless
@EJB(beanInterface = HotelService.class, name = "HotelService")
public class HotelService {

@EJB
private HotelDAO hotelDAO;

public List<HotelsEntity> getAll() {
    return hotelDAO.getAll();
}

public Hotel getHotelById(final String id) {
    return hotelDAO.getHotelById(id);
}
}

DAO

@Stateless
public class HotelDAO {

@PersistenceContext(unitName = Constants.PERSISTENCE_UNIT)
private EntityManager em;

public List<HotelsEntity> getAll() {
    // TODO complete me
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<HotelsEntity> criteria = builder.createQuery(HotelsEntity.class);
    Root<HotelsEntity> root = criteria.from(HotelsEntity.class);
    criteria.select(root);
    TypedQuery<HotelsEntity> resultQuery = em.createQuery(criteria);
    return resultQuery.getResultList();
}

I thought that issue may be in some eror during instatiation of HotelDAO but even without it mt HotelService is null.

Do you a have any opinion where is an issue can be?

I use glassfish 4.0 My pom is:

  <modelVersion>4.0.0</modelVersion>
<groupId>HospitalityRestServer</groupId>
<artifactId>HospitalityRestServer</artifactId>
<packaging>war</packaging>

<version>1.0-SNAPSHOT</version>
<name>HospitalityRestServer Maven Webapp</name>
<url>http://maven.apache.org</url>

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.3.5.Final</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>2.7</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>annotations-api</artifactId>
        <version>6.0.29</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.ejb</artifactId>
        <version>3.1</version>
    </dependency>
</dependencies>

Log:

[2014-04-28T17:58:05.828+0400] [glassfish 4.0] [WARNING] [] [javax.enterprise.web] 
tid: _ThreadID=22 _ThreadName=http-listener-1(4)] [timeMillis: 1398693485828] [levelValue: 900] [[

StandardWrapperValve[javax.ws.rs.core.Application]: Servlet.service() for servlet javax.ws.rs.core.Application threw exception java.lang.NullPointerException at com.example.controller.HotelsController.getHotelsList(HotelsController.java:29) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:125) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91) at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101) at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:267) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946) at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:323) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544) at java.lang.Thread.run(Thread.java:745) ]]

Mr Kohn Doew
  • 277
  • 1
  • 2
  • 18

1 Answers1

5

You need to either implement a @Local annotated interface that expresses the local view of that EJB bean, or you need to add the @LocalBean annotation to the HotelService class itself to explicitly state that it is a local no-interface view of that EJB.

@Stateless
@EJB(beanInterface = HotelService.class, name = "HotelService")
@LocalBean
public class HotelService {
    // ...
}

If you want the service to be available outside of the container for RMI or EJB client execution, you'll need to create a @Local and @Remote view of that service and implement both.

jgitter
  • 3,396
  • 1
  • 19
  • 26
  • Thanks for your answer, but it doesn't help -- I marked it as LocalBean but issue is the same – Mr Kohn Doew Apr 28 '14 at 13:40
  • After doing a little reading on the java ee 7 docs, I realized that the @LocalBean is not actually required. Are you getting any other errors on startup? Have you checked the server logs? – jgitter Apr 28 '14 at 13:41
  • Yes, on startup I had an issue described here https://java.net/jira/browse/GLASSFISH-20579 and I resolved it by setting asadmin set configs.config.server-config.cdi-service.enable-implicit-cdi=false That is all, log doesn't have anything else – Mr Kohn Doew Apr 28 '14 at 13:50
  • That may come back to bite you if you ever choose to use CDI in your application. But regardless, it sounds like you need to raise the log levels for your application. Also... can I see the NPE being thrown when you attempt to call your web service? – jgitter Apr 28 '14 at 13:55
  • Wait a minute... I just noticed you're also injecting the DAO into your Service class. Can I see the annotations you have on that object? – jgitter Apr 28 '14 at 13:57
  • Update with log. An a few minutes update and DAO but I also had tried without DAO -- issue is the same – Mr Kohn Doew Apr 28 '14 at 13:59
  • Update DAO. Too short – Mr Kohn Doew Apr 28 '14 at 14:01
  • The only other thing I can think of is that EJBs have to be injected into managed objects and apparently your service doesn't qualify. Try making your service a @Stateless bean, rebuild and try again. If that is the case, and you don't wish to add the overhead of another bean, try using CDI instead. :-) – jgitter Apr 28 '14 at 14:09
  • Well, my service is already a stateless bean :) – Mr Kohn Doew Apr 28 '14 at 14:13
  • I'm not talking about the HotelService object. I'm talking about the HotelController object which exposes a JAX-RS web service. – jgitter Apr 28 '14 at 14:14
  • Let me know if this works and I'll update my answer. – jgitter Apr 28 '14 at 14:21
  • 1
    I resolved it - I have added a bean.xml. I'm appreciate all your help jgitter. Thank you! – Mr Kohn Doew Apr 28 '14 at 14:30
  • I mark it as answer because at least it ha an answer in comments – Mr Kohn Doew Apr 28 '14 at 14:31
  • Congrats and cheers to you! – jgitter Apr 28 '14 at 14:31