• 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. }
  • 相关阅读:
    Xcode4快速Doxygen文档注释 — 简明图文教程
    iOS6 旋转
    echart 判断数据是否为空
    echart tootip使用技巧
    下拉菜单自动向上或向下弹起
    前后台数据交互
    打包代码
    echart 设计宽度为百分比时,div撑不开
    无缝滚动(小鹏写)
    内置对象-Request对象
  • 原文地址:https://www.cnblogs.com/pangblog/p/3397863.html
Copyright © 2020-2023  润新知