Results 1 to 7 of 7

Thread: Accessing local EJB from Servlet throws Exception

  1. #1
    Join Date
    Nov 2004
    Posts
    7

    Default Accessing local EJB from Servlet throws Exception

    Hi,

    I have problems using the Spring EJB access class to access a local EJB from a servlet.
    My application server is JBoss4RC1.

    I get the following Exception:
    =============================
    18:12:21,538 ERROR [Engine] StandardWrapperValve[HelloWorld]: Servlet.service()
    for servlet HelloWorld threw exception
    java.lang.IllegalArgumentException: object is not an instance of declaring class

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at org.springframework.ejb.access.LocalSlsbInvokerInt erceptor.invoke(LocalSlsbInvokerInterceptor.java:6 0)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :138)
    at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:152)
    at $Proxy69.sayHello(Unknown Source)
    at HelloWorld.doGet(HelloWorld.java:48)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:697)


    My EJB consists of the following classes:
    ========================================
    -local interface LocalHello.java
    -bean LocalHelloBean.java
    -home interface LocalHelloHome.java
    In addition I have defined a business interface Local.java, my bean class implements
    this interface.

    My applicationContext.xml:
    ==========================
    <beans>
    <bean id="local" class="org.springframework.ejb.access.LocalStatele ssSessionProxyFactoryBean">
    <property name="jndiName"><value>MeinEJB</value></property>
    <property name="businessInterface"><value>test.Local</value></property>
    </bean>


    <bean id="myBD" class = "HelloWorld">
    <property name="local"><ref bean="local"/></property>
    </bean>
    </beans>


    My servlet:
    ===========
    public class HelloWorld extends HttpServlet {

    private static Local local=null;


    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {


    // working version without Springs EJB Access classes
    try {

    InitialContext jndiContext= new InitialContext();
    Object ref = jndiContext.lookup("MeinEJB");

    LocalHelloHome home = (LocalHelloHome)PortableRemoteObject.narrow(ref,Lo calHelloHome.class);
    LocalHello myLocal = home.create();
    System.out.println(myLocal.sayHello("Test1234"));

    } catch (Exception e) {
    e.printStackTrace();
    }
    // version with Springs EJB access classes throws an exception
    System.out.println(local.sayHello("Test789"));

    }


    public void init(){
    ServletContext ctx=this.getServletContext();
    ApplicationContext app=WebApplicationContextUtils.getWebApplicationCo ntext(ctx);
    }

    public void setLocal(Local hello){
    this.local=hello;
    }
    }

    I checked that init, setLocal were invoked. The version without Spring works fine, but
    the line System.out.println(local.sayHello("Test789")); throws the exception.

    Can you please tell me what's wrong?

    Thanks and best regards
    Nicole Wengatz

  2. #2
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    First of all you should not use DI to inject resources into Servlets:
    <bean id="myBD" class = "HelloWorld">
    <property name="local"><ref bean="local"/></property>
    </bean>
    ...
    public void setLocal(Local hello){
    this.local=hello;
    }
    you can however use attribute app to lookup resources from Spring ApplicationContext from within your Servlet.
    I have two questions with regards to your code:
    1. is sayHello member of LocalHello or Local interfaces?
    2. could you show the "version with spring"?
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  3. #3
    Join Date
    Nov 2004
    Posts
    7

    Default

    >First of all you should not use DI to inject resources into Servlets:
    Why not? That's what I understood from the Spring documentation, see Chapter 15.1.2. 'Accessing local SLSBs.
    In my case MyComponent is the class Local and my Servlet offers a method setLocal.

    >you can however use attribute app to lookup resources from Spring ApplicationContext from within your Servlet.
    >I have two questions with regards to your code:
    >1. is sayHello member of LocalHello or Local interfaces?
    sayHello is member of both interfaces.

    public interface Local {
    public java.lang.String sayHello(String name);
    }

    public interface LocalHello extends javax.ejb.EJBLocalObject {

    public java.lang.String sayHello(String name);

    }
    >2. could you show the "version with spring"?
    It is already there in my posting. The init method of my Servlet will be invoked,
    and when executing this line ApplicationContext app=WebApplicationContextUtils.getWebApplicationCo ntext(ctx);
    Spring JNDI looks up my EJB 'MeinEJB' with business interface Local as defined in the applicationContext.xml.

    After this the method setLocal of myServlet will be invoked and the member variable local is set.

    I tried it out with EJB remote interface, there this way works fine.
    What's the problem with local interface here?

    Thanks and Best regards
    Nicole

  4. #4
    Join Date
    Aug 2004
    Location
    Montréal, Canada
    Posts
    845

    Default

    Nicole,

    1. EJB, Servlets and Spring DI
    Injecting EJB references into classes is what Spring EJB Integration is for. However, in your case you are trying to inject the reference into a servlet. This can not be managed by Spring since Spring does not manage the Servlet life cycle. As I said, you can use Spring as a singleton to retrieve the reference to your EJB:
    Code:
    public void init&#40;&#41;&#123; 
    ServletContext ctx=this.getServletContext&#40;&#41;; 
    ApplicationContext app=WebApplicationContextUtils.getWebApplicationContext&#40;ctx&#41;; 
    &#125;
    then just call
    Code:
    HelloLocal myLocal = &#40;HelloLocal&#41; app.getBean&#40;"local"&#41;;
    to access your EJB.
    2. Spring support for EJBs
    When you configure a LocalStatelessSessionProxyFactoryBean into your applicationContext.xml, Spring implements the plumbing to access the EJB (initialContext, loockup, Home caching ...). With that said, you no longer need to use the following code inside your client (servlet):
    InitialContext jndiContext= new InitialContext();
    Object ref = jndiContext.lookup("MeinEJB");

    LocalHelloHome home = (LocalHelloHome)PortableRemoteObject.narrow(ref,Lo calHelloHome.class);
    LocalHello myLocal = home.create();
    The following line of code will do the job for you:
    Code:
    HelloLocal myLocal = &#40;HelloLocal&#41; app.getBean&#40;"local"&#41;;
    HTH
    Omar Irbouh

    Spring Modules Team
    http://irbouh.blogspot.com/

  5. #5
    Join Date
    Nov 2004
    Posts
    7

    Default

    Hi Omar,

    thank you very much for your help, the solution you proposed works fine :-)

    BUT, I still have some severe doubts:

    1) Now my Servlet has to know the interface LocalHello which extends javax.ejb.EJBLocalObject,
    so it's not longer independent from EJB technology. That was one of my reasons (the main reason)
    to start evaluating Spring :-(

    2) When I access an EJB via the remote interface using the SimpleRemoteStatelessSessionProxyFactoryBean
    my servlet/client DOES NOT need to know the EJB remote interface class.
    In this scenario I can use the (EJB independent) business interface
    public interface Hello {
    public java.lang.String sayHello(String name);
    }

    So could you please explain me why there is such a big difference in the design of the two
    classes?

    Thank you very much!
    Nicole

  6. #6
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    Quote Originally Posted by wengatz_n
    1) Now my Servlet has to know the interface LocalHello which extends javax.ejb.EJBLocalObject,
    so it's not longer independent from EJB technology.
    That can be mended quite easily

    You can provide two interfaces, where the EJB local interface inherits from your buisness interface. That way your client is agnostic of EJB.

    Example:

    public interface Hello {
    void sayHello();
    }

    public interface LocalHello extends Hello, EJBLocalObject {}


    So you can use Hello instead of LocalHello in your servlet.

    Regards,
    Andreas

  7. #7
    Join Date
    Nov 2004
    Posts
    7

    Default

    Thanks a lot for your help.
    That works fine and I'm happy :-)

Similar Threads

  1. Context initialization failed
    By kanonmicke in forum Container
    Replies: 7
    Last Post: Sep 29th, 2005, 12:35 AM
  2. Replies: 3
    Last Post: Sep 22nd, 2005, 10:14 AM
  3. could not satisfy dependencies
    By springuser in forum Container
    Replies: 4
    Last Post: Apr 26th, 2005, 01:15 PM
  4. Replies: 1
    Last Post: Apr 25th, 2005, 07:37 PM
  5. Replies: 3
    Last Post: Nov 8th, 2004, 07:30 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •