Search code examples
struts2struts

InstantiationException when calling action using struts1-plugin


We migrating our old Struts 1 Application to Struts 2 using the struts1-plugin to wrap our actions.
This worked great with some actions but others throw the error shown below:

java.lang.InstantiationException 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
java.lang.Class.newInstance(Class.java:374)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:158)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:189)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:178)
com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.resolveModel(ScopedModelDrivenInterceptor.java:106)
com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:136)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
de.dak.intranet.webtier.extranet.StartPageFilter.doFilter(StartPageFilter.java:74)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
de.dak.intranet.webtier.auth.LoginFilter.doFilter(LoginFilter.java:288)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)

The configuration for this action very straightforward:

<package name="extranet" extends="struts1-default" namespace="/extranet">
  <action name="acceptConditions" class="org.apache.struts2.s1.Struts1Action>
    <param name="className">de.intranet.webtier.extranet.AcceptConditionsAction</param>
    <interceptor-ref name="struts1Stack"/>
    <result name="success">/servlet/index.jsp</result>
  </action>
</package>

I tried removing the interceptors in the action but that did not change anything. The action class looks like this (actual logic was omitted):

public class AcceptConditionsAction extends Action {
  public ActionForward execute(ActionMapping mapping, 
                               ActionForm form, 
                               HttpServletRequest request, 
                               HttpServletResponse response) 
        throws Exception {
    return mapping.findForward("success");
  }
}

The link in our jsp template is build correctly with the s:action-tag and another action on the same site works perfectly when the link is clicked. This action however generates the stacktrace shown above and I cannot figure out where it is coming from or how to fix it. The breakpoint inside the action is never reached therefore the error has to occur while instantiating the action itself.

I hope somebody can help me figure out what is happening.

EDIT: Working action for clarification:

<package name="extranet" extends="struts1-default" namespace="/extranet">
  <interceptors>
    <interceptor name="pwdForm" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor>
      <param name="className">de.intranet.webtier.extranet.PasswordForm</param>
      <param name="name">pwdForm</param>
    </interceptor>
  </interceptors>
  <action name="editPassword" class="org.apache.struts2.s1.Struts1Action">
    <param name="className">de.intranet.webtier.extranet.EditPasswordAction</param>
    <interceptor-ref name="pwdForm"/>
    <interceptor-ref name="struts1Stack"/>
    <result name="changePassword">/extranet/changePassword.jsp</result>
  </action>
</package>

Java implementation looks like the AcceptConditionsAction. Only the execute-method was overwritten and no constructor defined.


Solution

  • Aleksandr pointed me to the answer: The interceptor stack provided by the struts1-plugin (called struts1Stack) creates several interceptors that require a Form (i.e. scopedModelDriven, modelDriven and some others). If you don't use the entire stack and only add the interceptors needed by the action, it is not necessary anymore to define a FormBean.