#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 больше похож на пробный эксперимент для вас с очень небольшим количеством кода, и вы точно знаете, что нигде в своем коде рекурсия не использовалась.