0

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
jhenrique
  • 858
  • 1
  • 10
  • 17
  • 1
    Can you add the contents of your ejb-jar.xml? Or do you mean you're not using it anymore and instead just using annotations. Also, when you deploy the application do you get entries such as this "JNDI bindings for session bean named 'XXX'" where XXX should likely be the "WUFFacade" EJB – JGlass Sep 25 '18 at 18:16
  • @JGlass i'm just using annotations now, trying not to use those .xmls anymore (this part seems to be ok), updated the post with JNDIs. – jhenrique Sep 25 '18 at 18:32
  • 1
    Understood! One quick test, in WUFFacade if you don't have a default no argument constructor - could you try putting one and re-dploy and see if that helps? – JGlass Sep 25 '18 at 18:49
  • 1
    I actually didn't have a default no argument constructor. Did as you said, but still getting the same error. Nothing changed at all. – jhenrique Sep 25 '18 at 19:04
  • 1
    Just tried with a constructor from superclass, but still getting the null. – jhenrique Sep 25 '18 at 19:23
  • 1
    Hmm, just for a test, as a sanity check - maybe try just adding an empty ejb-jar.xml and be sure to specify the correct version for ejb-3. I'll add it as an answer just for an example - it can be deleted if it doesnt work. And sorry - I'm always fighting with similar problems as yours so trying my usual checks ;-) Also to note, the schema below is EJB 3.2 - but it may just work for you. – JGlass Sep 25 '18 at 20:04
  • 1
    I tried this strategy before, but I noticed my xml has some differences. I'll try with yours. – jhenrique Sep 25 '18 at 20:21
  • 1
    And display-name is optional - it can be removed – JGlass Sep 25 '18 at 20:44
  • 1
    Same problem. Still null. Tomorrow I'll try generating the .ear and .war in a different structure. – jhenrique Sep 25 '18 at 21:02
  • 1
    Bangs head on desk ;-( Let me know what the structure looks like, it's really strange that it works once and then is null afterwards - are you sure that somethings not nullifying it later on? I *believe* JBoss will create a pool of those EJB's, I think the defaults around 20 of them for reuse. I wonder if it also wouldnt hurt to see if removing the `@Remote` helps - are you really calling the EJB's from another JBoss instance because if you're not, e.g. the calling code is in the same JVM as the EJB's then you dont need the `@Remote` annotation. – JGlass Sep 26 '18 at 14:20
  • 1
    I really don't know wtf is happening. I created another project, from zero, the difference is that now I have just a .war deployed to wildfly. Inside this war I have META-INF, WEB-INF and an index.jsp, my .classes are inside the WEB-INF and all structure is based in the old project. The EJB annotation works now. The structure I was using yesterday (and that should work too) is an .ear, inside this .ear I have a .war and a .jar, this doesn't work. Still not getting my @EJB to work. I'll try some other solutions, if anything works, I'll let you know. – jhenrique Sep 26 '18 at 14:35
  • 1
    I feel your pain! In this link [writing enterprise beans](https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.0/html-single/developing_ejb_applications/index#writing_enterprise_beans) they do mention that EJB's should be packaged in an EJB Jar file - possibly thats whats causing your problems though you did get a simple new project working. All my EAR's generally contain and EJB Jar as well as an WAR so wondering if you tried to put all your EJB's in a jar and then reference them from the WAR to see if that would help - worth a try! Keep me posted! – JGlass Sep 26 '18 at 15:02
  • since you did not provide the meat of your remote ejb, can you answer one question. does the remote SLSB have any internal instance variables that are not managed or injected? i have a sneaky suspicion that you are trying to hold some form of state in this bean and that won't work if it is @Stateless. – him Sep 27 '18 at 14:44
  • 1
    @him In my WUFFacade I just have a default constructor, the methods save() and getItems(), the annotation EJB FUFHome home and 2 private int attributes. The WUFFacadeRemote is just the interface. I don't have anything else. I have just updated the classes above. – jhenrique Sep 27 '18 at 17:53
  • so the project is working with "simplified packaging" (in a single war). but it fails with a war/ejb-jar/ear construction. this tells me that the ejb-jar is either mal-assembled, mis-placed, or the ear application.xml is not sane. n.b. there could be another cause, but these three are the most likely candidates for such a state of affairs. verify that the ejb-jar is assembled properly. make sure the ear file has the ejb-jar at the same tier as the war file (and not in the ear files /lib directory). also, verify the application.xml has both of your deployments (war, jar) listed properly. – him Oct 04 '18 at 15:21
  • The .ear has the ejb-jar at the same tier as the war file. application.xml also has both war and jar listed. I noticed that always when wildfly was started, the EJB works and after calling the component again, it is null. After having this issue for some time, I decided to pack as a .war because it's not a problem to us. As a .war deployed, the @EJBs are always being injected properly, so I think it's ok for now. Thank you and all guys who took a look at the problem. – jhenrique Oct 08 '18 at 14:46

1 Answers1

0

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.

jhenrique
  • 858
  • 1
  • 10
  • 17