我正在构建一个使用磁贴的Struts2 Web应用程序但是我发现了一个非常令人沮丧的问题,如果apache.org失效(这似乎经常发生)Web应用程序无法启动。这是因为在其标准设置中,StrutsTilesListener尝试加载tiles defenitions文件,该文件包含一个带有public-id的DOCTYPE,该id指向位于tiles.apache.org上的DTD。
当应用程序启动时,使用Apache Xerces通过Apache Commons Digester加载定义文件,该文件尝试从tiles.apache.org加载DTD但是如果apache.org关闭则会失败并且随之而来的是整个Web应用程序不会启动。
我可以通过下载文件并将其置于本地并在struts定义文件中指定新的本地位置来绕过远程位置的下载,但是此解决方案不是非常便携,因为DTD在本地保存的位置可能是在不同的开发者机器上有所不同,一旦上传到实时环境就不同了,所以我必须继续编辑位置,以便运行webapp运行的机器,这简直很烦人。
项目中没有其他xml文件存在此问题,包括struts.xml文件,该文件在apache.org上也有DTD位置,所以很明显存在设置问题,其中Tiles严格要求DTD但其他组件不是。这有什么解决方案吗?我已经没有耐心了,我不能把这个网络应用程序告知,如果apache.org在我重新启动时关闭,那么webapp将不会恢复。
Struts tile defenition file
<?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>
apache.org关闭时的Stacktrace
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
答案 0 :(得分:16)
我发现了这个问题,这是我的错,我在问题中说的一切都是真的,但这只是真的,因为在tiles.xml文件中声明的DTD版本与tile的版本之间存在不匹配我在用。
我实际上正在使用Tiles 2.0.6,但是正在引用来自磁贴2.1的DTD,因此磁贴不会引用捆绑的DTD并尝试下载它。
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
"http://tiles.apache.org/dtds/tiles-config_2_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">
答案 1 :(得分:3)
我有一个类似的例外,其原因是根本原因 -
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 Tile 3.0。
<强>解决方案:强>
我下载了文件&#34; tiles-config_3_0.dtd&#34;并将其放在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">
它工作正常,此后不会查找文件的绝对路径。
答案 2 :(得分:0)
您可以抓住dtd并将其放入您的应用程序中。然后更改URL以引用本地副本。
只需执行“wget”或在浏览器中查看它并将文件保存到项目中。