Announcement Announcement Module
Collapse
No announcement yet.
Complete Code For Spring-StateLessSessionBean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Complete Code For Spring-StateLessSessionBean

    This is what i did , think this should help you also.

    server is jboss-3.0.4_tomcat-4.1.12 with spring1.1.4

    EJB Jar Should contain the Following :

    Code:
    /*
     * Created on Oct 14, 2005
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package spn;
    
    import java.rmi.RemoteException;
    
    /**
     * @author sathyanarayanan
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public interface EchoService {
    	public String echo(String message)throws RemoteException;
    }
    Code:
    /*
     * Created on Oct 14, 2005
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package spn;
    import javax.ejb.EJBObject;
    
    /**
     * @author sathyanarayanan
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public interface EchoServiceRemote extends EJBObject , EchoService  {
    
    }
    Code:
    /*
     * Created on Oct 14, 2005
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package spn;
    
    import java.rmi.RemoteException;
    
    import javax.ejb.CreateException;
    import javax.ejb.EJBHome;
    
    /**
     * @author sathyanarayanan
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public interface EchoServiceHome extends EJBHome {
    	public EchoServiceRemote create() throws CreateException ,RemoteException;
    }
    Code:
    /*
     * Created on Oct 14, 2005
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package spn;
    
    /**
     * @author sathyanarayanan
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public class EchoServiceImpl implements EchoService  {
    
    	/* (non-Javadoc)
    	 * @see spn.EchoService#echo(java.lang.String)
    	 */
    	public String echo(String message) {
    		// TODO Auto-generated method stub
    		return message;
    	}
    
    }
    Code:
    /*
     * Created on Oct 14, 2005
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package spn;
    
    import javax.ejb.CreateException;
    import java.rmi.RemoteException;
    
    import org.springframework.ejb.support.AbstractStatelessSessionBean;
    
    /**
     * @author sathyanarayanan
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    public class EchoServiceEJB extends AbstractStatelessSessionBean implements
    		EchoService {
    
    	private static final String BEAN_NAME = "EchoServiceImpl";
    	private EchoService service ;
    	/**
    	 * Comment for <code>serialVersionUID</code>
    	 */
    	private static final long serialVersionUID = 1L;
    
    	/* &#40;non-Javadoc&#41;
    	 * @see org.springframework.ejb.support.AbstractStatelessSessionBean#onEjbCreate&#40;&#41;
    	 */
    	protected void onEjbCreate&#40;&#41; throws CreateException &#123;
    		service = &#40;EchoService&#41; getBeanFactory&#40;&#41;.getBean&#40;BEAN_NAME&#41;;
    
    	&#125;
    
    	/* &#40;non-Javadoc&#41;
    	 * @see spn.EchoService#echo&#40;java.lang.String&#41;
    	 */
    	public String echo&#40;String message&#41; throws RemoteException &#123;
    		// TODO Auto-generated method stub
    		System.out.println&#40;message&#41;;
    		return service.echo&#40;message&#41;;
    	&#125;
    
    	/**
    	 * @return Returns the service.
    	 */
    	public EchoService getService&#40;&#41; &#123;
    		return service;
    	&#125;
    	/**
    	 * @param service The service to set.
    	 */
    	public void setService&#40;EchoService service&#41; &#123;
    		this.service = service;
    	&#125;
    &#125;
    Code:
    applicationContext.xml
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    <beans default-autowire="autodetect">
    	  <bean id="EchoServiceImpl" class="spn.EchoServiceImpl" />
    	  <bean id="EchoServiceEJB" class="spn.EchoServiceEJB">
    			<property name="service">
    					<ref local="EchoServiceImpl" />
    			</property>
    	  </bean>
    </beans>
    Code:
    ejb-jar.xml
    
    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http&#58;//java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
    
    <ejb-jar>
    	<enterprise-beans>
    		<session>
    			<ejb-name>EchoServiceEJB</ejb-name>
    			<home>spn.EchoServiceHome</home>
    			<remote>spn.EchoServiceRemote</remote>
    			<ejb-class>spn.EchoServiceEJB</ejb-class>
    			<session-type>Stateless</session-type>
    			<transaction-type>Container</transaction-type>
    			<env-entry>
    				<env-entry-name>ejb/BeanFactoryPath</env-entry-name>
    				<env-entry-type>java.lang.String</env-entry-type>
    				<env-entry-value>applicationContext.xml</env-entry-value>
    		   </env-entry>
    		</session>
    	</enterprise-beans>
    
    	<assembly-descriptor>
    		<container-transaction>
    			<method>
    				<ejb-name>EchoServiceEJB</ejb-name>
    				<method-intf>Remote</method-intf>
    				<method-name>*</method-name>
    			</method>
    			<trans-attribute>Required</trans-attribute>
    		</container-transaction>
    	</assembly-descriptor>
    </ejb-jar>
    Code:
    jboss.xml
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <jboss>
    	<enterprise-beans>
    		<session>
    			<ejb-name>EchoServiceEJB</ejb-name>
    			<jndi-name>ejb/echoService</jndi-name>
    		</session>
    	</enterprise-beans>
    </jboss>
    Package Structure:
    Spring EJB
    - META-INF
    ejb-jar.xml
    jboss.xml
    - spn
    all the java classes
    - WEB-INF
    -- lib
    commons-logging-1.0.3.jar
    spring-1.1.4.jar

    - applicationContext.xml

    Note:
    make sure applicationContext.xml is in the classpath.


    In the Client Side :

    have a spn folder with the remote,home,the echoservice interfaces.



    Code:
    BeanConfig.xml
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    
    	  <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
            <property name="environment">
                <value>
                java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
                java.naming.provider.url=jnp&#58;//localhost&#58;1099
                java.naming.factory.url.pkgs=org.jboss.naming&#58;org.jnp.interfaces
                </value>
            </property>
         </bean>
    
    	 <bean id="echoService" class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
    		   <property name="jndiName">
    				<value>ejb/echoService</value>
    		   </property>
    		   <!--property name="resourceRef">
    				<value>false</value>
    		   </property-->
    		   <property name="jndiTemplate">
                <ref local="jndiTemplate"/>
             </property>
    		   <property name="businessInterface">
    				<value>spn.EchoService</value>
    		   </property>
    	</bean>
    
    
    </beans>

    Code:
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.core.io.FileSystemResource;
    
    import spn.EchoService;
    
    
    public class Executor
    &#123;
         public static void main&#40;String&#91;&#93; arg&#41;
          &#123;
           try
           &#123;
              InputStream beanConfigFile = new FileInputStream&#40;"C&#58;\\SpringPersist\\BeanConfigFile.xml"&#41;;
              BeanFactory factory =&#40;BeanFactory&#41; new XmlBeanFactory&#40;beanConfigFile&#41;;
               //echoService
              EchoService remoteBean=&#40;EchoService&#41;factory.getBean&#40;"echoService"&#41;;
              System.out.println&#40;remoteBean&#41;;
              String echoedMessage = remoteBean.echo&#40;"Om Sri SaiRam"&#41;;
              System.out.println&#40;"echoedMessage&#58;"+echoedMessage&#41;;
    
    
    
    
            &#125;
            catch&#40;Exception e&#41;
            &#123;
              e.printStackTrace&#40;&#41;;
            &#125;
    
          &#125;
    &#125;
    
    
    Note&#58; you should have these jars.
    
    
    Add all the jars from the C&#58;\jboss-3.0.4_tomcat-4.1.12\client
    and the jboss-common.ajr and log4j.jar from C&#58;\jboss-3.0.4_tomcat-4.1.12\lib

    Thats all .All the Best.

  • #2
    Complete Code For Spring-StateLessSessionBean

    Thanks for the code,

    I'd like to ask question regarding your business interface :

    ...
    import java.rmi.RemoteException;

    public interface EchoService
    {
    public String echo(String message)throws RemoteException;
    }

    Your business interface requires us to catch RemoteException everytime we call its method.

    I've seen example from Spring documentation and its business interface does not throw RemoteException, also Spring states that it wraps all RemoteException into RemoteAccessException which is unchecked exception. But I don't see it implemented in your code.

    So, do we really need to throw RemoteException on business interface ?


    Regards,


    Setya

    Comment


    • #3
      No. But, what you end up with is two interfaces. One that implements your business interface and the other which implements the EJB interface (which is almost identical).

      This example would look like the following using XDoclet. Basically you specify the business interface, the business object and the EJB bean implementation. XDoclet would generate the Home, remote interface, ejb-jar.xml, jboss.xml. And the business interface doesn't have any hint of RemoteException. This would allow you to migrate the remoting implementation to Hessian/Burlap/RMI or anything else (or nothing at all, using the local object). Note that the business methods in the Bean class must have the @ejb:interface-method tag.

      I have patterned this after an actual working example that I've implemented. It really works and saves you from writing more than you have to.

      EchoService.java:
      Code:
      package spn;
      
      public interface EchoService {
      	public String echo(String message);
      }
      EchoServiceImpl.java:
      Code:
      package spn;
      
      public class EchoServiceImpl implements EchoService {
      
      	public String echo(String message) {
      		return message;
      	}
      }
      EchoServiceBean.java: (notice the different package):
      Code:
      package ejb.impl;
      
      import javax.ejb.CreateException;
      
      import org.springframework.ejb.support.AbstractStatelessSessionBean;
      
      import spn.EchoService;
      
      /**
       * @ejb:bean name="EchoServiceEJB"
       * display-name="EchoServiceEJB"
       * jndi-name="ejb/echoService"
       * type="Stateless"
       * view-type="remote"
       * transaction-type="Container"
       * 
       * @ejb:home extends="javax.ejb.EJBHome"
       * 
       * @ejb:interface extends="javax.ejb.EJBObject"
       *
       * @ejb:env-entry name="ejb/BeanFactoryPath"
       * type="java.lang.String"
       * value="applicationContext.xml" 
       * 
       * @jboss.container-configuration name="Standard Stateless SessionBean"
       * 
       * @weblogic max-beans-in-free-pool="100"
       *  
       * @author william.poitras
       *
       */
      public class EchoServiceBean extends AbstractStatelessSessionBean implements EchoService {
      
      	private static final String BEAN_NAME = "EchoServiceImpl";
      	EchoService echoService;
      	protected void onEjbCreate() throws CreateException {
      		echoService = (EchoService)getBeanFactory().getBean(BEAN_NAME);
      	}
      
      	/**
      	 * @ejb:interface-method
      	 */
      	public String echo(String message) {
      		return echoService.echo(message);
      	}
      	
      }
      Ant snippet for XDoclet generation:
      Code:
      	<target name="generate-ejb">
      		<mkdir dir="${gen.src.dir}" />
      		<mkdir dir="${ejb.deployment.dir}" />
      		<taskdef name="ejbdoclet" classname="xdoclet.modules.ejb.EjbDocletTask" classpathref="xdoclet.lib.path" />
      
      		<ejbdoclet destdir="${gen.src.dir}">
      			<packageSubstitution packages="impl" substituteWith="api" />
      			<fileset dir="${src.dir}">
      				<include name="**/*Bean.java" />
      			</fileset>
      
      			<deploymentdescriptor destdir="${ejb.deployment.dir}" />
      
      			<jboss destdir="${ejb.deployment.dir}" />
      			<homeinterface />
      			<remoteinterface />
      		</ejbdoclet>
      	</target>

      Comment


      • #4
        Complete Code For Spring-StateLessSessionBean

        Thanx for the response,

        And what would the generated Remote Interface look like ?

        Regards,


        Setya

        Comment


        • #5
          It looks like this (the .api package name was generated by XDoclet by substituting for .impl for .api, its part of the ejbdoclet call).

          One thing you might notice: the implementation of the bean doesn't throw any exceptions but the remote interface does. The way this works is you throw EJBException (which is unchecked) from your Bean class and the container will convert those to RemoteExceptions
          Code:
          package ejb.api;
          
          /**
           * Remote interface for EchoService .
           * @weblogic max-beans-in-free-pool="100"
           */
          public interface EchoService 
             extends javax.ejb.EJBObject
          {
          
             public String echo(String message)
                throws java.rmi.RemoteException;
          
          }

          Comment


          • #6
            Complete Code For Spring-StateLessSessionBean

            I understand now.

            Thank you very much for you assistance.

            Regards,


            Setya

            Comment


            • #7
              This code doesn't work for me if i try on the same jboss the webapp and the ejb the error is :

              java.rmi.ServerException: EJBException:; nested exception is:
              javax.ejb.EJBException: Invalid invocation, check your deployment packaging, method=public abstract ejb.api.EchoServiceEJB ejb.api.EchoServiceEJBHome.create() throws javax.ejb.CreateException,java.rmi.RemoteException


              but if the webapps and the client are in two different jboss, it works

              Can you help me ?

              Comment


              • #8
                Where are you throwing the EJBException? If its part of the creation, you might consider throwing a CreateException.

                Comment


                • #9
                  Excuse me but i don't understand, what do you want to know ?.

                  Comment


                  • #10
                    Could you post your code for the EchoServiceEJB? Include the XDoclet comments as well.

                    Comment


                    • #11
                      Hi,

                      i have tried in another way and now it works probably just a misunderstanding from me, but no matters thanks for all.

                      Do you know how i can with a webapps see all ejb in a jndi and load them with the dependancy injection in Spring. Imagine you have a webapps that can find automatically all services of a type and load them because they all implements the same interface(something like plugins).

                      Thanks,

                      Avalone.

                      Comment


                      • #12
                        Complete separation of web application and services+daos

                        Hello all,

                        I see few examples on SPRING + EJBs and I would like to thank everybody for contributing exposing these code lines!

                        I want to expose my problem.

                        I have a classic five layers architecture application with a complete separation between web stuff and services (managers in appfuse) and DAOs + model.
                        I use Spring as web framework.
                        In my actions I use delegates who does JNDI lookup with a Locator to EJB stateless services (I don't use Spring for that).
                        Only Services + DAOs have SPRING implementation.
                        I obtain this kind of error even if application deployment seems good :


                        java.rmi.ServerError: Unexpected Error:; nested exception is:
                        java.lang.StackOverflowError
                        org.jboss.ejb.plugins.LogInterceptor.handleExcepti on(LogInterceptor.java:398)
                        org.jboss.ejb.plugins.LogInterceptor.invoke(LogInt erceptor.java:195)
                        org.jboss.ejb.plugins.ProxyFactoryFinderIntercepto r.invoke(ProxyFactoryFinderInterceptor.java:122)
                        org.jboss.ejb.StatelessSessionContainer.internalIn voke(StatelessSessionContainer.java:331)
                        org.jboss.ejb.Container.invoke(Container.java:709)
                        sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
                        sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
                        sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
                        java.lang.reflect.Method.invoke(Method.java:324)
                        org.jboss.mx.server.ReflectedDispatcher.dispatch(R eflectedDispatcher.java:60)
                        org.jboss.mx.server.Invocation.dispatch(Invocation .java:62)
                        org.jboss.mx.server.Invocation.dispatch(Invocation .java:54)
                        org.jboss.mx.server.Invocation.invoke(Invocation.j ava:82)
                        org.jboss.mx.server.AbstractMBeanInvoker.invoke(Ab stractMBeanInvoker.java:197)
                        org.jboss.mx.server.MBeanServerImpl.invoke(MBeanSe rverImpl.java:473)
                        org.jboss.invocation.local.LocalInvoker.invoke(Loc alInvoker.java:97)
                        org.jboss.invocation.InvokerInterceptor.invoke(Inv okerInterceptor.java:90)
                        org.jboss.proxy.TransactionInterceptor.invoke(Tran sactionInterceptor.java:46)
                        org.jboss.proxy.SecurityInterceptor.invoke(Securit yInterceptor.java:55)
                        org.jboss.proxy.ejb.StatelessSessionInterceptor.in voke(StatelessSessionInterceptor.java:100)
                        org.jboss.proxy.ClientContainer.invoke(ClientConta iner.java:85)
                        $Proxy74.findUser(Unknown Source)
                        com.dsinfo.hyperproject.common.delegate.ResourceDe legate.findUser(ResourceDelegate.java:68)
                        com.dsinfo.hyperproject.web.struts.action.LogonAct ion.login(LogonAction.java:52)
                        sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
                        sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
                        sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
                        java.lang.reflect.Method.invoke(Method.java:324)
                        org.apache.struts.actions.DispatchAction.dispatchM ethod(DispatchAction.java:274)
                        org.apache.struts.actions.DispatchAction.execute(D ispatchAction.java:194)
                        com.dsinfo.hyperproject.web.struts.action.BaseDisp atchAction.execute(BaseDispatchAction.java:28)
                        org.apache.struts.action.RequestProcessor.processA ctionPerform(RequestProcessor.java:419)
                        org.apache.struts.action.RequestProcessor.process( RequestProcessor.java:224)
                        org.apache.struts.action.ActionServlet.process(Act ionServlet.java:1196)
                        org.apache.struts.action.ActionServlet.doPost(Acti onServlet.java:432)
                        javax.servlet.http.HttpServlet.service(HttpServlet .java:717)
                        javax.servlet.http.HttpServlet.service(HttpServlet .java:810)
                        org.jboss.web.tomcat.filters.ReplyHeaderFilter.doF ilter(ReplyHeaderFilter.java:75)



                        In fact, I wanted to know if I have to register SPRING application context in the client or this kind of implementation is possible.

                        Thanks all !


                        David

                        Comment


                        • #13
                          There is no reason why you can't use a service locator. EJBs implemented using Spring are still EJBs. There must be another issue.

                          Comment


                          • #14
                            Wow!!

                            It works!!! Thanks!!!

                            Comment

                            Working...
                            X