Announcement Announcement Module
Collapse
No announcement yet.
Reloading acegi configuration changes with tomcat Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Reloading acegi configuration changes with tomcat

    I am running Acegi 1.0.2 with Tomcat 4.1.34. Due to constraints in our working environment I am not allowed to restart the tomcat server on a key development sever during office hours (8 a.m. Ė 7 p.m.).

    During the course of development I obviously want to make changes to the acegi configuration and have them take effect immediately, without having to wait until the end of the working day to reload tomcat. However, Iím finding that I have to restart the tomcat server for the changes to take effect.

    Iíve included a specific example below. Iíve taken the simple acegi security sample tutorial from the acegi download and deployed it into tomcat on my local machine. The relevant parts of web.xml and te-acegi-security.xml (the referenced acegi config file) are included below, and as you can see they are straight out of the box.

    web.xml:

    Code:
        <filter>
            <filter-name>Acegi Filter Chain Proxy</filter-name>
            <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
            <init-param>
                <param-name>targetClass</param-name>
                <param-value>org.acegisecurity.util.FilterChainProxy</param-value>
            </init-param>
        </filter>
    
        <filter-mapping>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <url-pattern>/*</url-pattern>
        </filter-mapping>
    te-acegi-security.xml:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    
    <beans>
    	<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
    		<property name="filterInvocationDefinitionSource">
    			<value>
    				CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    				PATTERN_TYPE_APACHE_ANT
    				/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
    			</value>
    		</property>
    	</bean>
    
    	<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
    
    	etc...
    </beans>
    As an example, I renamed the httpSessionContextIntegrationFilter bean to anotherHttpSessionContextIntegrationFilter in te-acegi-security.xml. I then used a bespoke jsp called springconfig.jsp (which is NOT protected by acegi) to reload the Spring web application context.

    springconfig.jsp:

    Code:
    <html>
    <head>
    <%@ page import="org.springframework.web.context.WebApplicationContext,
    	org.springframework.web.context.support.XmlWebApplicationContext,
    	org.springframework.web.context.support.WebApplicationContextUtils,
    	java.util.*" %>
    </head>
    <body>
    <%
    
    WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(application);
    
    if (ctx != null){
    %>
    <p>I got spring context</p>
    <%
    	if ((ctx instanceof XmlWebApplicationContext) && ("true".equals(request.getParameter("reload")))) {
    		((XmlWebApplicationContext) ctx).refresh();
    		out.println("<p>reloaded</p>");
    	}
    	
    	out.println("<ul>");
    	String[] allbeans = ctx.getBeanDefinitionNames();
    	for( int i = 0; i < allbeans.length; i++ ){
    		out.println("<li>" + allbeans[i] + "</li>" );
    	}
    	out.println("</ul>");
    }
    else {
    %>
    <p>no spring</p>
    <%
    } 
    %>
    <p><a href="?reload=true" >reload spring config</a></p>
    </body>
    </html>
    Output of springconfig.jsp, following a reload:

    I got spring context

    reloaded

    * filterChainProxy
    * anotherHttpSessionContextIntegrationFilter
    * logoutFilter
    * authenticationProcessingFilter
    * securityContextHolderAwareRequestFilter
    * anonymousProcessingFilter
    * exceptionTranslationFilter
    * filterInvocationInterceptor
    * authenticationManager
    * jiveAuthenticationProvider
    * jiveAuthorisationServiceLive
    * te-loggerListener

    Following the reload of the spring context, I visit the home page of the application and get the following exception:

    Code:
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'httpSessionContextIntegrationFilter' is defined
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:360)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:692)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:219)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:149)
    	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:541)
    	at org.acegisecurity.util.FilterChainProxy.obtainAllDefinedFilters(FilterChainProxy.java:220)
    	at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:135)
    	at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:209)
    	at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:595)
    	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:432)
    	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:954)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:138)
    	at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:595)
    	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:432)
    	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:954)
    	at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2459)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:132)
    	at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:595)
    	at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:118)
    	at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:593)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:116)
    	at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:593)
    	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:432)
    	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:954)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:126)
    	at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:595)
    	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:432)
    	at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:954)
    	at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:152)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
    	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
    	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
    	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
    	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
    	at java.lang.Thread.run(Thread.java:534)
    It seems that FilterToBeanProxy is holding on to the old definition of the bean (httpSessionContextIntegrationFilter) which of course no longer exists, hence the NoSuchBeanDefinitionException exception. This may seem a trivial point, but it also holds for any other changes I make to acegi beans, not just bean name changes e.g. if I update the configuration of protected resources; changes will not be taken account of until tomcat is reloaded. Does anyone know a way around this?

  • #2
    A slightly different solution, can't you just run a copy of Tomcat locally?

    Comment


    • #3
      Tomcat 4.1 Is this still supported? OK, anyway...

      Can't you restart your webapp only, not the whole server?
      The tomcat-Manager webapp should help you there.

      Tip:

      I always use as much local as I can. At the moment I have a project which needs tomcat and a database-, ldap-, archive- and smtp-server. I run all in my vmware image without any probs.

      Comment


      • #4
        Originally posted by spgmx View Post
        Can't you restart your webapp only, not the whole server? The tomcat-Manager webapp should help you there.
        Yes indeed, another good point!

        Originally posted by spgmx View Post
        I always use as much local as I can. At the moment I have a project which needs tomcat and a database-, ldap-, archive- and smtp-server. I run all in my vmware image without any probs.
        I'm with you there. When I'm developing I need to be able to tweak, re-configure, restart, break, fix, etc...... I can't imagine trying to develop against a 'hands off' style box, it's just too constraining.

        Comment

        Working...
        X