Search code examples
javajspstruts2jstlognl

Struts2 properties not populated in JSP


I have a Struts 2.5.10.1 application that isn't populating any EL or OGNL variables. I've verified with a debugger that the variables are being set on the action class. The error is "The class 'com.sun.proxy.$Proxy404' does not have the property 'jobRunning'. File: javax/el/BeanELResolver.java Line number: 686". This is the Struts.xml:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    <constant name="struts.custom.i18n.resources" value="global"/>
    <constant name="struts.enable.SlashesInActionNames" value="true"/>
    <constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
    <constant name="struts.patternMatcher" value="namedVariable"/>
    <constant name="struts.devMode" value="true"/>
    <constant name="struts.multipart.maxSize" value="16777216"/>
    <constant name="struts.convention.default.parent.package" value="parent-package"/>
    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
    <constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory"/>
    <constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>


    <package name="parent-package" extends="security-manager,struts2-support,json-default" namespace="/">

    </package>
</struts>

The action has these annotation based interceptors:

@InterceptorRefs({
        @InterceptorRef(value = "exception"),
        @InterceptorRef(value = "alias"),
        @InterceptorRef(value = "servletConfig"),
        @InterceptorRef(value = "i18n"),
        @InterceptorRef(value = "userInfoObjectInterceptor"),
        @InterceptorRef(value = "securityCheckInterceptor", params = {"mode", "before"}),
        @InterceptorRef(value = "prepare"),
        @InterceptorRef(value = "debugging"),
        @InterceptorRef(value = "fileUpload"),
        @InterceptorRef(value = "checkbox"),
        @InterceptorRef(value = "multiselect"),

        @InterceptorRef(value = "staticParams"),
        @InterceptorRef(value = "actionMappingParams"),
        @InterceptorRef(value = "params", params = {"excludeParams", "dojo\\..*,^struts\\..*", "ordered", "true"}),
        @InterceptorRef(value = "securityCheckInterceptor", params = {"mode", "after"}),
        @InterceptorRef(value = "validation", params = {"validateAnnotatedMethodOnly", "true"}),
        @InterceptorRef(value = "workflow")
})

The jsp header:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="app" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<script type="text/javascript" src="${pageContext.request.contextPath}/jquery/dateFormat.js"></script>

<%--@elvariable id="action" type="njob.actions.WelcomeAction"--%>

<app:wrapper pageTitle="Welcome Page">
<jsp:body>

The failure point:

<c:out value="${action.currentEnvironment}"/> <%-- also fails with <s:property value="%{currentEnvironment}--%>

The action class has the correct getter and setters:

  public String getCurrentEnvironment() {
        return currentEnvironment;
    }

    public void setCurrentEnvironment(String currentEnvironment) {
        this.currentEnvironment = currentEnvironment;
    }

Solution

  • Ok, I found how to force the creation of CGLIB based proxys for actions. I added this line to the applicationContext.xml:

    <aop:aspectj-autoproxy proxy-target-class="true"/>
    

    I still don't know why Struts was using the wrong proxy class. My app isn't even using the Spring AOP library. I think it's something to do with my company's custom struts plugin.