从Struts2操作标记调用操作时的java.lang.StackOverflowError

时间:2011-05-31 01:18:13

标签: java hibernate plugins struts2 stack-overflow

我有dccr.jsp文件,它通过标记调用一个动作:

<s:action name="query-privilege" executeResult="false" var="privilege">
            <s:param name="moduleid">9</s:param>
            <s:param name="privilege">v</s:param>
            <s:param name="pagename">dccr</s:param>
</s:action>

我使用此操作在用户之间查询模块权限,如下所示:

<s:if test="%{#privilege.allowable == false}">
       //do something
</s:if>

这是我的行动支持班:

    private String pagename;
    private String moduleid;
    private boolean allowable;
    private String privilege;
    private final UsertypeModuleDAO umodDao = (UsertypeModuleDAO) ServletActionContext.getServletContext().getAttribute("usermoduleDAO");

    //loggers, session properties etc.

@Action(value = "/query-privilege", results = {
        @Result(name = "SUCCESSdccr", location = "/dccr.jsp"),
        @Result(name = "ERROR", location = "../error/messages.jsp")
    })
    @Override
    public String execute() {
        try {
            char p = privilege.charAt(0);
            int i = Integer.parseInt(moduleid);
            allowable = queryPrivilege(i, p);
            logger.info(privilege+", "+moduleid+", "+ut.getUsertypeid()+", "+allowable);
            return SUCCESS + pagename;
        } catch (Exception e) {
            if (emps != null) {
                logger.fatal("(" + emps.getIdnumber() + "):" + e.getLocalizedMessage(), e);
            } else {
                logger.fatal(e.getLocalizedMessage(), e);

            }
            e.printStackTrace();
            addActionError(e.getLocalizedMessage());
            return ERROR;
        }
    }

    private boolean queryPrivilege(int moduleid, char privilege) {
        DetachedCriteria criteria = DetachedCriteria.forClass(UsertypeModule.class);
        criteria.createCriteria("usertypes", "ut").setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        criteria.createCriteria("modules", "m").setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        criteria.add(Restrictions.eq("m.moduleid", moduleid));
        criteria.add(Restrictions.eq("ut.usertypeid", ut.getUsertypeid()));
        UsertypeModule um = umodDao.getPrivilege(criteria);
        logger.info(um.getModulename());
        boolean p = false;
        switch (privilege) {
            case 'v': p = um.isViewable();
                break;
            case 'e': p = um.isEditable();
                break;
            case 'c': p = um.isCreateable();
                break;
            case 'd': p = um.isDeleteable();
                break;
        }
        return p;
    }

//getters and setters

这是我的数据访问对象中的代码:'umodDao':

@SuppressWarnings("unchecked")
    public UsertypeModule getPrivilege(DetachedCriteria dc){
        Criteria criteria = dc.getExecutableCriteria(session);
        criteria.setMaxResults(1);
        return (UsertypeModule) criteria.uniqueResult();
    }

当我运行我的项目并导航到dccr.jsp时,我收到此错误:

May 31, 2011 8:34:52 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.StackOverflowError
    at java.util.HashMap.get(HashMap.java:300)
    at java.lang.Package.getSystemPackage(Package.java:491)
    at java.lang.Package.getPackage(Package.java:313)
    at java.lang.Class.getPackage(Class.java:698)
    at com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInterceptor.isCandidadeClass(SessionTransactionInjectorInterceptor.java:313)
    at com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInterceptor.injectHibernateCoreSession(SessionTransactionInjectorInterceptor.java:340)
    at com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInterceptor.injectHibernateCoreSession(SessionTransactionInjectorInterceptor.java:361)

是的,我使用的是FHP(Full Hibernate Plugin 1.4GA),我的Servlet容器是netbeans 7.0上的Tomcat 7.0。我已经玩了好几天但每次尝试都失败了,堆栈跟踪指向FHP插件的SessionTransactionInjectorInterceptor.injectHibernateCoreSession方法。请帮助我或者说一些可能会有所帮助的事情。


我怀疑这个问题必须与我的tomcat策略有关,因为当我升级到fhp 2.2GA时,我仍然遇到了stackoverflower,但是

java.security.AccessController.doPrivileged(Native Method

已包含在堆栈跟踪中。但这只是一种怀疑。由于这个问题,我无法继续我的工作所以我正在考虑将我的项目恢复到最新的工作版本,以便继续我的工作,并在我能够解决这个持久性问题时最终提交我的更改。

3 个答案:

答案 0 :(得分:1)

java.lang.StackOverflowError通常表示没有停止条件的递归调用。我开始寻找一个。

答案 1 :(得分:0)

我刚检查了SessionTransactionInjectorInterceptor的代码。

使用Class.getPackage()会导致问题。他们不应该使用getPackage(),而是从类名解析包名。

我不确定你如何解决这个问题。从同一个包加载一个类运行之前(即静态{}块中的某个地方)并调用getPackage()应该会有所帮助。

总体而言struts2不应该使用getPackage,因为它用于不同的目的。 (除此之外,没有性能优势,但需要在全局锁定上同步)。

答案 2 :(得分:0)

我遇到了类似的问题,但不知何故,这个问题神奇地修复了。每当我运行它时,我得到了这个令人难以置信的长堆栈跟踪,这是StackOverflowException的结果。

我按照第一个回答者的建议,在调试模式下运行它,看看是否有一些永无止境的递归调用。但是,在调试模式期间,问题不再出现。

我的理论是这个堆栈溢出问题与Struts2 FilterDispatcher类有某种关系。

如果您发现代码没有任何问题,那么您可能也会遇到这种情况。特别是,如果您的Struts2项目更像是一个试用实验,只需要很少的代码,而且您知道在代码中的任何地方都没有使用递归。