Struts2 & Tiles: когда apache.org не работает, мое веб-приложение не запускается

Я создаю веб-приложение Struts2, которое использует плитки, однако я обнаружил довольно неприятную проблему, когда, если apache.org не работает (что, кажется, происходит довольно регулярно), веб-приложение не запускается. Это связано с тем, что в своей стандартной настройке StrutsTilesListener пытается загрузить файл определений плиток, который включает DOCTYPE с общедоступным идентификатором, указывающим на DTD, расположенный наtiles.apache.org.

Когда приложение запускается, файл определения загружается с помощью Apache Xerces через Apache Commons Digester, который пытается загрузить DTD с сайтаtiles.apache.org, но если apache.org не работает, это не удается, и вместе с этим все веб-приложение не запускается.

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

Никакие другие xml-файлы в проекте не имеют этой проблемы, включая файл struts.xml, который также имеет местоположение DTD на apache.org, поэтому очевидно, что существует проблема установки, когда Tiles строго требует DTD, а другие компоненты — нет. Есть ли какое-нибудь решение для этого? У меня заканчивается терпение, и я не могу запустить это веб-приложение, зная, что если apache.org не работает, когда я перезапускаю его, веб-приложение не вернется.

Файл защиты плиток Struts

<?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
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
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, когда apache.org не работает

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

person 3urdoch    schedule 21.02.2011    source источник
comment
Какова фактическая ошибка, которую вы получаете? Я ожидаю, что Tiles DTD будет упакован в один из JAR-файлов Tiles.   -  person Steven Benitez    schedule 23.02.2011
comment
org.apache.tiles.definition.DefinitionsFactoryException: Ошибка чтения определений ввода-вывода. вызвано... java.net.SocketException: сброс соединения   -  person 3urdoch    schedule 23.02.2011
comment
Звучит как еще одна причина использовать Sitemesh.   -  person Nathan Hughes    schedule 02.03.2011
comment
@Nathan Hughes Возможно, вы правы, возможно, еще не поздно полностью отказаться от плитки в этом проекте.   -  person 3urdoch    schedule 03.03.2011
comment
Приятно знать, что это не вина Тайлза.   -  person Nathan Hughes    schedule 03.03.2011


Ответы (3)


Я обнаружил проблему, и это моя вина, все, что я сказал в своем вопросе, было правдой, однако это было правдой только потому, что было несоответствие между версией DTD, которая была объявлена ​​​​в файлеtiles.xml, и версией тайлов, которые я использовал .

На самом деле я использую Tiles 2.0.6, но ссылался на DTD из плиток 2.1, поэтому плитки не ссылались на связанный DTD и вместо этого пытались загрузить его.

<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
       "http://tiles.apache.org/dtds/tiles-config
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
1.dtd">

Должны были быть

<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
person 3urdoch    schedule 03.03.2011
comment
У меня была точно такая же проблема :) Ваш ответ спас мне день. Ваше здоровье - person Pierre Henry; 23.03.2011
comment
Вау... Я не мог понять, что эта неправильная конфигурация вызывает мою проблему... спасибо - person Pierpaolo Cira; 07.07.2015

Я получил аналогичное исключение с основной причиной ниже -

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)

Я использую плитку Apache 3.0.

Решение:

Я скачал файл «tiles-config_3_0.dtd» и поместил его в каталог WEB-INF/dtd. Сделанные ниже изменения в файле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">

Он отлично работает и после этого не ищет абсолютный путь к файлу.

person Ujjwal    schedule 24.04.2014
comment
Протокол jndi отлично работает на машине разработки. Но на сервере Ubuntu не может понять jndi. Ты знаешь почему? - person hurelhuyag; 07.09.2017

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

Просто выполните «wget» или просмотрите его в браузере и сохраните файл в своем проекте.

person DaShaun    schedule 02.03.2011
comment
Да, я сделал это, но здесь возникает проблема изменения местоположения на разных машинах разработчика. Тогда путь DTD должен быть абсолютным или относительным к рабочему каталогу, но рабочий каталог не совпадает с корнем веб-приложения. каталог в моем случае это каталог внедрения tomcat (или каталог внедрения eclipse при разработке в eclipse) - person 3urdoch; 02.03.2011
comment
Это должно быть только относительно корня приложения. Поэтому поместите загруженный .dtd в свой военный файл в /dtds. - person DaShaun; 03.03.2011
comment
Пробовал это, не работает, когда я запускаю его в eclipse, он ищет в домашнем каталоге eclipse и даже выдает исключение FileNotFoundException, указывающее, где он смотрел. Вызвано: java.io.FileNotFoundException: C:\Program Files (x86)\Eclipse Helios\tiles-config_2_1.dtd (система не может найти указанный файл), если он работает в tomcat, это то же самое, но рабочий каталог tomcat. - person 3urdoch; 03.03.2011