12 Replies Latest reply on Aug 28, 2008 3:01 AM by nbhatia.bhatian.comcast.net

    Can't access session bean from front-end

    nbhatia.bhatian.comcast.net
      I have just started learning Seam. I am trying to access a stateless session bean from the front end, but somehow it's not working.

      Here's an excerpt from my facelets page:


      `<h:inputText value="#{helloWorld.firstName}" />`


      I am getting this error:


      `javax.servlet.ServletException: /pages/login.xhtml @22,67 value="#{helloWorld.firstName}": Target Unreachable, identifier 'helloWorld' resolved to null`


      Here's my stateless session bean:

      @Stateless
      @Name("helloWorld")
      public class HelloWorldBean implements HelloWorld {
         
          private String firstName;
         
          public String getFirstName() {
              return firstName;
          }
          public void setFirstName(String firstName) {
              this.firstName = firstName;
          }

          ...
      }

      I can see that it is published in my JNDI tree as:

        +- helloworldseam-app-1.0
        |   +- HelloWorldBean
        |   |   +- local (proxy: $Proxy76 implements interface samples.helloworldseam.HelloWorld,interface org.jboss.ejb3.JBossProxy)


      I have defined jndi-pattrn as follows in my components.xml:

      <core:init jndi-pattern="helloworldseam-app-1.0/#{ejbName}/local" debug="true"/>

      Why is the front-end not finding the bean? Which concept am I missing?

      Thanks.
      Naresh
        • 1. Re: Can't access session bean from front-end
          blabno

          Show deployment log. I bet you do not have seam.properties in your EJB module.

          • 2. Re: Can't access session bean from front-end
            nimo22

            Your HelloWorld.java must be an interface having at least two methods:


            public String getFirstName();
            public void setFirstName(String firstName);


            Ensure that this is done.


            • 3. Re: Can't access session bean from front-end
              blabno

              This is not an issue here. The component itself cannot be found by Seam.

              • 4. Re: Can't access session bean from front-end
                cosmo

                Do you see the same error if your SLSB is local?

                • 5. Re: Can't access session bean from front-end
                  nbhatia.bhatian.comcast.net
                  Thank you all for your help.

                  1) Yes, I did not have seam.properties. That was my first problem. I was able to move one step forward after adding this file - the front-end seemed to reach "some" bean or proxy.

                  2) Next problem indeed was that I did not have getters and setters on my fields in the SLSB interface (got some cryptic message from facelets on this). Anyway, after I added getters and setters I moved forward one more step.

                  Now I am getting this error:

                  SEVERE: Error Rendering View[/pages/login.xhtml]
                  javax.faces.FacesException: javax.el.ELException: /pages/login.xhtml @22,67 value="#{helloWorld.firstName}": Error reading 'firstName' on type org.javassist.tmp.java.lang.Object_$$_javassist_2
                  Caused by: javax.el.ELException: /pages/login.xhtml @22,67 value="#{helloWorld.firstName}": Error reading 'firstName' on type org.javassist.tmp.java.lang.Object_$$_javassist_2
                  Caused by: java.lang.IllegalArgumentException: Could not invoke method by reflection: HelloWorld.getFirstName() on: $Proxy156
                  Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
                          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                          at java.lang.reflect.Method.invoke(Method.java:597)
                          at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
                          ... 64 more

                  Where do I go from here?

                  Thanks.
                  Naresh

                  P.S. BTW, my SLSB is already in local scope:

                  @Stateless
                  @Name("helloWorld")
                  public class HelloWorldBean implements HelloWorld {
                      ...
                  }
                  • 6. Re: Can't access session bean from front-end
                    monkeyden

                    Does the interface have the @Local annotation?  Please post all relevant code.

                    • 7. Re: Can't access session bean from front-end
                      nbhatia.bhatian.comcast.net
                      The interface does NOT have a @Local annotation - I thought that the EJB3 specification allows pure Java interfaces without any annotations (@Local and @Remote can only be specified on the implementation - @Local being the default). This has certainly worked for me in pure EJB3 applications. The JBoss EJB 3.0 TrailBlazer examples also show this approach.

                      Having said that, I see that the Seam samples do put @Local on the interface (e.g. in the registration example, the Register interface is annotated with @Local) - I don't understand why. Anyway, I tried putting @Local on my interface and I am getting a different error now:

                      java.lang.IllegalArgumentException: value of context variable is not an instance of the component bound to the context variable: helloWorld

                      What should I do next? Here's the current state of my code:

                      HelloWorld.java
                      ===============
                      package samples.helloworldseam;

                      import javax.ejb.Local;

                      @Local
                      public interface HelloWorld {
                          public String getFirstName();
                          public void setFirstName(String firstName);
                          public String getGreeting();
                          public void setGreeting();
                      }

                      HelloWorldBean.java
                      ===================
                      package samples.helloworldseam;

                      import javax.ejb.Stateless;

                      import org.jboss.seam.annotations.Name;

                      @Stateless
                      @Name("helloWorld")
                      public class HelloWorldBean implements HelloWorld {
                         
                          private String firstName;
                          private String greeting;
                         
                          public String getFirstName() {
                              return firstName;
                          }
                          public void setFirstName(String firstName) {
                              this.firstName = firstName;
                          }

                          public String getGreeting() {
                              return greeting;
                          }
                          public void setGreeting() {
                              greeting = null;
                              if (firstName != null && !firstName.isEmpty()) {
                                  greeting = "Hello " + firstName;
                              }
                          }
                      }

                      login.html
                      ==========
                      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                      <ui:composition
                          xmlns="http://www.w3.org/1999/xhtml"
                          xmlns:c="http://java.sun.com/jstl/core"
                          xmlns:f="http://java.sun.com/jsf/core"
                          xmlns:h="http://java.sun.com/jsf/html"
                          xmlns:ui="http://java.sun.com/jsf/facelets"
                          template="/templates/template.xhtml">

                          <ui:define name="body">

                              <h:form id="login">
                                  <div>
                                      <table border="0">
                                          <tr>
                                              <td valign="top" align="right">
                                                  First Name:
                                              </td>
                                              <td>
                                                  <h:inputText style="width: 12em; border: solid 1px #808080;"
                                                      value="#{helloWorld.firstName}" />
                                              </td>
                                              <td>
                                                  <h:commandButton action="#{helloWorld.setGreeting}" value="Submit"/>
                                              </td>
                                          </tr>
                                      </table>
                                  </div>
                              </h:form>
                             
                              <div>
                                  #{helloWorld.greeting}
                              </div>

                          </ui:define>

                      </ui:composition>

                      I can attach my complete code to a JIRA issue if needed. FYI, I am trying to create the entire project from scratch using Maven 2. The examples provided with Seam use non-standard Maven layout and it is too difficult understand. I am sure there is justification for this layout, but it certainly slows down the learning curve for people who are used to the standard Maven layout.

                      Thanks.
                      Naresh
                      • 8. Re: Can't access session bean from front-end
                        blabno

                        Not sure but maybe ... setGreeting method breaks JavaBean contract. Name your action method differently i.e. public void greet().

                        • 9. Re: Can't access session bean from front-end
                          nbhatia.bhatian.comcast.net
                          Good thought. I tried it and I am back to the original error:

                          javax.faces.FacesException: javax.el.ELException: /pages/login.xhtml @22,67 value="#{helloWorld.firstName}": Error reading 'firstName' on type

                          If I remove the @Local from the HelloWorld interface then I still get:

                          java.lang.IllegalArgumentException: value of context variable is not an instance of the component bound to the context variable: helloWorld
                          • 10. Re: Can't access session bean from front-end
                            blabno

                            Do not remove @Local annotation. Post your bean code, and please format it well.
                            If you want, send me your project and I will debug it. s4237 at pjwstk dot edu dot pl

                            • 11. Re: Can't access session bean from front-end
                              blabno

                              Error was trivial. Always show full stack trace for the last lines tend to be most meaningful. You had helloworldseam-server-1.0.jar (the ejb module) inside WEB-INF/lib which caused ClassCast family exception. Actually it was



                              Caused by: java.lang.IllegalArgumentException: Could not invoke method by reflection: HelloWorld.getFirstName() on: $Proxy85

                              and



                              Caused by: java.lang.IllegalArgumentException: HelloWorldBean

                              but the problem was in class loading.

                              • 12. Re: Can't access session bean from front-end
                                nbhatia.bhatian.comcast.net

                                Thanks so much Bernard. That was indeed the problem.


                                Now that the app is running, I removed the @Local from the interface and it still works. So the only remaining question in my mind is why do Seam examples use @Local on the interface? I have not seen this in the EJB3 specs or even in JBoss EJB3 examples.


                                Thanks.
                                Naresh