Я работаю над проектом, использующим openSymphony 2.1.2 и struts 2.3.8.Настройка StrutsSpringObjectFactory как мой текущий ObjectFactory
Однако на этой базе кода я пытаюсь применить код части, который был написан для более старых версий openSymphony и struts.
Вот этот кусок коды:
http://www.lischke-online.de/index.php/java/action-unit-testing-with-struts-2-0-part-2
(Как примечание стороны, мне нужен этот код для того, чтобы иметь возможность моделировать работы распорок действия от моего унаследованного проекта, в системе, основывается на различных рамок)
у меня есть проблема со следующим пунктом:.
final StrutsSpringObjectFactory ssf = new StrutsSpringObjectFactory("auto", "true", servletContext);
ObjectFactory.setObjectFactory(ssf);
на втором литий пе, я получаю сообщение об ошибке: The method setObjectFactory(StrutsSpringObjectFactory) is undefined for the type ObjectFactory
Однако, когда я смотрю на javadoc of ObjectFactory, я не вижу, альтернативный метод, который позволил бы мне установить конкретный ObjectFactory
(например, StrutsSpringObjectFactory
), как ObjectFactory
, который будет использоваться при выполнении действий. Итак, как мне установить такой конкретный ObjectFactory
с новым API?
Обновленный код:
static {
sessionMap = new HashMap<String, Object>();
// Create fake back end here.
// ...
// ===== Struts setup:
// Create and use a file system resource loader otherwise Tiles will not find
// our configuration file. The default resource loader is able to find struts.xml
// if it is in the classpath, but not tiles.xml.
final FileSystemResourceLoader loader = new FileSystemResourceLoader();
final String[] config = new String[] { "WEB-INF/classes/struts.xml" };
servletContext = new MockServletContext(loader);
final XmlWebApplicationContext appContext = new XmlWebApplicationContext();
// Link the servlet context and the Spring context.
appContext.setServletContext(servletContext);
appContext.setConfigLocations(config);
appContext.refresh();
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
appContext);
servletContext.addInitParameter(BasicTilesContainer.DEFINITIONS_CONFIG, "WEB-INF/tiles.xml");
// Creating the tiles listener statically (not via class loader).
final StrutsTilesListener tilesListener = new StrutsTilesListener();
final ServletContextEvent event = new ServletContextEvent(servletContext);
tilesListener.contextInitialized(event);
// Use spring as the object factory for Struts
//this code not working anymore with struts 2.3.2:
//final StrutsSpringObjectFactory ssf = new StrutsSpringObjectFactory("auto", "true", servletContext);
//ObjectFactory.setObjectFactory(ssf);
//my change: (original note working with newer version of struts)
//StrutsSpringObjectFactory.setObjectFactory(ssf);
//(*) original location.
// Dispatcher is the guy that actually handles all requests. Pass in
// an empty. Map as the parameters but if you want to change stuff like
// what config files to read, you need to specify them here
// (see Dispatcher's source code)
dispatcher = new Dispatcher(servletContext, new HashMap<String, String>());
dispatcher.init();
Dispatcher.setInstance(dispatcher);
//(*) moved to here:
//http://stackoverflow.com/questions/15821643/setting-strutsspringobjectfactory-as-my-current-objectfactory?noredirect=1#comment22519072_15821643
final StrutsSpringObjectFactory ssf = new StrutsSpringObjectFactory("auto", "true", "false", servletContext, "false", dispatcher.getContainer());
}
Стек след, который я получаю от этого кода, при вызове теста из в веб-приложение (развернутый войны):
08:50:28,471 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (http--127.0.0.1-8080-1) #{accountLookupBean.lookupAccounts()}: java.lang.ExceptionInInitial
izerError: javax.faces.FacesException: #{accountLookupBean.lookupAccounts()}: java.lang.ExceptionInInitializerError
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at javax.faces.component.UICommand.broadcast(UICommand.java:315) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIData.broadcast(UIData.java:1093) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIData.broadcast(UIData.java:1093) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIData.broadcast(UIData.java:1093) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.10.Final.jar:]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:154) [jboss-as-web-7.1.0.Final.jar:7.1.0.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.10.Final.jar:]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.10.Final.jar:]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.10.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.10.Final.jar:]
at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_29]
Caused by: javax.faces.el.EvaluationException: java.lang.ExceptionInInitializerError
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.
0.Final]
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
... 23 more
Caused by: java.lang.ExceptionInInitializerError
at com.myapp.services.AccountLookupServiceImpl.getRows(AccountLookupServiceImpl.java:38) [classes:]
at com.myapp.beans.AccountLookupBean.lookupAccounts(AccountLookupBean.java:39) [classes:]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.6.0_29]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [rt.jar:1.6.0_29]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [rt.jar:1.6.0_29]
at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_29]
at org.apache.el.parser.AstValue.invoke(AstValue.java:262) [jbossweb-7.0.10.Final.jar:]
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) [jbossweb-7.0.10.Final.jar:]
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0
.Final]
... 24 more
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/classes/struts.xml];
nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/classes/struts.xml]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341) [spring-beans-3.2.1.RELEASE.jar:3.2.1.REL
EASE]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302) [spring-beans-3.2.1.RELEASE.jar:3.2.1.REL
EASE]
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174) [spring-beans-3.2.1.RELEASE
.jar:3.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209) [spring-beans-3.2.1.RELEASE
.jar:3.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180) [spring-beans-3.2.1.RELEASE
.jar:3.2.1.RELEASE]
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125) [spring-web-3.2.1.RELEASE.jar:3.2.1.R
ELEASE]
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94) [spring-web-3.2.1.RELEASE.jar:3.2.1.RE
LEASE]
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130) [spring-context-
3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537) [spring-context-3.2.1.RELEASE.jar:
3.2.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:451) [spring-context-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at com.myapp.softgems.ActionBaseTestCase.<clinit>(ActionBaseTestCase.java:70) [classes:]
... 34 more
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/classes/struts.xml]
at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:140) [spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:328) [spring-beans-3.2.1.RELEASE.jar:3.2.1.REL
EASE]
... 44 more
UPDATE 2:
Причина, по которой я хочу протестировать действие, - это не просто щелкнуть правой кнопкой мыши o n из проводника проекта, а затем щелкните правой кнопкой мыши «запустить как Junit». Я действительно хочу запустить тест как часть моего веб-приложения.
Это то, что я имею в виду: я пытаюсь вызвать следующий код одного из моих классов обслуживания:
DataTest test = new DataTest("testDataAction");
JUnitCore jUnitCore = new JUnitCore();
jUnitCore.run(test);
Потому что, в DataTest я пытаюсь выполнить() DataAction. Это действие вызывает некоторую беспорядочную логику db и в конечном итоге возвращает некоторые данные. Мне нужны эти данные для моего сервиса. Вместо того, чтобы пытаться выяснить, что делает действие, я просто хочу выполнить() его и получить данные. Способ, которым я пытаюсь это сделать, - запустить тест, который будет выполнять() действие.
Мои struts.xml не находятся непосредственно в проекте, который я создаю. Вот моя ситуация: позвольте мне назвать мой новый проект, проект A; и проект устаревших распорок, от которого я зависим, проект B. Проект A строится другой структурой (JSF & Spring). Проект B использует стойки для пользовательского интерфейса. Но его действия были написаны таким грязным способом, что большая часть логики доступа к БД была написана непосредственно в действиях. Поэтому, если я хочу использовать логику из проекта B и не переписывать ее, временным решением (которое я пытаюсь выполнить) было бы выполнение Action из проекта B с соответствующими данными запроса. Способ сделать это, выполнив тест на действие из B, в классе обслуживания от A.
Поскольку проект B был упакован как файл войны, мой способ повторно использовать его с Maven в проекте A, заключается в том, чтобы определить его как наложение в проекте A. Классы и другие ресурсы из класса path проекта B упакованы в банку. Тогда в проекте А у меня есть зависимость от этой банки. Так struts.xml живет в банке, которая содержит классы и xml проекта B. Во время компиляции проект A может видеть только struts.xml в банке проекта A.
Только когда я собираю проект A, войну B распаковывается, его содержимое (включая struts.xml) копируется в целевую папку проекта A, а затем A + B упаковываются вместе в качестве войны. (в финальной войне struts.xml будет как в банке B, так и в WEB-INF/классах с окончательной войной.
Итак, на практике, если я попытаюсь запустить тест, щелкнув правой кнопкой мыши test и их «запускать как junit», он не должен искать struts.xml в некоторых WEB-INF/классах в моем пути к классам - сначала в моей рабочей области нет такой вещи, только в созданной войне. Во-вторых, я пытаюсь запустить тест только с в течение войны (как я показал выше). В то время существует WEB-INF/classes/struts.xml, почему его не найти?
Посмотрите на плагин struts2-junit и класс 'StrutsSpringJUnit4TestCase'. –