eliotc
Dec 6th, 2006, 12:11 AM
Until today, I have been using the ControllerClassNameHandler without a problem. However, I just configured spring for transactions, and added annotation based transactions to all my form controllers. Now the name handler has stopped working properly (except when exactly one controller but not more than 1 has transaction annotations.)
My setup is spring 2.0 final. I added the library spring-aspects.jar to support annotations Below I have put the error trace, the spring-servlet.xml contents and relevant parts of a form controller.
Does anyone know what is causing this problem, the error message makes no sense to me. Is there a fix?
Any help would be much appreciated! thanks in advance:) , Eliot
Here is my error trace in tomcat 5.5:
org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'org.springframework.web.servlet.mvc.support.Contr ollerClassNameHandlerMapping' defined in ServletContext resource [/WEB-INF/crowd-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot map handler [operatorWithQualcommAccountSupportsForm] to URL path [/.proxy6*]: There's already handler [com.qualcomm.crowd.controller.OperatorWithAddressF ormController@14aa6c3] mapped.
Caused by:
java.lang.IllegalStateException: Cannot map handler [operatorWithQualcommAccountSupportsForm] to URL path [/.proxy6*]: There's already handler [com.qualcomm.crowd.controller.OperatorWithAddressF ormController@14aa6c3] mapped.
at org.springframework.web.servlet.handler.AbstractUr lHandlerMapping.registerHandler(AbstractUrlHandler Mapping.java:214)
at org.springframework.web.servlet.mvc.support.Contro llerClassNameHandlerMapping.registerController(Con trollerClassNameHandlerMapping.java:128)
at ....
spring-servlet.xml (one of three spring files in the webapp:
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- This is needed for upload image forms -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsM ultipartResolver"/>
<!-- The various Controllers -->
<bean id="operatorWithAddressForm"
class="com.qualcomm.crowd.controller.OperatorWithAddressF ormController">
<property name="operatorManager" ref="operatorManager" />
<property name="formView">
<value>operatorGeneralInfo/addressEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/addressDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorWithAliasesForm"
class="com.qualcomm.crowd.controller.OperatorWithAliasesF ormController">
<property name="operatorManager" ref="operatorManager" />
<property name="formView">
<value>operatorGeneralInfo/aliasEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/aliasDisplay</value>
</property>
<!-- property name="validator" ref="operatorValidator"/-->
</bean>
<bean id="operatorWithQualcommAccountSupportsForm" class="com.qualcomm.crowd.controller.OperatorWithQualcomm AccountSupportsFormController">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/accountManagerEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/accountManagerDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorWithTypeForm" class="com.qualcomm.crowd.controller.OperatorWithTypeForm Controller">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/typeEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/typeDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorPrivateCommentForm" class="com.qualcomm.crowd.controller.OperatorPrivateComme ntFormController">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/commentsEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/commentsDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorPublicCommentForm" class="com.qualcomm.crowd.controller.OperatorPublicCommen tFormController">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/commentsEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/commentsDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<!-- The various object validators, used in form submissions -->
<bean id="operatorValidator" class="com.qualcomm.crowd.validator.OperatorValidator"/>
<!-- Map Exception types to pages -->
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMapp ingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.RuntimeException">runtimeException</prop>
<prop key="com.qualcomm.crowd.error.ImageFileException">imageFileException</prop>
<prop key="com.qualcomm.crowd.error.InvalidSearchCriteriaExce ption">invalidSearchCriteriaException</prop>
<prop key="com.qualcomm.crowd.error.NoSuchEmployeeException">operatorGeneralInfo/noSuchEmployeeException</prop>
<prop key="com.qualcomm.crowd.error.NoSuchEntityException">noSuchEntityException</prop>
<prop key="com.qualcomm.crowd.error.NoSuchOperatorException">operatorGeneralInfo/noSuchOperatorException</prop>
</props>
</property>
</bean>
<!-- E.g. we map the url yadayada/* to YadaYadaController -->
<!-- Note that in conjunction with default method mapping, we map url yadayada/eatIt.run to method YadaYadaController.eatIt(...) -->
<bean
class="org.springframework.web.servlet.mvc.support.Contro llerClassNameHandlerMapping" />
<!-- maps view name operatorGeneralInfo/yada to crowd2/operatorGeneralInfo/yada.jsp -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResou rceViewResolver">
<property name="prefix">
<value>/crowd2/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
Relevant part of the controller:
package com.qualcomm.crowd.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.transaction.annotation.Transac tional;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormCont roller;
import com.qualcomm.crowd.entity.Operator;
import com.qualcomm.crowd.error.NoSuchOperatorException;
import com.qualcomm.crowd.service.OperatorManager;
/**
* This form only supports operator address updates, i.e. editing operator
* addresses that already exist. Creation is performed in another controller
*/
@Transactional(readOnly = true)
public class OperatorWithAddressFormController extends SimpleFormController {
// -------------------------- methods
/**
* The constructor binds the form to an Operator object
*/
public OperatorWithAddressFormController() {
setCommandName("operator");
setCommandClass(Operator.class);
// need a session to hold the formBackingObject
setSessionForm(true);
// initialize the form from the formBackingObject
setBindOnNewForm(true);
}
/**
* This form supports operator address updates, and so operator object
* properties must be populate with data from database
*/
protected Object formBackingObject(HttpServletRequest request) throws Exception {
.... }
/** Method updates an existing Owner. */
@Transactional(readOnly = false, rollbackFor = NoSuchOperatorException.class)
protected ModelAndView onSubmit(Object command) throws ServletException, NoSuchOperatorException {
Operator operator = (Operator) command;
// delegate the update to the Business layer
this.operatorManager.updateOperatorWithAddress(ope rator);
return new ModelAndView(getSuccessView(), "operator", operator);
}
}
My setup is spring 2.0 final. I added the library spring-aspects.jar to support annotations Below I have put the error trace, the spring-servlet.xml contents and relevant parts of a form controller.
Does anyone know what is causing this problem, the error message makes no sense to me. Is there a fix?
Any help would be much appreciated! thanks in advance:) , Eliot
Here is my error trace in tomcat 5.5:
org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'org.springframework.web.servlet.mvc.support.Contr ollerClassNameHandlerMapping' defined in ServletContext resource [/WEB-INF/crowd-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot map handler [operatorWithQualcommAccountSupportsForm] to URL path [/.proxy6*]: There's already handler [com.qualcomm.crowd.controller.OperatorWithAddressF ormController@14aa6c3] mapped.
Caused by:
java.lang.IllegalStateException: Cannot map handler [operatorWithQualcommAccountSupportsForm] to URL path [/.proxy6*]: There's already handler [com.qualcomm.crowd.controller.OperatorWithAddressF ormController@14aa6c3] mapped.
at org.springframework.web.servlet.handler.AbstractUr lHandlerMapping.registerHandler(AbstractUrlHandler Mapping.java:214)
at org.springframework.web.servlet.mvc.support.Contro llerClassNameHandlerMapping.registerController(Con trollerClassNameHandlerMapping.java:128)
at ....
spring-servlet.xml (one of three spring files in the webapp:
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!-- This is needed for upload image forms -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsM ultipartResolver"/>
<!-- The various Controllers -->
<bean id="operatorWithAddressForm"
class="com.qualcomm.crowd.controller.OperatorWithAddressF ormController">
<property name="operatorManager" ref="operatorManager" />
<property name="formView">
<value>operatorGeneralInfo/addressEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/addressDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorWithAliasesForm"
class="com.qualcomm.crowd.controller.OperatorWithAliasesF ormController">
<property name="operatorManager" ref="operatorManager" />
<property name="formView">
<value>operatorGeneralInfo/aliasEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/aliasDisplay</value>
</property>
<!-- property name="validator" ref="operatorValidator"/-->
</bean>
<bean id="operatorWithQualcommAccountSupportsForm" class="com.qualcomm.crowd.controller.OperatorWithQualcomm AccountSupportsFormController">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/accountManagerEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/accountManagerDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorWithTypeForm" class="com.qualcomm.crowd.controller.OperatorWithTypeForm Controller">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/typeEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/typeDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorPrivateCommentForm" class="com.qualcomm.crowd.controller.OperatorPrivateComme ntFormController">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/commentsEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/commentsDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<bean id="operatorPublicCommentForm" class="com.qualcomm.crowd.controller.OperatorPublicCommen tFormController">
<property name="operatorManager" ref="operatorManager"/>
<property name="formView">
<value>operatorGeneralInfo/commentsEdit</value>
</property>
<property name="successView">
<value>operatorGeneralInfo/commentsDisplay</value>
</property>
<property name="validator" ref="operatorValidator"/>
</bean>
<!-- The various object validators, used in form submissions -->
<bean id="operatorValidator" class="com.qualcomm.crowd.validator.OperatorValidator"/>
<!-- Map Exception types to pages -->
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMapp ingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.RuntimeException">runtimeException</prop>
<prop key="com.qualcomm.crowd.error.ImageFileException">imageFileException</prop>
<prop key="com.qualcomm.crowd.error.InvalidSearchCriteriaExce ption">invalidSearchCriteriaException</prop>
<prop key="com.qualcomm.crowd.error.NoSuchEmployeeException">operatorGeneralInfo/noSuchEmployeeException</prop>
<prop key="com.qualcomm.crowd.error.NoSuchEntityException">noSuchEntityException</prop>
<prop key="com.qualcomm.crowd.error.NoSuchOperatorException">operatorGeneralInfo/noSuchOperatorException</prop>
</props>
</property>
</bean>
<!-- E.g. we map the url yadayada/* to YadaYadaController -->
<!-- Note that in conjunction with default method mapping, we map url yadayada/eatIt.run to method YadaYadaController.eatIt(...) -->
<bean
class="org.springframework.web.servlet.mvc.support.Contro llerClassNameHandlerMapping" />
<!-- maps view name operatorGeneralInfo/yada to crowd2/operatorGeneralInfo/yada.jsp -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResou rceViewResolver">
<property name="prefix">
<value>/crowd2/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
Relevant part of the controller:
package com.qualcomm.crowd.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.transaction.annotation.Transac tional;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormCont roller;
import com.qualcomm.crowd.entity.Operator;
import com.qualcomm.crowd.error.NoSuchOperatorException;
import com.qualcomm.crowd.service.OperatorManager;
/**
* This form only supports operator address updates, i.e. editing operator
* addresses that already exist. Creation is performed in another controller
*/
@Transactional(readOnly = true)
public class OperatorWithAddressFormController extends SimpleFormController {
// -------------------------- methods
/**
* The constructor binds the form to an Operator object
*/
public OperatorWithAddressFormController() {
setCommandName("operator");
setCommandClass(Operator.class);
// need a session to hold the formBackingObject
setSessionForm(true);
// initialize the form from the formBackingObject
setBindOnNewForm(true);
}
/**
* This form supports operator address updates, and so operator object
* properties must be populate with data from database
*/
protected Object formBackingObject(HttpServletRequest request) throws Exception {
.... }
/** Method updates an existing Owner. */
@Transactional(readOnly = false, rollbackFor = NoSuchOperatorException.class)
protected ModelAndView onSubmit(Object command) throws ServletException, NoSuchOperatorException {
Operator operator = (Operator) command;
// delegate the update to the Business layer
this.operatorManager.updateOperatorWithAddress(ope rator);
return new ModelAndView(getSuccessView(), "operator", operator);
}
}