5 Replies Latest reply on Aug 16, 2016 3:41 PM by Erik Sliman

    Cannot access local stateless EJB interface from WAR (REST)

    Erik Sliman Apprentice

      I've been trying for 4 hours to get injection or even an old fashioned initial context lookup to work.  This is simple.  I have a stateless session bean, and a WAR with rest services that needs to access it.  The documentation on Wildfly is horrible, and I cannot find a single tutorial anywhere for this insanely simple use case.

       

      From the war, I've tried all of these (commented) and more:

       

      //    java:global/jvestApp/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreLocal

      //    java:app/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreLocal

      //    java:module/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreLocal

      //    java:global/jvestApp/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreRemote

      //    java:app/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreRemote

      //    java:module/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreRemote

      //    java:jboss/exported/jvestApp/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreRemote

         

          @EJB(lookup="java:global/jvestApp/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreLocal")

      //    @EJB(lookup="java:app/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreLocal")

      //    @EJB(lookup="ejb:jvestApp/jvestEJB/ejb/StringStore/StringStoreBean!net.openstandards.jvest.ejb.StringStoreLocal")

      //    @Inject

      //    @EJB(name="ejb/StringStore", mappedName="ejb/StringStore")

      //    @EJB(name="java:app/jvestEJB/ejb/StringStore!net.openstandards.jvest.ejb.StringStoreLocal")

      //    @EJB(name="ejb/StringStore")

      //    @EJB(lookup="java:comp/env/ejb/StringStore")

      //    @EJB

          StringStoreLocal stringStore;

       

      I've tried both local and remote.  I either get a NULL, or get a deployment exception such as:

       

      Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type StringStoreLocal with qualifiers @Default

        at injection point [UnbackedAnnotatedField] @Inject net.openstandards.jvest.rest.ServiceRest.stringStore

       

      or

       

      Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-001517: The type of the resource producer field [[UnbackedAnnotatedField] @EJB net.openstandards.jvest.rest.ServiceRest.stringStore] does not match the resource type net.openstandards.jvest.ejb.StringStoreBean

       

      or, when I either include a lookup or do an initial context lookup:

       

      23:20:06,820 INFO  [stdout] (AsyncAppender-ASYNC) java.lang.ClassCastException: net.openstandards.jvest.ejb.StringStoreLocal$$$view1 cannot be cast to net.openstandards.jvest.ejb.StringStoreLocal

       

      Bean currently looks like:

       

      @Stateless(name="ejb/StringStore", mappedName="ejb/StringStore" )

      //@LocalBean

      public class StringStoreBean implements StringStoreLocal, StringStoreRemote {

       

      and local interface:

       

      @Local

      public interface StringStoreLocal {

       

      If someone could just create a simple Wildfly 10 Hello world with a web REST using injection to access EJB stateless, that would be really nice.

       

      Ironically, I've been using JBoss since version 2.2/2.4 in 2001 (OpenStandards.net was deployed using it in 2002), back when Marc Fluery was on the message boards a lot and, I believe, in college still.  I've been doing web/EJB development since, primarily in WebSphere, doing TONS of REST/EJB development.  I have never had a problem with InitialContext and used injection with JPA in WAS.   I've done remoting to JBoss EJB's from both Swing clients and other J2EE platforms (WebSphere).  I'm new to Wildfly, as I haven't developed for JBoss since probably 5.  I

       

      The Wildfly documentation does not give a single good example of the basic use case of a WAR and EJB module in a single EAR.  Four hours of trial and error with no success is just insane.

       

      Googling returns everything BUT this simple use case for Wildfly 10.

        • 1. Re: Cannot access local stateless EJB interface from WAR (REST)
          Wolfgang Mayer Master

          WildFly should comply to JSR-000339 (The JavaTM API for RESTful Web Services).

          For a simple application it should be enough to have a class which is annotated with @ApplicationPath and extends Application, the service class and the EJB.

          For example:

           

          The Application:

           

          import javax.ws.rs.core.Application;

          @javax.ws.rs.ApplicationPath("resources")

          public class MyApplication extends Application {

          }


          The service:

          @Stateless

          @Path("/greeting")

          public class HelloWorldResource {

           

              @EJB

              private NameStorageBean nameStorage;

             

              @GET

              @Produces("text/html")

              public String getGreeting() {

                  return "<html><body><h1>Hello "+nameStorage.getName()+"!</h1></body></html>";

              }

             

              @PUT

              @Consumes("text/plain")

              public void setName(String content) {

                  nameStorage.setName(content);

              }

          }

           

          The EJB:

           

          @Stateless

          public class NameStorageBean {

           

              // name field

              private String name = "This is my World!!";

           

              public String getName() {

                  return name;

              }

           

              public void setName(String name) {

                  this.name = name;

              }

          }

          1 of 1 people found this helpful
          • 2. Re: Cannot access local stateless EJB interface from WAR (REST)
            Erik Sliman Apprentice

            Thank you.  I got your example working.  I'll work backwards from there to try to get my app working.

            I noticed it leaves out local and remote interfaces.  Is this acting like a local interface?  Is there also an implicit remote interface?  I'd hope for security reasons that remote interfaces are still explicit.

            Will this work just fine with JTA and CMT?  That is the primary reason I use EJBs. 

            I noticed the session bean also worked if I had it in my WAR.  If I just put it all in the WAR, will CMT still work?  Last I checked, cannot use CMT from the WAR. 

            • 3. Re: Cannot access local stateless EJB interface from WAR (REST)
              Erik Sliman Apprentice

              OK, I got my EJB/WAR interaction working now.  I identified and resolved the issue quickly thanks to your example!  Consider turning your Hello World example that into an article and try to get it into the primary docs, because that use case is core to why JBoss was created.  

               

              SOLUTION

               

              Had to use "resources" path defined by ApplicationPath, which I previously defined long ago but quit using even though the code was active when I got REST working with Jersey (org.glassfish.jersey.servlet.ServletContainer), defining a different path in web.xml.  This was originally developed in Tomcat, which is why I needed Jersey at the time.  It ran just fine in Wildfly with quite a few REST services until I needed to begin using EJBs, bringing me here.

               

              Also had to have the @stateless annotation in the REST class.  Would really like to understand that more, since this isn't an EJB, at least not by the old definition. 

               

              If you have a chance, I'd appreciate it if you can take a look at the questions in the previous reply.

              • 4. Re: Cannot access local stateless EJB interface from WAR (REST)
                Wolfgang Mayer Master

                >>> I noticed it leaves out local and remote interfaces.  Is this acting like a local interface?  Is there also an implicit remote interface?  I'd hope for security reasons that remote interfaces are still explicit.

                "A Session Bean’s no-interface view is a variation of the Local view". Please see chap 3.4.4 of JSR 318 (Enterprise JavaBeans,Version 3.1)

                 

                >>> Will this work just fine with JTA and CMT?  That is the primary reason I use EJBs.

                Chap 13 of JSR 318 focuses on transactions

                 

                >>> If I just put it all in the WAR, will CMT still work?

                Chap 20 of JSR 318 focuses on packaging.

                • 5. Re: Cannot access local stateless EJB interface from WAR (REST)
                  Erik Sliman Apprentice

                  Thank you.

                   

                  To help the next guy, answers below...

                   

                  _____

                  >>> I noticed it leaves out local and remote interfaces.  Is this acting like a local interface?  Is there also an implicit remote interface?  I'd hope for security reasons that remote interfaces are still explicit.

                  "A Session Bean’s no-interface view is a variation of the Local view". Please see chap 3.4.4 of JSR 318 (Enterprise JavaBeans,Version 3.1)

                   

                  Yes, it acts like a local interface in that the container intercepts invocations and handles it properly like a session bean.

                   

                  _____

                  >>> Will this work just fine with JTA and CMT?  That is the primary reason I use EJBs.

                  Chap 13 of JSR 318 focuses on transactions

                   

                  Yes.

                   

                  Whenever a client invokes a method  on an enterprise bean’s business interface (or on the no-interface view  or home or component interface of an enterprise bean),  the container interposes on the method  invocation. The interposition allows the container  to control transaction demarcation declaratively  through the transaction attribute set by the developer. (See Section 13.3.7 for a description of transaction attributes.)

                   

                  _____

                  >>> If I just put it all in the WAR, will CMT still work?

                  Chap 20 of JSR 318 focuses on packaging.

                   

                  Section 20.4 says yes, you can include EJBs in a WAR now.  But, it is not backward compatible with EJB 2.1/1/1 beans, which must still be in an EJB module.