java.lang.Ошибка StackOverflowError при вызове действия из тега действия Struts2

#java #hibernate #plugins #struts2 #stack-overflow

#java #переход в спящий режим #Плагины #struts2 #переполнение стека

Вопрос:

У меня есть файл 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 (полный плагин гибернации 1.4GA), и мой контейнер сервлета — Tomcat 7.0 на netbeans 7.0. Я несколько дней безуспешно пытался, но при каждой попытке продолжал терпеть неудачу, трассировки стека указывают на метод SessionTransactionInjectorInterceptor плагина FHP.injectHibernateCoreSession. Пожалуйста, помогите мне или просто скажите что-нибудь, что может пролить некоторый свет.


У меня есть подозрение, что эта проблема была связана с моей политикой tomcat, потому что, когда я обновился до fhp 2.2GA, я все еще сталкивался со stackoverflowerror, однако

java.security.AccessController.doPrivileged(Native Method )

уже включено в трассировку стека. Но это только подозрение. Я не могу продолжить свою работу из-за этой проблемы, поэтому я подумываю о возврате моего проекта к самой последней рабочей редакции, чтобы продолжить свою работу и в конечном итоге зафиксировать свои изменения, когда я смогу устранить эту постоянную проблему.

Комментарии:

1. Да, последняя строка повторяется бесконечно…

2. Тогда может показаться, что SessionTransactionInjectorInterceptor является источником проблемы. Я бы взглянул на то, что там происходит.

Ответ №1:

java.lang.StackOverflowError обычно означает рекурсивный вызов, у которого нет условия остановки. Я бы начал искать один.

Комментарии:

1. Спасибо, сэр, однако я не знаю, какая конкретная часть моего кода выполняет бесконечную рекурсию.

Ответ №2:

Я только что проверил код SessionTransactionInjectorInterceptor.

Использование Class.getPackage() частично вызывает проблему. Они должны не использовать getPackage() , а анализировать имя пакета из имени класса.

Я не уверен, как вы можете обойти проблему. Загрузка класса из того же пакета, прежде чем столкнуться с проблемой (т. Е. где-то в статическом блоке {}) и вызов getPackage(), должны помочь.

В целом struts2 не должен использовать getPackage, поскольку он предназначен для разных целей. (кроме того, нет никаких преимуществ в производительности, но необходимо синхронизировать с глобальной блокировкой).

Ответ №3:

У меня была похожая на вашу проблема, но каким-то волшебным образом проблема устранилась сама собой. Всякий раз, когда я запускал его, я получал невероятно длинную пару трассировок стека, которые были результатом исключения StackOverflowException.

Я последовал совету первого ответчика и запустил его в режиме отладки, чтобы посмотреть, был ли какой-то бесконечный рекурсивный вызов. Однако в режиме отладки проблема больше не возникала.

Моя теория заключается в том, что эта проблема с переполнением стека была каким-то образом связана с классом Struts2 FilterDispatcher.

Если вы не можете найти ничего неправильного в своем коде, это может быть то, что происходит и с вами. Особенно, если ваш проект Struts2 больше похож на пробный эксперимент для вас с очень небольшим количеством кода, и вы точно знаете, что нигде в своем коде рекурсия не использовалась.