Announcement Announcement Module
Collapse
No announcement yet.
Message Driven Bean + Spring: NullPointerException error? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Message Driven Bean + Spring: NullPointerException error?

    Hi all!

    I'm building a project using EJB 2.1 Message Driven Bean + Spring. I have 2 XML files:

    - beanRefContext.xml


    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
    	<bean id="businessBeanFactory"
    		class="org.springframework.context.support.ClassPathXmlApplicationContext">
    		<constructor-arg value="businessApplicationContext.xml" />
    	</bean>
    </beans>

    - businessApplicationContext.xml


    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:jee="http://www.springframework.org/schema/jee"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    	http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
    	
         <jee:jndi-lookup id="userTransaction" jndi-name="java:comp/UserTransaction"/> 
    	
        <jee:jndi-lookup id="oracleDataSource" jndi-name="jdbc/dsTTR"/>
        
        <bean id="demoFacade" class="com.fse.ecs.domain.logic.implement.DemoFacadeImpl">
    		<property name="transaction" ref="userTransaction"/>  
        	<property name="demoOraDao" ref="demoOraDao"/>
        </bean>
    
    	<!-- SqlMap setup for iBATIS Database Layer -->
    	<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    		<property name="configLocation" value="sql-map-config.xml"/>
    	</bean>
    	
    	<!-- ========================= DAO DEFINITIONS: IBATIS IMPLEMENTATIONS ========================= -->
    	<bean id="demoOraDao" class="com.fse.ecs.dao.ibatis.DemoDeclarationOraDaoImpl">
    		<property name="dataSource" ref="oracleDataSource"/>
    		<property name="sqlMapClient" ref="sqlMapClient"/>
    	</bean>
    
    </beans>

    - ejb-jar.xml


    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <ejb-jar id="ejb-jar_ID" version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
    	<display-name>
    	ECSDemoMDB</display-name>
    	<enterprise-beans>
    		<message-driven id="MDB">
    			<ejb-name>MDB</ejb-name>
    			<ejb-class>com.fse.ecs.ejb.MDBBean</ejb-class>
    			<messaging-type>javax.jms.MessageListener</messaging-type>
    			<transaction-type>Bean</transaction-type>
    			<message-destination-type>javax.jms.Queue</message-destination-type>
    			<activation-config>
    				<activation-config-property>
    					<activation-config-property-name>destinationType</activation-config-property-name>
    					<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
    				</activation-config-property>
    			</activation-config>
    		</message-driven>
    	</enterprise-beans>
    	<assembly-descriptor>
    	</assembly-descriptor>
    </ejb-jar>
    - And MDBBean class extends org.springframework.ejb.support.AbstractMessageDri venBean

    Code:
    package com.fse.ecs.ejb;
    
    import javax.jms.BytesMessage;
    import javax.jms.JMSException;
    import javax.jms.TextMessage;
    
    import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
    
    import com.fse.ecs.domain.DeclarationBean;
    import com.fse.ecs.domain.logic.DemoFacade;
    import com.fse.ecs.domain.logic.implement.DemoFacadeImpl;
    import com.fse.ecs.util.DeclarationUtil;
    
    import demo.ibm.business.BusinessFacade;
    
    /**
     * Bean implementation class for Enterprise Bean: TestMDB
     */
    public class TestMDBBean extends org.springframework.ejb.support.AbstractMessageDrivenBean
    	implements
    		javax.ejb.MessageDrivenBean,
    		javax.jms.MessageListener {
    
    
    	/**
    	 * setMessageDrivenContext
    	 */
    	public void setMessageDrivenContext(javax.ejb.MessageDrivenContext ctx) {
    		super.setMessageDrivenContext(ctx);
    
    setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
    		setBeanFactoryLocatorKey("businessBeanFactory");
    	}
    
    
    	private DemoFacade facade;
    	
    	/**
    	 * onMessage
    	 */
    	public void onMessage(javax.jms.Message msg) {
    		facade.doBusiness(msg);
    	}
    	
    
    	protected void onEjbCreate() {
    		facade = (DemoFacade) getBeanFactory().getBean("demoFacade");
    	}
    }
    But I cannot get "demoFacade" object, because in onEjbCreate() method:

    facade = (DemoFacade) getBeanFactory().getBean("demoFacade"); //==> java.lang.NullPointerException

    Can you help me to fix this error, thanks!

  • #2
    Is there any ouput in the logfile upon deployment?

    Comment


    • #3
      I think you can rely on default context resolution (in your MDB) and don't need to wrap your applicationContext.xml as you do, if you follow Andreas' suggestion.

      Regards,
      Ollie

      PS: Seems Andreas has edited has post... he suggested to provide the applicationContext.xml as JNDI entry "java:comp/env/ejb/BeanFactoryPath" as the default implementation tries to resolve the context file under location specified in this environment entry.
      Last edited by Oliver Gierke; Nov 13th, 2007, 02:34 AM.

      Comment


      • #4
        Originally posted by Oliver Schlicht View Post
        PS: Seems Andreas has edited has post... he suggested to provide the applicationContext.xml as JNDI entry "java:comp/env/ejb/BeanFactoryPath" as the default implementation tries to resolve the context file under location specified in this environment entry.
        You read fast

        Yes. I proposed to add an environment entry, but afterwards concluded that it might not be necessary for ContextSingletonBeanFactoryLocator.

        Comment


        • #5
          Can you tell me in which XML file should I put the following code

          Code:
          <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>

          Comment


          • #6
            That has to be placed in ejb-jar.xml. Though, for ContextSingletonBeanFactoryLocator that might not help. I suggest investigating the logfile on deployment to see if something else happens before the NPE actually arises.

            Comment


            • #7
              I've tried but it's not work and encounter the following error:

              Code:
              [11/13/07 17:14:58:375 ICT] 00000046 SystemErr     R java.lang.NullPointerException
              [11/13/07 17:14:58:406 ICT] 00000046 SystemErr     R 	at org.springframework.ejb.support.AbstractEnterpriseBean.getBeanFactory(AbstractEnterpriseBean.java:145)
              [11/13/07 17:14:58:406 ICT] 00000046 SystemErr     R 	at com.ejb.TestBean.onEjbCreate(TestBean.java)
              [11/13/07 17:14:58:406 ICT] 00000046 SystemErr     R 	at com.ejb.TestBean.ejbCreate(TestBean.java:42)
              [11/13/07 17:14:58:406 ICT] 00000046 SystemErr     R 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              [11/13/07 17:14:58:406 ICT] 00000046 SystemErr     R 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:85)
              [11/13/07 17:14:58:406 ICT] 00000046 SystemErr     R 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:58)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:60)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at java.lang.reflect.Method.invoke(Method.java:391)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.MessageDrivenBeanO.<init>(MessageDrivenBeanO.java:145)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.BMMessageDrivenBeanO.<init>(BMMessageDrivenBeanO.java:57)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.BMMessageDrivenBeanOFactory.create(BMMessageDrivenBeanOFactory.java:39)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.EJSHome.createBeanO(EJSHome.java:836)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.EJSHome.createBeanO(EJSHome.java:939)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.activator.UncachedActivationStrategy.atActivate(UncachedActivationStrategy.java:83)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.activator.Activator.activateBean(Activator.java:593)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.EJSContainer.preInvokeActivate(EJSContainer.java:3362)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.EJSContainer.preInvoke(EJSContainer.java:2828)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.EJSContainer.preInvoke(EJSContainer.java:2756)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.MDBWrapper.onMessage(MDBWrapper.java:87)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.container.MDBWrapper.onMessage(MDBWrapper.java:127)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ejs.jms.listener.ServerSession.run(ServerSession.java:456)
              [11/13/07 17:14:58:421 ICT] 00000046 SystemErr     R 	at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1332)
              Can you fix it for me!

              Comment


              • #8
                This could normally only happen if the beanfactory has not been resolved. I suspect there must have been another exception before.

                Comment


                • #9
                  In ejb-jar.xml I've tried put in the following code

                  Code:
                  <?xml version="1.0" encoding="UTF-8"?>
                  <ejb-jar id="ejb-jar_ID" version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">
                  	<display-name>
                  	ECSDemoMDB</display-name>
                  	<enterprise-beans>
                  		<message-driven id="MDB">
                  			<ejb-name>MDB</ejb-name>
                  			<ejb-class>com.fse.ecs.ejb.MDBBean</ejb-class>
                  			<messaging-type>javax.jms.MessageListener</messaging-type>
                  			<transaction-type>Bean</transaction-type>
                  			<message-destination-type>javax.jms.Queue</message-destination-type>
                  			<activation-config>
                  				<activation-config-property>
                  					<activation-config-property-name>destinationType</activation-config-property-name>
                  					<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
                  				</activation-config-property>
                  			</activation-config>
                  		    <env-entry>
                  	            <env-entry-name>ejb/BeanFactoryPath</env-entry-name>
                  	            <env-entry-type>java.lang.String</env-entry-type>
                  	            <env-entry-value>businessApplicationContext.xml</env-entry-value>
                  		    </env-entry>
                  		</message-driven>
                  	</enterprise-beans>
                  	<assembly-descriptor>
                  	</assembly-descriptor>
                  </ejb-jar>
                  And businessApplicationContext.xml file put in ejbModule directory

                  In MDBBean class

                  Code:
                  public class MDBBean 
                  	extends AbstractJmsMessageDrivenBean
                  	implements
                  		javax.ejb.MessageDrivenBean,
                  		javax.jms.MessageListener {
                  
                  	private DemoFacade demoFacade = null;
                  	
                  	/**
                  	 * setMessageDrivenContext
                  	 */
                  	public void setMessageDrivenContext(MessageDrivenContext ctx) {	
                  		super.setMessageDrivenContext(ctx);
                  		setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
                  		setBeanFactoryLocatorKey("businessBeanFactory");
                  	}
                  
                  	/**
                  	 * ejbCreate
                  	 */
                  	public void ejbCreate() {
                  		onEjbCreate();
                  	}
                  	/**
                  	 * onMessage
                  	 */
                  	public void onMessage(javax.jms.Message msg) {
                  		System.out.println("doBusiness:  " + msg.toString());
                  		if(demoFacade!=null) {
                  			System.out.println("demoFacade is not null");
                  		} else {
                  			System.out.println("demoFacade is null");
                  		}
                  	}
                  	/**
                  	 * ejbRemove
                  	 */
                  	public void ejbRemove() {
                  	}
                  
                  	protected void onEjbCreate() {
                  		BeanFactory factory = null;
                  		try {						
                  			factory = getBeanFactory();
                  			demoFacade = (DemoFacade)factory.getBean("demoFacade");
                  		} catch(Exception e) {
                  			e.printStackTrace();
                  		}		
                  	}
                  }
                  I'm running debug mode and at hight line code throw NullPointerException, I cannot fix this error. Can you help me!
                  Last edited by chinhtd; Nov 13th, 2007, 05:21 AM.

                  Comment


                  • #10
                    Remove your ejbCreate and ejbRemove method. You are overriding the initialization of the ejbCreate in the superclass and cleanup code of the ejbRemove... Hence your NullPointerException.

                    Next to that you don't need to implement javax.ejb.MessageDrivenBean and javax.jms.MessageListener you already extend a superclass which implements those.

                    The implementation of ejbCreate of AbstractMessageDrivenBean
                    Code:
                    /**
                     * Lifecycle method required by the EJB specification but not the
                     * MessageDrivenBean interface. This implementation loads the BeanFactory.
                     * <p>Don't override it (although it can't be made final): code initialization
                     * in onEjbCreate(), which is called when the BeanFactory is available.
                     * <p>Unfortunately we can't load the BeanFactory in setSessionContext(),
                     * as resource manager access isn't permitted and the BeanFactory may require it.
                     */
                    public void ejbCreate() {
                    	loadBeanFactory();
                    	onEjbCreate();
                    }
                    and the ejbRemove

                    Code:
                    /**
                     * EJB lifecycle method, implemented to invoke onEjbRemote and unload the
                     * BeanFactory afterwards.
                     * <p>Don't override it (although it can't be made final): code your shutdown
                     * in onEjbRemove.
                     * @see #onEjbRemove
                     */
                    public void ejbRemove() {
                    	onEjbRemove();
                    	unloadBeanFactory();
                    }

                    This is your message driven bean after removal of all the unnecessary and unwanted code!

                    Code:
                    public class MDBBean extends AbstractJmsMessageDrivenBean {
                    
                    	private DemoFacade demoFacade = null;
                    	
                    	/**
                    	 * setMessageDrivenContext
                    	 */
                    	public void setMessageDrivenContext(MessageDrivenContext ctx) {	
                    		super.setMessageDrivenContext(ctx);
                    		setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
                    		setBeanFactoryLocatorKey("businessBeanFactory");
                    	}
                    
                    	/**
                    	 * onMessage
                    	 */
                    	public void onMessage(javax.jms.Message msg) {
                    		System.out.println("doBusiness:  " + msg.toString());
                    		if(demoFacade!=null) {
                    			System.out.println("demoFacade is not null");
                    		} else {
                    			System.out.println("demoFacade is null");
                    		}
                    	}
                    
                    	protected void onEjbCreate() {
                            demoFacade = (DemoFacade) getBeanFactory().getBean("demoFacade");
                    	}
                    }
                    Last edited by Marten Deinum; Nov 13th, 2007, 05:56 AM.

                    Comment


                    • #11
                      First, I recommend to remove the env-entry element again. The proposal was an error, that's why I removed it from my post.

                      Second, Try to debug into the "getBeanFactory" invocation. That might provide further clues.

                      BTW: I recommend not to overload ejbCreate() and ejbRemove() in your class.

                      Regards,
                      Andreas

                      Comment


                      • #12
                        Also, you dont have to specify the location in the ejb-jar.xml file; you can code it if you like:

                        Code:
                        	public void setMessageDrivenContext(MessageDrivenContext messageDrivenContext) {
                        		super.setMessageDrivenContext(messageDrivenContext);
                        		setBeanFactoryLocator(ContextSingletonBeanFactoryLocator
                        				.getInstance(this.beanRefContextLocation));
                        		setBeanFactoryLocatorKey(this.beanFactoryName);
                        	}

                        Comment


                        • #13
                          Thank you very much!

                          I remove the env-entry element, remove ejbCreate and ejbRemove method, remove implements javax.ejb.MessageDrivenBean, javax.jms.MessageListener and EJB is running success!

                          Special thanks to Andreas Senft and mdeinum
                          Last edited by chinhtd; Nov 14th, 2007, 12:56 AM.

                          Comment


                          • #14
                            Your welcome, glad we figured it out.

                            Comment


                            • #15
                              Other question

                              I have a question with my EJB Project. I use Spring and iBatis in this project. At present, to use the two library I do as follow: Extract spring.jar and ibatis.jar files then copy them to ejbModule directory. I would rather you give me another way to use these libraries such as: edit class-path variable and it can point to spring.jar and ibatis.jar. Thank a lot.

                              Comment

                              Working...
                              X