Page 1 of 2 12 LastLast
Results 1 to 10 of 18

Thread: Using Bean Factory on 2nd attempt causes errors

  1. #1
    Join Date
    Jan 2006
    Location
    Huddersfield/Coventry
    Posts
    28

    Default Using Bean Factory on 2nd attempt causes errors

    I have updated my project, which uses Spring to inject the managers and DAO, to get EJB3 working with the Springframework. Since introducing the EJBs i have been having some problems. My problems occur when calling the beanfactory more then once.

    org.springframework.beans.factory.BeanDefinitionSt oreException: Unexpected exception parsing XML document from class path resource [spring-config.xml]; nested exception is java.lang.IllegalArgumentException: Class [org.springframework.beans.factory.xml.SimpleProper tyNamespaceHandler] does not implement the NamespaceHandler interface

    When i called the bean factory initially to get the EJB (EJB3). There are no problems, everything works fine. But upon using the Bean factory again in order to get the manager beans used by the EJB layer the above error is thrown.

    The EJB is in a separate jar file, the web content is in a war file and the core of the code sits inside a 3rd jar file. All of which is within a EAR file.

    The bean factory code is

    beanFactory = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml"}, false);

    Thanks in advance

  2. #2
    Join Date
    Dec 2006
    Location
    Normal, Illinois
    Posts
    277

    Default

    Looks like you are loading your application context multiple times (hard to tell though from the limited example). You should try to bootstrap the application context using a ServletContextListener (or some other mechanism) so that the application context is only loaded once and held onto. Then you can just request your bean from the application context that is already loaded.
    Caleb Washburn

  3. #3
    Join Date
    Jan 2006
    Location
    Huddersfield/Coventry
    Posts
    28

    Default

    Hi Caleb,
    The code

    beanFactory = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml"}, false);

    is being used twice first time to get the service object with the EJB and then again inside the EJB to access the Manager bean. This is where it fails on the 2nd attempt. So i do believe that the ApplicationContext is being loaded twice

    With regards to using the using the ServletContextListener, could you give an example of how i would possibly use this.

    Thanks

  4. #4
    Join Date
    Dec 2006
    Location
    Normal, Illinois
    Posts
    277

    Default

    To bootstrap at the Web tier.

    Add the following to the web.xml

    Code:
    <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-config.xml</param-value>
    </context-param>
    
    <listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    Then to get access to the WebApplicationContext use the following.

    Code:
    ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext())
    This will retrieve the bootstrapped application context from an Application scoped variable.

    To bootstrap the EJB container you can have your EJB Bean Class extend from Springs AbstractStatelessSessionBean. Then add an EJB Environment Variable with the name of "ejb/BeanFactoryPath" and value of "location of your application context file".

    Code:
    <env-entry>
      <env-entry-name>ejb/BeanFactoryPath</env-entry-name>
      <env-entry-type>java.lang.String</env-entry-type>
      <env-entry-value>classpath:applicationContext.xml</env-entry-value>
    </env-entry>
    Then in your EJB you can use the getBeanFactory() method to get the bootstrapped application context from the EJB container.

    Note: now that I re-read your problem this might be because your classpath is not the same for both the Web container and EJB container. Need to verify that you have all the jar files added to Java jar dependecies of both the Web and EJB components.
    Caleb Washburn

  5. #5
    Join Date
    Jan 2006
    Location
    Huddersfield/Coventry
    Posts
    28

    Default

    Thanks for the example.

    I am currently using EJB3 so dont have an ejb-jar fille. How would i specify the env entry for the bean factory in my EJB bean class

    <env-entry>
    <env-entry-name>ejb/BeanFactoryPath</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>classpath:applicationContext.xml</env-entry-value>
    </env-entry>

  6. #6
    Join Date
    Dec 2006
    Location
    Normal, Illinois
    Posts
    277

    Default

    Looks like in order to have env-entry values you still need an ejb-jar.xml file. Here's a doc that talks about Spring and EJB 3.0

    http://www.oracle.com/technology/tec...ring.html#slsb
    Caleb Washburn

  7. #7
    Join Date
    Jan 2006
    Location
    Huddersfield/Coventry
    Posts
    28

    Default

    Thanks for that example.

    There is a new error now

    java.lang.NullPointerException
    at org.springframework.ejb.support.AbstractEnterprise Bean.getBeanFactory(AbstractEnterpriseBean.java:15 4)


    Unfortuantly it doesnt give to much info about what is missing

    My code is as follows

    In my myapp.jar(which resides in a ear file)

    ejb-jar.xml

    <session>
    <ejb-name>ExpensesEJBBean</ejb-name>
    <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>


    ExpensesEJBBean class file

    @Stateless(name = "ExpensesEJBBean", mappedName = "ExpensesEJBBean")
    public class ExpensesEJBBean extends AbstractStatelessSessionBean implements ExpensesEJBLocal, ExpensesEJB {

    protected void onEjbCreate() throws CreateException {
    System.out.println("READY");
    expensesManager = (ExpensesManager) getBeanFactory().getBean("expensesManager");
    }

    public List getAllRecords(String month) throws EJBException {
    System.out.println("getAllRecords");
    Object o = super.getBeanFactory().getBean("expensesManager");
    return expensesManager.getAllRecords();
    }
    }


    applicationContext.xml

    <bean id="expensesService" class="uk.co.aztekSolutions.expensesApp.services.c ore.expenses.ExpensesServiceImpl">
    <property name="expensesEJB" ref="expensesEJB"/>
    </bean>

    <bean id="expensesEJB" class="org.springframework.jndi.JndiObjectFactoryB ean">
    <property name="jndiEnvironment">
    <props>
    <prop key="java.naming.factory.initial">org.jnp.interfac es.NamingContextFactory</prop>
    <prop key="java.naming.factory.url.pkgs">org.jboss.namin g:org.jnp.interfaces</prop>
    <prop key="java.naming.provider.url">jnp://localhost:1099</prop>
    </props>
    </property>
    <property name="jndiName" value="AztekApplication/ExpensesEJBBean/local"/>
    <property name="resourceRef">
    <value>true</value>
    </property>
    </bean>

    <bean id="expensesManager" class="uk.co.aztekSolutions.server.domain.expenses .ExpensesManagerImpl">
    </bean>

    <bean id="bankManager" class="uk.co.aztekSolutions.server.domain.bank.Ban kManagerImpl">
    </bean>


    The code appears to be failing on

    Object o = super.getBeanFactory().getBean("expensesManager");

  8. #8
    Join Date
    Dec 2006
    Location
    Normal, Illinois
    Posts
    277

    Default

    Looks like the result of getBeanFactory() is null. This usually happens when the file you specify cannot be found.

    Where do you have your applicationContext.xml file placed? If you have it in the root of the classpath. Try...

    Code:
             <env-entry-value>classpath:applicationContext.xml</env-entry-value>
    Try turning on DEBUG level messages (with Log4j or your logging implementation) to have more insight into what is going on.
    Caleb Washburn

  9. #9
    Join Date
    Jan 2006
    Location
    Huddersfield/Coventry
    Posts
    28

    Unhappy

    The applicationContext.xml recides in the root of the ejb jar file. But the same nullpointer exception is still occuring. I have switched on the logging but nothing useful is being displayed. Not sure if it cant see the env entry in the ejb-jar.xml file.

    Is it possible to enter this value programmatically.

    For example i have seen the method setBeanFactoryLocatorKey(). I have tried entering "ejb/BeanFactoryPath" and /applicationContext.xml with no luck

    would appreciate any further assitance you could provde. woah 2.06am time for bed i think. Given enough time to this problem today.

  10. #10
    Join Date
    Dec 2006
    Location
    Normal, Illinois
    Posts
    277

    Default

    In the constructor of your bean you can do the following.

    Code:
    setBeanFactoryLocator(SingletonBeanFactoryLocator.getInstance("classpath:applicationContext.xml"));
    This will override the default behavior of looking for the applicationContext file locations in the ejb environment variable entry.
    Caleb Washburn

Posting Permissions

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