我在项目的开发过程中,发现Tomcat解压war 的一点例外。
   
   现象如下:

使用ANT工具把web应用程序打包为war文件。然后把war文件放到tomcat的webapps,让tomcat自己解压。结果出现解压的web应用程序文件丢失。使用rar工具打开war文件。文件都齐全。怎么有这种现象呢??查看tomcat的log文档。发现在解压war文档NullpointException.我升级tomcat到5.0还是出现这种现象。

jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/HostConfig.java

解决方法:

我从tomcat网站下载了catalina 的原代码,进行分析。发现是在解压war文件出现input为null,而 input= jar.getInputStream(entry);然后提高tomcat的debug级别。可以在tomcat的log文档看到tomcat解压war文档的过程。发现如果某些文件名为???.txt,经检查发现原来这个文件的文件名为汉字。
      噢!才发现war文件在解压的过程中无法处理汉字的文件名。(因为找不到文件名为???.txt的文件而导致null例外。原来这个文件是个注释文档),所以在使用ant把web应用程序打包为war文件,一定要把文件名为汉字的文件去掉。使用Forte for java的IDE工具把web应用程序打包为war文件会不包含这些文件名为汉字的文件

下面是部分war文档解压的部分代码

代码采自jakarta.org

类HostConfig.java

jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/HostConfig.java

解决方法:

我从tomcat网站下载了catalina 的原代码,进行分析。发现是在解压war文件出现input为null,而 input= jar.getInputStream(entry);然后提高tomcat的debug级别。可以在tomcat的log文档看到tomcat解压war文档的过程。发现如果某些文件名为???.txt,经检查发现原来这个文件的文件名为汉字。
      噢!才发现war文件在解压的过程中无法处理汉字的文件名。(因为找不到文件名为???.txt的文件而导致null例外。原来这个文件是个注释文档),所以在使用ant把web应用程序打包为war文件,一定要把文件名为汉字的文件去掉。使用Forte for java的IDE工具把web应用程序打包为war文件会不包含这些文件名为汉字的文件

下面是部分war文档解压的部分代码

代码采自jakarta.org

类HostConfig.java

jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/HostConfig.java

  1. protected void deployWARs(File appBase, String[] files) {
  2. for (int i = 0; i < files.length; i++) {
  3. if (files[i].equalsIgnoreCase("META-INF"))
  4. continue;
  5. if (files[i].equalsIgnoreCase("WEB-INF"))
  6. continue;
  7. if (deployed.contains(files[i]))
  8. continue;
  9. File dir = new File(appBase, files[i]);
  10. if (files[i].toLowerCase().endsWith(".war")) {
  11. deployed.add(files[i]);
  12. // Calculate the context path and make sure it is unique
  13. String contextPath = "/" + files[i];
  14. int period = contextPath.lastIndexOf(".");
  15. if (period >= 0)
  16. contextPath = contextPath.substring(0, period);
  17. if (contextPath.equals("/ROOT"))
  18. contextPath = "";
  19. if (host.findChild(contextPath) != null)
  20. continue;
  21. // Checking for a nested /META-INF/context.xml
  22. JarFile jar = null;
  23. JarEntry entry = null;
  24. InputStream istream = null;
  25. BufferedOutputStream ostream = null;
  26. File xml = new File
  27. (configBase, files[i].substring
  28. (0, files[i].lastIndexOf(".")) + ".xml");
  29. if (!xml.exists()) {
  30. try {
  31. jar = new JarFile(dir);
  32. entry = jar.getJarEntry("META-INF/context.xml");
  33. if (entry != null) {
  34. istream = jar.getInputStream(entry);
  35. ostream =
  36. new BufferedOutputStream
  37. (new FileOutputStream(xml), 1024);
  38. byte buffer[] = new byte[1024];
  39. while (true) {
  40. int n = istream.read(buffer);
  41. if (n < 0) {
  42. break;
  43. }
  44. ostream.write(buffer, 0, n);
  45. }
  46. ostream.flush();
  47. ostream.close();
  48. ostream = null;
  49. istream.close();
  50. istream = null;
  51. entry = null;
  52. jar.close();
  53. jar = null;
  54. deployDescriptors(configBase(), configBase.list());
  55. return;
  56. }
  57. catch (Exception e) {
  58. // Ignore and continue
  59. if (ostream != null) {
  60. try {
  61. ostream.close();
  62. catch (Throwable t) {
  63. ;
  64. }
  65. ostream = null;
  66. }
  67. if (istream != null) {
  68. try {
  69. istream.close();
  70. catch (Throwable t) {
  71. ;
  72. }
  73. istream = null;
  74. }
  75. entry = null;
  76. if (jar != null) {
  77. try {
  78. jar.close();
  79. catch (Throwable t) {
  80. ;
  81. }
  82. jar = null;
  83. }
  84. }
  85. }
  86. if (isUnpackWARs()) {
  87. // Expand and deploy this application as a directory
  88. log.debug(sm.getString("hostConfig.expand", files[i]));
  89. URL url = null;
  90. String path = null;
  91. try {
  92. url = new URL("jar:file:" +
  93. dir.getCanonicalPath() + "!/");
  94. path = ExpandWar.expand(host, url);
  95. catch (IOException e) {
  96. // JAR decompression failure
  97. log.warn(sm.getString
  98. ("hostConfig.expand.error", files[i]));
  99. continue;
  100. catch (Throwable t) {
  101. log.error(sm.getString
  102. ("hostConfig.expand.error", files[i]), t);
  103. continue;
  104. }
  105. try {
  106. if (path != null) {
  107. url = new URL("file:" + path);
  108. ((Deployer) host).install(contextPath, url);
  109. }
  110. catch (Throwable t) {
  111. log.error(sm.getString
  112. ("hostConfig.expand.error", files[i]), t);
  113. }
  114. else {
  115. // Deploy the application in this WAR file
  116. log.info(sm.getString("hostConfig.deployJar", files[i]));
  117. try {
  118. URL url = new URL("file", null,
  119. dir.getCanonicalPath());
  120. url = new URL("jar:" + url.toString() + "!/");
  121. ((Deployer) host).install(contextPath, url);
  122. catch (Throwable t) {
  123. log.error(sm.getString("hostConfig.deployJar.error",
  124. files[i]), t);
  125. }
  126. }
  127. }
  128. }
  129. }

类 ExpandWar.java
jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/ExpandWar.java

  1. package org.apache.catalina.startup;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.InputStream;
  6. import java.io.IOException;
  7. import java.net.JarURLConnection;
  8. import java.net.URL;
  9. import java.util.Enumeration;
  10. import java.util.jar.JarEntry;
  11. import java.util.jar.JarFile;
  12. import org.apache.catalina.Host;
  13. import org.apache.catalina.Logger;
  14. import org.apache.catalina.core.StandardHost;
  15. import org.apache.catalina.util.StringManager;
  16. /**
  17.  * Expand out a WAR in a Host‘s appBase.
  18.  *
  19.  * @author Craig R. McClanahan
  20.  * @author Remy Maucherat
  21.  * @author Glenn L. Nielsen
  22.  * @version $Revision: 1.4 $
  23.  */
  24. public class ExpandWar {
  25. /**
  26.      * The string resources for this package.
  27.      */
  28. protected static final StringManager sm =
  29. StringManager.getManager(Constants.Package);
  30. /**
  31.      * Expand the WAR file found at the specified URL into an unpacked
  32.      * directory structure, and return the absolute pathname to the expanded
  33.      * directory.
  34.      *
  35.      * @param host Host war is being installed for
  36.      * @param war URL of the web application archive to be expanded
  37.      *  (must start with "jar:")
  38.      *
  39.      * @exception IllegalArgumentException if this is not a "jar:" URL
  40.      * @exception IOException if an input/output error was encountered
  41.      *  during expansion
  42.      */
  43. public static String expand(Host host, URL war)
  44. throws IOException {
  45. int debug = 0;
  46. Logger logger = host.getLogger();
  47. if (host instanceof StandardHost) {
  48. debug = ((StandardHost) host).getDebug();
  49. }
  50. // Calculate the directory name of the expanded directory
  51. if (debug >= 1) {
  52. logger.log("expand(" + war.toString() + ")");
  53. }
  54. String pathname = war.toString().replace(‘\\‘, ‘/‘);
  55. if (pathname.endsWith("!/")) {
  56. pathname = pathname.substring(0, pathname.length() - 2);
  57. }
  58. int period = pathname.lastIndexOf(‘.‘);
  59. if (period >= pathname.length() - 4)
  60. pathname = pathname.substring(0, period);
  61. int slash = pathname.lastIndexOf(‘/‘);
  62. if (slash >= 0) {
  63. pathname = pathname.substring(slash + 1);
  64. }
  65. if (debug >= 1) {
  66. logger.log("  Proposed directory name: " + pathname);
  67. }
  68. return expand(host, war, pathname);
  69. }
  70. /**
  71.      * Expand the WAR file found at the specified URL into an unpacked
  72.      * directory structure, and return the absolute pathname to the expanded
  73.      * directory.
  74.      *
  75.      * @param host Host war is being installed for
  76.      * @param war URL of the web application archive to be expanded
  77.      *  (must start with "jar:")
  78.      * @param pathname Context path name for web application
  79.      *
  80.      * @exception IllegalArgumentException if this is not a "jar:" URL
  81.      * @exception IOException if an input/output error was encountered
  82.      *  during expansion
  83.      */
  84. public static String expand(Host host, URL war, String pathname)
  85. throws IOException {
  86. int debug = 0;
  87. Logger logger = host.getLogger();
  88. if (host instanceof StandardHost) {
  89. debug = ((StandardHost) host).getDebug();
  90. }
  91. // Make sure that there is no such directory already existing
  92. File appBase = new File(host.getAppBase());
  93. if (!appBase.isAbsolute()) {
  94. appBase = new File(System.getProperty("catalina.base"),
  95. host.getAppBase());
  96. }
  97. if (!appBase.exists() || !appBase.isDirectory()) {
  98. throw new IOException
  99. (sm.getString("hostConfig.appBase",
  100. appBase.getAbsolutePath()));
  101. }
  102. File docBase = new File(appBase, pathname);
  103. if (docBase.exists()) {
  104. // War file is already installed
  105. return (docBase.getAbsolutePath());
  106. }
  107. // Create the new document base directory
  108. docBase.mkdir();
  109. if (debug >= 2) {
  110. logger.log("  Have created expansion directory " +
  111. docBase.getAbsolutePath());
  112. }
  113. // Expand the WAR into the new document base directory
  114. JarURLConnection juc = (JarURLConnection) war.openConnection();
  115. juc.setUseCaches(false);
  116. JarFile jarFile = null;
  117. InputStream input = null;
  118. try {
  119. jarFile = juc.getJarFile();
  120. if (debug >= 2) {
  121. logger.log("  Have opened JAR file successfully");
  122. }
  123. Enumeration jarEntries = jarFile.entries();
  124. if (debug >= 2) {
  125. logger.log("  Have retrieved entries enumeration");
  126. }
  127. while (jarEntries.hasMoreElements()) {
  128. JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
  129. String name = jarEntry.getName();
  130. if (debug >= 2) {
  131. logger.log("  Am processing entry " + name);
  132. }
  133. int last = name.lastIndexOf(‘/‘);
  134. if (last >= 0) {
  135. File parent = new File(docBase,
  136. name.substring(0, last));
  137. if (debug >= 2) {
  138. logger.log("  Creating parent directory " + parent);
  139. }
  140. parent.mkdirs();
  141. }
  142. if (name.endsWith("/")) {
  143. continue;
  144. }
  145. if (debug >= 2) {
  146. logger.log("  Creating expanded file " + name);
  147. }
  148. input = jarFile.getInputStream(jarEntry);
  149. expand(input, docBase, name);
  150. input.close();
  151. input = null;
  152. }
  153. catch (IOException e) {
  154. // If something went wrong, delete expanded dir to keep things 
  155. // clean
  156. deleteDir(docBase);
  157. throw e;
  158. finally {
  159. if (input != null) {
  160. try {
  161. input.close();
  162. catch (Throwable t) {
  163. ;
  164. }
  165. input = null;
  166. }
  167. if (jarFile != null) {
  168. try {
  169. jarFile.close();
  170. catch (Throwable t) {
  171. ;
  172. }
  173. jarFile = null;
  174. }
  175. }
  176. // Return the absolute path to our new document base directory
  177. return (docBase.getAbsolutePath());
  178. }
  179. /**
  180.      * Delete the specified directory, including all of its contents and
  181.      * subdirectories recursively.
  182.      *
  183.      * @param dir File object representing the directory to be deleted
  184.      */
  185. public static void deleteDir(File dir) {
  186. String files[] = dir.list();
  187. if (files == null) {
  188. files = new String[0];
  189. }
  190. for (int i = 0; i < files.length; i++) {
  191. File file = new File(dir, files[i]);
  192. if (file.isDirectory()) {
  193. deleteDir(file);
  194. else {
  195. file.delete();
  196. }
  197. }
  198. dir.delete();
  199. }
  200. /**
  201.      * Expand the specified input stream into the specified directory, creating
  202.      * a file named from the specified relative path.
  203.      *
  204.      * @param input InputStream to be copied
  205.      * @param docBase Document base directory into which we are expanding
  206.      * @param name Relative pathname of the file to be created
  207.      *
  208.      * @exception IOException if an input/output error occurs
  209.      */
  210. protected static void expand(InputStream input, File docBase, String name)
  211. throws IOException {
  212. File file = new File(docBase, name);
  213. BufferedOutputStream output = null;
  214. try {
  215. output =
  216. new BufferedOutputStream(new FileOutputStream(file));
  217. byte buffer[] = new byte[2048];
  218. while (true) {
  219. [b]int n = input.read(buffer);[/b]
  220. if (n <= 0)
  221. break;
  222. output.write(buffer, 0, n);
  223. }
  224. finally {
  225. if (output != null) {
  226. try {
  227. output.close();
  228. catch (IOException e) {
  229. // Ignore
  230. }
  231. }
  232. }
  233. }
  234. }

tomcat解压war包的一点例外的更多相关文章

  1. linux解压war包的命令

    网上很多人说用jar包解压,但jar命令解压时不能指定目录,推荐使用unzip解压war包. 一.命令名: unzip 功 能说明:解压缩zip文 件 语 法:unzip [-cflptuvz][-a ...

  2. jar 压缩 解压 war包

    Win+R 输入cmd进入命令行,进入到源码所在目录.所用工具,jdk自带的jar.exe 打包命令:jar -cvf xxx.war * 解包命令: jar -xvf xxx.war * 参数 说明 ...

  3. shell 脚本解压war包+备份+tomcat自动关闭+启动

    公司的开发环境每次替换war包时候,老是需要重新上传并且手动解压,然后再去重启tomcat.觉得这样子太麻烦了,于是写了一个shell脚本,自动解压+备份+tomcat自动关闭+启动.代码如下: #关 ...

  4. Linux下打包压缩war、解压war包和jar命令

    情景:把project_a文件夹下的文件打包成project.war 1. 打包 jar -cvf project.war /project_a 说明: -c 创建war包 -v 显示过程信息 -f ...

  5. unzip解压war包并覆盖

    unzip -o blog.war -d BLOG 参数: -o 不进行询问直接覆盖 -d 压缩文件解压到BLOG文件夹下 详细使用语法: unzip [-Z] [-opts[modifiers]] ...

  6. jar 解压war包到指定目录

    用 jar -xvf  .jar 命令默认解压到当前目录,想要解压到指定目录 需要使用unzip .jar -d 目录 如: unzip pay.war -d /home/zookeeper1/tes ...

  7. linux解压war包

    可以用unzip命令 unzip project.war -d project 这样就在当前目录下解压project.war到project目录里面,参数-d的意思是创建project目录 附:unz ...

  8. 使用jar打war包或解压war包

    进入Dos命令行,并到目标文件夹,如C:\Temp,待打包的内容在C:\Temp\Blog里,目标,把Blog里的相应文件打成war报 1.打包 C:\Temp\jar -cvf Blog.war . ...

  9. 解压war包

    unzip cat-alpha-3.0.0.war -d /tmp/test 说明:-d指定解压的路径和文件,文件名不存在会自动创建

随机推荐

  1. selenium python (十)浏览器多窗口处理

    #!/usr/bin/python# -*- coding: utf-8 -*-__author__ = 'zuoanvip'#在测试过程中有时候会遇到出现多个浏览器窗口的情况,这时候我们可以通过窗口 ...

  2. ifstream 流 判断文件是否结尾的函数eof(.xml

    pre{ line-height:1; color:#800080; font-size:16px;}.sysFunc{color:#627cf6;font-style:italic;font-wei ...

  3. cJSON学习笔记

    1.JSON格式简述 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解析和生成.它基于JavaScript(Standa ...

  4. wifi reaver

    PIN码的格式很简单, 八位十进制数,最后一位(第8位)为校验位(可根据前7位算出),验证时先检测前4位,如果一致则反馈一个信息,所以只需1万次就可完全扫描一遍前4位,前4位确定下来的话,只需再试10 ...

  5. Delphi 调用外部程序并等待其运行结束

    转自:http://blog.csdn.net/xieyunc/article/details/4140620   如何让Delphi调用外部程序并等待其运行结束 1. uses     Window ...

  6. 单源最短路径的Bellman-Ford 算法

    1.算法标签 BFS 2.算法概念 Bellman-Ford算法有这么一个先验知识在里面,那就是最短路径至多在N步之内,其中N为节点数,否则说明图中有负权值的回路,这样的图是找不到最短路径的.因此Be ...

  7. Azure Cloud中的Log4Net设置

    这里的Cloud包含Worker Role和Web Role,Role是运行在云主机中的,这里的主机和VM有所不同,Windows Azure Role Architecture.我们并没有和本地服务 ...

  8. Spark RDD概念学习系列之RDD的创建(六)

    RDD的创建  两种方式来创建RDD: 1)由一个已经存在的Scala集合创建 2)由外部存储系统的数据集创建,包括本地文件系统,还有所有Hadoop支持的数据集,比如HDFS.Cassandra.H ...

  9. 1001Sum Problem

    Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): ...

  10. STM32中的位带(bit-band)操作

    转:http://blog.csdn.net/gaojinshan/article/details/11479929 //位带操作,实现51类似的GPIO控制功能 //具体实现思想,参考<< ...