java - example - Struts2 & Tiles: cuando apache.org está inactivo, mi aplicación web no puede iniciarse
struts2 maven (3)
Estoy construyendo una aplicación web Struts2 que usa mosaicos, sin embargo, he descubierto un problema bastante frustrante donde si apache.org no funciona (lo que parece suceder con bastante frecuencia), la aplicación web no se inicia. Esto se debe a que en su configuración estándar, StrutsTilesListener intenta cargar el archivo de argumentos de las teselas, que incluye un DOCTYPE con una identificación pública que apunta a una DTD ubicada en tiles.apache.org.
Cuando se inicia la aplicación, el archivo de definición se carga utilizando Apache Xerces a través de Apache Commons Digester, que intenta cargar el DTD desde tiles.apache.org, pero si apache.org falla, esto no funciona y con ello no se iniciará la aplicación web completa.
Puedo omitir la descarga desde una ubicación remota descargando el archivo y colocándolo local y especificando la nueva ubicación local en el archivo de definiciones de struts; sin embargo, esta solución no es muy portátil ya que la ubicación donde se guarda el DTD local puede ser diferente en diferentes máquinas de desarrollador y diferentes una vez cargados en un entorno en vivo, así que tendría que seguir editando la ubicación para que la máquina en la que se está ejecutando la aplicación web sea sencillamente molesta.
Ningún otro archivo xml del proyecto tiene este problema, incluido el archivo struts.xml, que también tiene una ubicación DTD en apache.org, por lo que es evidente que hay un problema de instalación donde Tiles exige estrictamente el DTD, pero otros componentes no lo están. Hay alguna solución para esto? Me estoy quedando sin paciencia y no puedo poner esta aplicación web en vivo sabiendo que si apache.org no funciona cuando lo reinicio, la aplicación web no volverá.
Struts tiles archivo de defensa
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>
<definition name="master" template="/tiles/templates/master.jsp">
</definition>
<definition name="public" extends="master">
<put-attribute name="header" value="/tiles/templates/public/header.jsp" />
<put-attribute name="footer" value="/tiles/templates/public/footer.jsp" />
<put-attribute name="templateMeta" value="/tiles/templates/public/meta.jsp" />
</definition>
</tiles-definitions>
Stacktrace cuando Apache.org está abajo
SEVERE: Exception sending context initialized event to listener instance of class org.apache.struts2.tiles.StrutsTilesListener
java.lang.IllegalStateException: Unable to instantiate container.
at org.apache.tiles.web.startup.TilesListener.contextInitialized(TilesListener.java:60)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3972)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4467)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:519)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.apache.tiles.definition.DefinitionsFactoryException: I/O Error reading definitions.
at org.apache.tiles.definition.digester.DigesterDefinitionsReader.read(DigesterDefinitionsReader.java:273)
at org.apache.tiles.definition.UrlDefinitionsFactory.readDefinitions(UrlDefinitionsFactory.java:286)
at org.apache.tiles.definition.UrlDefinitionsFactory.init(UrlDefinitionsFactory.java:130)
at org.apache.tiles.impl.BasicTilesContainer.initializeDefinitionsFactory(BasicTilesContainer.java:406)
at org.apache.tiles.impl.BasicTilesContainer.init(BasicTilesContainer.java:130)
at org.apache.tiles.factory.TilesContainerFactory.initializeContainer(TilesContainerFactory.java:232)
at org.apache.tiles.factory.TilesContainerFactory.createTilesContainer(TilesContainerFactory.java:198)
at org.apache.tiles.factory.TilesContainerFactory.createContainer(TilesContainerFactory.java:163)
at org.apache.tiles.web.startup.TilesListener.createContainer(TilesListener.java:90)
at org.apache.struts2.tiles.StrutsTilesListener.createContainer(StrutsTilesListener.java:68)
at org.apache.tiles.web.startup.TilesListener.contextInitialized(TilesListener.java:57)
... 15 more
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at org.apache.commons.digester.Digester.createInputSourceFromURL(Digester.java:2072)
at org.apache.commons.digester.Digester.resolveEntity(Digester.java:1725)
at com.sun.org.apache.xerces.internal.util.EntityResolverWrapper.resolveEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.resolveEntityAsPerStax(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.apache.commons.digester.Digester.parse(Digester.java:1887)
at org.apache.tiles.definition.digester.DigesterDefinitionsReader.read(DigesterDefinitionsReader.java:267)
... 25 more
Puede tomar el dtd y colocarlo en su aplicación. Luego, cambie la URL para hacer referencia a su copia local.
Simplemente haga un "wget" o visualícelo en su navegador y guarde el archivo en su proyecto.
Descubrí el problema y es mi culpa, todo lo que dije en mi pregunta era cierto; sin embargo, solo era cierto porque había una discrepancia entre la versión de DTD que se declaró en el archivo tiles.xml y la versión de los mosaicos que estaba usando .
De hecho, estoy usando Tiles 2.0.6 pero estaba haciendo referencia a la DTD desde las teselas 2.1, por lo que tiles no estaba haciendo referencia a la DTD incluida y tratando de descargarla en su lugar.
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
Debería haber sido
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
Obtuve una excepción similar con la causa raíz siguiente:
Caused by: org.apache.tiles.definition.DefinitionsFactoryException: I/O Error reading definitions.
at org.apache.tiles.definition.digester.DigesterDefinitionsReader.read(DigesterDefinitionsReader.java:273)
at org.apache.tiles.definition.UrlDefinitionsFactory.readDefinitions(UrlDefinitionsFactory.java:286)
Estoy usando Apache Tile 3.0.
Solución:
Descargué el archivo "tiles-config_3_0.dtd" y lo coloqué en WEB-INF / dtd dir. Hecho debajo de los cambios en el archivo tiles-definition.xml -
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"jndi:/localhost/myapp/WEB-INF/dtd/tiles-config_3_0.dtd">
Funciona bien y no busca la ruta absoluta del archivo a partir de entonces.