Search code examples
jbossejbejb-3.0ejb-3.1wildfly-9

EJB not initializing in Wildfly 9.0.0 using @EJB


I'm trying to migrate from EJB2.x to EJB3.x and i'm using Wildfly 9.0.0. The old EJB2.x is working in JBoss 4.2.2 and this is how it looks like:

public interface WUFFacadeRemote extends EJBObject {
    public ClientData getItems(ClientData data);
    public ClientData save(ClientData data);
}

public interface WUFFacadeHome extends EJBHome {
    public WUFFacadeRemote create();
}

public class WUFFacade {
    public ClientData getItems(ClientData data) { 
        //code here
    }

    public ClientData save(ClientData data) {
        //code here
    }
}

public class WUFAction extends HttpServlet implements IAction {
    public void doPost(HttpServletRequest request, HttpServletResponse response) {

        ... 

        Object objRef = ic.lookup("java:comp/env/wUF");

        com.wuf.WUFFacadeHome home = (com.wuf.WUFFacadeHome) PortableRemoteObject.narrow(objRef, com.wuf.WUFFacadeHome.class);

        engine = home.create();

        //engine gets the reference, and I can use it normally.
        ...
    }
}

I also have the ejb-jar.xml and it's working. Now, the solution I was thinking to EJB3.x and Wildfly 9.0.0 is as below:

@WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
public class WUFAction extends HttpServlet implements IAction {

    @EJB
    private WUFFacadeRemote engine; 

    public void doPost(HttpServletRequest request, HttpServletResponse response) {

        //Here I should be able to use my engine.
        //Wildfly starts and I call the page, engine is not null at this moment,
        //but after I call the page again, it becomes null and remains null.
    }
}

@Stateless
@Remote(WUFFacadeRemote.class)
public class WUFFacade extends RootFacade implements WUFFacadeRemote, Serializable {
    public WUFFacade() { }

    @EJB
    FUFHome home;

    public ClientData getItems(ClientData data) {
        //code here
    }

    public ClientData save(ClientData data) {
        //code here
    }

    private Col load(ClientData data,InitialContext ic) {
        //here i'm calling home.
        // but home is always null. It was supposed to have the @EJB reference initialized.
        //But instead I get a null pointer...
        home.findByFilter(loader);
    }
}

@Remote(FUFHome.class)
public interface FUFHome {

    FUF create(FUFValue fUFValue);

    FUF findByPrimaryKey(FUFPK  pk);

    Collection findByFilter(FacadeLoader loader);
}



public interface WUFFacadeRemote{
    public ClientData getItems(ClientData data);
    public ClientData save(ClientData data);
}

I don't have ejb-jar.xml anymore, the deploy is sucessfully done and Wildfly starts with no errors. Then the first time I call the page in question, it seems that @EJB is working (Debug is "Proxy for remote EJB StatelessEJBLocator for "bus-facade/WUFFacade", view is interface com.wuf.WUFFacadeRemote, affinity is None"), the value is not null, but for all subsequent calls, my variable is null and I got a NullPointerException.

I really don't know what i'm doing wrong (maybe i'm completely lost), but to me, @EJB should be working correctly like that. What am I missing? Thanks.

As i'm using EJB3.x i'm just using annotations now, (this seems to be ok).

JNDIs:

JNDI bindings for session bean named FUF in deployment

java:global/fumo/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:app/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:module/FUF!apyon.components.fumo.fuf.FUF
java:global/fumo/bus-entities-fumo/FUF
java:app/bus-entities-fumo/FUF
java:module/FUF

JNDI bindings for session bean named WUFFacade

java:global/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:app/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:module/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:jboss/exported/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:global/fumo/bus-facade-fumo/WUFFacade
java:app/bus-facade-fumo/WUFFacade
java:module/WUFFacade

Solution

  • I think I found a possible solution to the problem. I'll still try to find another one, but this is good so far.

    After changing to a .war and keeping my other projects in .ears it's working. Maybe the problem was because I have a RootController servlet im my main.ear, which is the starting point of the aplication. The context starts there and then it redirects to fumo.ear (now fumo.war).

    For some reason, I always was getting a null in my EJB after entering a page. It was always hapening when I first entered a JSP and tried to call the page again. My solution to this is:

    @WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
    public class WUFAction extends HttpServlet {
    
        private WUFFacadeRemote engine; 
    
        public void doGet(HttpServletRequest req, HttpServletResponse resp) {
            doPost(req, resp);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response) {
    
            if(engine == null) {
                InitialContext ic; 
                try {
                    ic = new InitialContext();
                    engine = (WUFFacadeRemote) ic.lookup("java:global/fumo/WUFFacade!fumo.wuf.WUFFacadeRemote");
                } catch (NamingException e) {
                    e.printStackTrace();
                }
            }
    
            //here I always have the context now.
        }
    }
    

    And as a .war my structure now looks like this:

    enter image description here enter image description here

    So other annotations like @Inject and @EJB are now working. Always when i'm being redirect from a JSP calling a Servlet or some action, I first check if the context is not null, otherwise I lookup it. My @Stateless are working and the @PersistenceContext and @Remote are working too.

     @Stateless
     public class WUFFacade implements WUFFacadeRemote {
         @Inject
         private FUFRules rules;
    
         @EJB
         private FUFHome home;
    
        private Col load(ClientData data, InitialContext ic) throws InterfaceException {
            try {
                // home here is nor null anymore.
                Collection res = (Collection) home.findByFilter(loader);
                ...
            } catch (InterfaceException e) {
                e.printStackTrace();
            }
            ...
            return data;
        }
    }
    

    So I'd like to thank everyone who helped in the thread. It was a good way to understand and see the problem or to find a workaround. As I said, I'll still try the .ear in the future, but as a simplified packaging it definitely works.