Results 1 to 9 of 9

Thread: Web-application context how to setup

  1. #1
    Join Date
    Jan 2012
    Posts
    8

    Default Web-application context how to setup

    Hi All, I had two questions,
    1) In Spring MVC application, what is the purpose of having ContextLoaderListener?

    2) Below are the my entries in web.xml,
    All MVC beans are defined in servlet-context.xml
    All database and annotation based transaction management is defined in applicationContext.xml and I'm using container managed transaction in JBoss

    The trasaction manager works fine if I keep the applicationContext.xml as higlighted in below as <init-param> to DispatcherServlet. But I thought we should only pass the Spring MVC context info to DispatcherServlet and if I remove the applicationContext.xml the transaction manager stops working? I'm confused what is best way of managing the context files?

    Web.xml
    Code:
    <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>    
                /WEB-INF/config/applicationContext.xml
                /WEB-INF/config/spring-mail.xml
            </param-value>
        </context-param>
        <context-param>
            <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
            <param-value>messages</param-value>
        </context-param>
    
    
    
    <servlet>
            <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>
                    /WEB-INF/config/servlet-context.xml
                   /WEB-INF/config/applicationContext.xml
                </param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    applicationContext.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"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                   http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
                   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    
        <!-- registers all of Spring's standard post-processors for annotation-based configuration -->
        <context:annotation-config />
    
        <jee:jndi-lookup id="dataSource" jndi-name="java:OracleDS"/>
    
    
        <tx:annotation-driven/>
        <tx:jta-transaction-manager/>
    
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation"
                      value="classpath:com/common/model/config/sqlmapconfig.xml"/>
        </bean>
    
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg ref="sqlSessionFactory"/>
        </bean>
    
    </beans>
    servlet-context.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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <context:component-scan base-package="com.xxxx"/>
    
    <!-- Configures the @Controller programming model -->
    <mvc:annotation-driven/>
    
    <!-- Configures Handler Interceptors -->
    <mvc:interceptors>
        <!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
        <!--Register Request/Response Interceptor-->
        <bean class="com.xxx.common.auditor.RequestInterceptor"/>
       <!-- <bean class="com.xxx.common.interceptor.UserAuthenticationInterceptor"/>-->
    </mvc:interceptors>
    
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"/>
    
    <!-- Application Message Bundle -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="/WEB-INF/messages/messages"/>
        <property name="cacheSeconds" value="0"/>
    </bean>
    Thanks for you help!
    Last edited by Taran.Singh; Feb 10th, 2012 at 06:31 AM.

  2. #2
    Join Date
    Jan 2012
    Posts
    8

    Default

    Can someone respond please or is this to do with the length and complexity of the question?
    sorry it's a long one, but I only wanted to make it clear
    looking for replies....

  3. #3

    Default

    The ContextLoaderListener helps manage the lifecycle of the root-level Spring context in the servlet container (e.g. the application server). You can register any root-level Spring context (any Spring configuration that you want to apply to all servlets running in the same server instance) using the <context-param> element.

    You can, of course, run multiple DispatcherServlets in the same server instance (each mapped to their own top-level URL). Any configuration that is specific to an application can be passed in the <init-param> to the DispatcherServlet.

    So, to achieve the kind of separation between container-level and application-level configuration, you could change your web.xml like this:

    Code:
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>    
        /WEB-INF/config/servlet-context.xml
      </param-value>
    </context-param>
    
    <servlet>
      <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
          /WEB-INF/config/applicationContext.xml
        </param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
    </servlet>

  4. #4
    Join Date
    Jan 2012
    Posts
    8

    Default

    Hi @scottyfred,
    Thanks for your reply and my apologies for taking so long to come back on this, as I had been busy with other stuff. I did try waht you suggested of having servlet-context.xml being passed to ContextLoaderListener and applicationContext.xml to DispatcherServlet, but it didn't work. Basically it my web-app couldn't get back the data base connection even. All data base beans are defined in applicationContext.xml as per the code above. I was wondering isn't it vice versa what you said, I mean shouldn''t we be passing servlet-context.xml to Dispatcher servlet and applicationContext.xml to ContextLoaderListener. But doing that, the transaction manager doesn't work as explained above unless I pass the applicationContext.xml to DispatcherServlet.

    cheers

  5. #5

    Default

    Taran,

    Apologies, I didn't look at your example context.xml files very closely to see what was in each of them. Given what you have in each file, you are right in that applicationContext.xml should be passed to the contextLoaderListener, and servlet-context.xml should be passed to DispatcherServlet.

    When splitting the application contexts like this, the two contexts have a parent-child relationship. The context passed to the contextLoaderListener becomes the parent of the DispatcherServlet's context. So, all beans declared in applicationContext.xml should also be visible to the DispatcherServlet's context.

    You say that the tx manager works in one case but doesn't work in another case. What exactly happens when the tx manager doesn't work? Are you getting an error when the app context tries to load, or is the app just not behaving as you expect it to?

  6. #6
    Join Date
    Jan 2012
    Posts
    8

    Default

    Quote Originally Posted by scottyfred View Post
    Taran,

    Thanks for your prompt reply !

    When splitting the application contexts like this, the two contexts have a parent-child relationship. The context passed to the contextLoaderListener becomes the parent of the DispatcherServlet's context. So, all beans declared in applicationContext.xml should also be visible to the DispatcherServlet's context.
    That must contain the answer, but I'm not sure if I need to do some extra configuration for this parent-child (applcation-context --> web-application-context). I'm under the impression that this happens by default in Spring MVC. Is that correct?

    You say that the tx manager works in one case but doesn't work in another case. What exactly happens when the tx manager doesn't work? Are you getting an error when the app context tries to load, or is the app just not behaving as you expect it to?
    Yes if I remove the application-context file entry from Dispatcher servlet as highlighted in red below, then the transaction don't get started.

    Please note, I'm using annotation based transaction management defined in applicationContext.xml and I'm using container managed transaction manager from JBoss (JTA)

    Web.xml
    Code:
     <servlet>
            <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>
                    /WEB-INF/config/servlet-context.xml /WEB-INF/config/applicationContext.xml
                </param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    Transaction Manager config
    Code:
     
    <jee:jndi-lookup id="dataSource" jndi-name="java:OracleDS"/>
    
    Annotation snippet
    
    Code:
    @Transactional(
            propagation = Propagation.REQUIRED,
            isolation = Isolation.DEFAULT,
            readOnly = false)
    public interface LoginService {
    
        public LoginVO getUserDetails(String userID);
    }
    <tx:annotation-driven/> <tx:jta-transaction-manager/>
    Logs show that the JtaTransactionManager started, but when the transactional methods are called, no transaction gets bounded/started. I verified via setting logger level to DEBUG
    Logs
    HTML Code:
    12:37:35,921 INFO  [STDOUT] INFO : org.springframework.transaction.jta.JtaTransactionManager - Using JTA TransactionManager: com.arjuna.ats.jbossatx.jta.TransactionManagerDelegate@b4870
    12:37:35,922 INFO  [STDOUT] DEBUG: org.springframework.transaction.jta.JtaTransactionManager - JTA TransactionSynchronizationRegistry found at default JNDI location [java:comp/TransactionSynchronizationRegistry]
    12:37:35,922 INFO  [STDOUT] INFO : org.springframework.transaction.jta.JtaTransactionManager - Using JTA TransactionSynchronizationRegistry: com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple@c0bb57
    [20

  7. #7
    Join Date
    Jan 2012
    Posts
    8

    Default

    Does anyone have an idea? I haven't found an answer yet, even the Spring 3.0 book says that it makes sense to put all the web layer information to Dispatcher-servlet.xml and rest of configuration XMLs should be passed to ContextLoaderListerner.
    If I remove the application-context file entry from Dispatcher servlet as highlighted in red below, then the container managed JTA transaction don't start when the service layer annotated with transaction information are called. Am I missing something or is appropriate to pass the transaction information which is in application context to Dispatcher servlet.

  8. #8
    Join Date
    Jun 2012
    Posts
    2

    Default

    I too am having the same issue and looking for some direction.

    Anyone have any resources they recommend?

    Eric

  9. #9
    Join Date
    Jun 2012
    Posts
    2

    Default

    I think I have figured out an answer.

    In the servlet-context.xml specify the following
    Code:
        <context:component-scan base-package="com.xxxx" use-default-filters="false">
            <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
        </context:component-scan>
    In the root-context.xml specify the following
    Code:
        <context:component-scan base-package="com.xxxx" use-default-filters="false">
            <context:include-filter expression="org.springframework.stereotype.Component" type="annotation" />
            <context:include-filter expression="org.springframework.stereotype.Service" type="annotation" />
        </context:component-scan>
    This allowed the @Transaction annotation to work for me.

    Eric

Posting Permissions

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