tomcat解压war包的一点例外

我在项目的开发过程中,发现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. }

 

posted @ 2013-10-30 21:48  pangbangb  阅读(1782)  评论(0编辑  收藏  举报