java Struts2 & Tiles:当 apache.org 关闭时,我的 web 应用程序无法启动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5067447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Struts2 & Tiles: When apache.org is down my webapp fails to start
提问by 3urdoch
I am building a Struts2 web application which uses tiles however I have discovered a quite frustrating problem where if apache.org is down (which seems to happen quite regularly) the web application fails to start. This is because in its standard setup the StrutsTilesListener tries to load the tiles defenitions file which includes a DOCTYPE with a public-id which points to a DTD located on tiles.apache.org.
我正在构建一个使用磁贴的 Struts2 Web 应用程序,但是我发现了一个非常令人沮丧的问题,如果 apache.org 关闭(这似乎经常发生),Web 应用程序将无法启动。这是因为在其标准设置中,StrutsTilesListener 尝试加载包含 DOCTYPE 的图块防御文件,该 DOCTYPE 具有指向位于 tile.apache.org 上的 DTD 的公共 ID。
When the application starts up the definition file is loaded using Apache Xerces via Apache Commons Digester which tries to load the DTD from tiles.apache.org but if apache.org is down then this fails and with it the whole web application wont start.
当应用程序启动时,定义文件是通过 Apache Commons Digester 使用 Apache Xerces 加载的,它试图从 tile.apache.org 加载 DTD,但如果 apache.org 关闭,那么这将失败,并且整个 Web 应用程序将无法启动。
I can bypass the download from a remote location by downloading the file and placing it local and specifying the new local location in the struts definitions file, however this solution is not very portable as the location where the DTD is saved locally may be different on different developer machines and different once uploaded to a live environment so I would have to keep editing the location so suite the machine the webapp is running on which is just plain annoying.
我可以通过下载文件并将其放置在本地并在 struts 定义文件中指定新的本地位置来绕过从远程位置的下载,但是此解决方案不是很便携,因为本地保存 DTD 的位置可能因不同而不同开发人员机器和不同的一旦上传到实时环境,所以我必须继续编辑位置,以便适合运行 web 应用程序的机器,这很烦人。
No other xml files in the project have this problem, including the struts.xml file which also has a DTD location on apache.org so clearly there is a setup problem where Tiles is strictly requiring the DTD but other components are not. Is there any solution to this? I am running out of patience and I cannot put this webapp live knowing that if apache.org is down when I restart it the webapp wont come back up.
项目中没有其他 xml 文件有这个问题,包括 struts.xml 文件,它在 apache.org 上也有一个 DTD 位置,所以很明显存在一个设置问题,即 Tiles 严格要求 DTD 而其他组件则没有。有什么解决办法吗?我已经没有耐心了,我无法让这个 webapp 上线,因为我知道如果 apache.org 在我重新启动时关闭,webapp 将不会恢复。
Struts tiles defenition file
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_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 when apache.org is down
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
回答by 3urdoch
I have discovered the problem and it is my fault, everything I said in my question was true however it was only true because there was a mismatch between the DTD version that was declared in the tiles.xml file and the version of tiles I was using.
我发现了问题,这是我的错,我在问题中所说的一切都是真的,但这只是因为在tiles.xml 文件中声明的DTD 版本与我使用的tile 版本不匹配.
I am actually using Tiles 2.0.6 but was referencing the DTD from tiles 2.1 so tiles was not referencing the bundled DTD and trying to download it instead.
我实际上使用的是 Tiles 2.0.6,但引用了来自 Tiles 2.1 的 DTD,因此 Tiles 没有引用捆绑的 DTD 而是尝试下载它。
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
Should have been
本来应该
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
回答by Ujjwal
I got a similar exception with below root cause -
我遇到了类似的异常,其根本原因如下-
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)
I am using Apache Tile 3.0.
我正在使用 Apache Tile 3.0。
Solution:
解决方案:
I downloaded the file "tiles-config_3_0.dtd" and placed it in WEB-INF/dtd dir. Made below changes in the tiles-definition.xml file -
我下载了文件“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">
It works fine and does not look for absolute path of the file thereafter.
它工作正常,此后不会查找文件的绝对路径。
回答by DaShaun
You can grab the dtd and place it in your application. Then change the URL to reference your local copy.
您可以获取 dtd 并将其放入您的应用程序中。然后更改 URL 以引用您的本地副本。
Just do a "wget" or view it in your browser and save the file to your project.
只需执行“wget”或在浏览器中查看它并将文件保存到您的项目中。