设为首页 收藏本站
查看: 558|回复: 0

[经验分享] tomcat解压war包的一点例外

[复制链接]

尚未签到

发表于 2015-8-12 08:23:49 | 显示全部楼层 |阅读模式
  我在项目的开发过程中,发现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





  • protected void deployWARs(File appBase, String[] files) {

  •         for (int i = 0; i < files.length; i++) {

  •             if (files.equalsIgnoreCase("META-INF"))
  •                 continue;
  •             if (files.equalsIgnoreCase("WEB-INF"))
  •                 continue;
  •             if (deployed.contains(files))
  •                 continue;
  •             File dir = new File(appBase, files);
  •             if (files.toLowerCase().endsWith(".war")) {

  •                 deployed.add(files);

  •                 // Calculate the context path and make sure it is unique
  •                 String contextPath = "/" + files;
  •                 int period = contextPath.lastIndexOf(".");
  •                 if (period >= 0)
  •                     contextPath = contextPath.substring(0, period);
  •                 if (contextPath.equals("/ROOT"))
  •                     contextPath = "";
  •                 if (host.findChild(contextPath) != null)
  •                     continue;

  •                 // Checking for a nested /META-INF/context.xml
  •                 JarFile jar = null;
  •                 JarEntry entry = null;
  •                 InputStream istream = null;
  •                 BufferedOutputStream ostream = null;
  •                 File xml = new File
  •                     (configBase, files.substring
  •                      (0, files.lastIndexOf(".")) + ".xml");
  •                 if (!xml.exists()) {
  •                     try {
  •                         jar = new JarFile(dir);
  •                         entry = jar.getJarEntry("META-INF/context.xml");
  •                         if (entry != null) {
  •                             istream = jar.getInputStream(entry);
  •                             ostream =
  •                                 new BufferedOutputStream
  •                                 (new FileOutputStream(xml), 1024);
  •                             byte buffer[] = new byte[1024];
  •                             while (true) {
  •                                 int n = istream.read(buffer);
  •                                 if (n < 0) {
  •                                     break;
  •                                 }
  •                                 ostream.write(buffer, 0, n);
  •                             }
  •                             ostream.flush();
  •                             ostream.close();
  •                             ostream = null;
  •                             istream.close();
  •                             istream = null;
  •                             entry = null;
  •                             jar.close();
  •                             jar = null;
  •                             deployDescriptors(configBase(), configBase.list());
  •                             return;
  •                         }
  •                     } catch (Exception e) {
  •                         // Ignore and continue
  •                         if (ostream != null) {
  •                             try {
  •                                 ostream.close();
  •                             } catch (Throwable t) {
  •                                 ;
  •                             }
  •                             ostream = null;
  •                         }
  •                         if (istream != null) {
  •                             try {
  •                                 istream.close();
  •                             } catch (Throwable t) {
  •                                 ;
  •                             }
  •                             istream = null;
  •                         }
  •                         entry = null;
  •                         if (jar != null) {
  •                             try {
  •                                 jar.close();
  •                             } catch (Throwable t) {
  •                                 ;
  •                             }
  •                             jar = null;
  •                         }
  •                     }
  •                 }

  •                 if (isUnpackWARs()) {

  •                     // Expand and deploy this application as a directory
  •                     log.debug(sm.getString("hostConfig.expand", files));
  •                     URL url = null;
  •                     String path = null;
  •                     try {
  •                         url = new URL("jar:file:" +
  •                                       dir.getCanonicalPath() + "!/");
  •                         path = ExpandWar.expand(host, url);
  •                     } catch (IOException e) {
  •                         // JAR decompression failure
  •                         log.warn(sm.getString
  •                                  ("hostConfig.expand.error", files));
  •                         continue;
  •                     } catch (Throwable t) {
  •                         log.error(sm.getString
  •                                   ("hostConfig.expand.error", files), t);
  •                         continue;
  •                     }
  •                     try {
  •                         if (path != null) {
  •                             url = new URL("file:" + path);
  •                             ((Deployer) host).install(contextPath, url);
  •                         }
  •                     } catch (Throwable t) {
  •                         log.error(sm.getString
  •                                   ("hostConfig.expand.error", files), t);
  •                     }

  •                 } else {

  •                     // Deploy the application in this WAR file
  •                     log.info(sm.getString("hostConfig.deployJar", files));
  •                     try {
  •                         URL url = new URL("file", null,
  •                                           dir.getCanonicalPath());
  •                         url = new URL("jar:" + url.toString() + "!/");
  •                         ((Deployer) host).install(contextPath, url);
  •                     } catch (Throwable t) {
  •                         log.error(sm.getString("hostConfig.deployJar.error",
  •                                          files), t);
  •                     }

  •                 }

  •             }

  •         }

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




  • package org.apache.catalina.startup;

  • import java.io.BufferedOutputStream;
  • import java.io.File;
  • import java.io.FileOutputStream;
  • import java.io.InputStream;
  • import java.io.IOException;
  • import java.net.JarURLConnection;
  • import java.net.URL;
  • import java.util.Enumeration;
  • import java.util.jar.JarEntry;
  • import java.util.jar.JarFile;

  • import org.apache.catalina.Host;
  • import org.apache.catalina.Logger;
  • import org.apache.catalina.core.StandardHost;
  • import org.apache.catalina.util.StringManager;

  • /**
  • * Expand out a WAR in a Host‘s appBase.
  • *
  • * @author Craig R. McClanahan
  • * @author Remy Maucherat
  • * @author Glenn L. Nielsen
  • * @version $Revision: 1.4 $
  • */

  • public class ExpandWar {


  •     /**
  •      * The string resources for this package.
  •      */
  •     protected static final StringManager sm =
  •         StringManager.getManager(Constants.Package);


  •     /**
  •      * Expand the WAR file found at the specified URL into an unpacked
  •      * directory structure, and return the absolute pathname to the expanded
  •      * directory.
  •      *
  •      * @param host Host war is being installed for
  •      * @param war URL of the web application archive to be expanded
  •      *  (must start with "jar:")
  •      *
  •      * @exception IllegalArgumentException if this is not a "jar:" URL
  •      * @exception IOException if an input/output error was encountered
  •      *  during expansion
  •      */
  •     public static String expand(Host host, URL war)
  •         throws IOException {

  •         int debug = 0;
  •         Logger logger = host.getLogger();

  •         if (host instanceof StandardHost) {
  •             debug = ((StandardHost) host).getDebug();
  •         }

  •         // Calculate the directory name of the expanded directory
  •         if (debug >= 1) {
  •             logger.log("expand(" + war.toString() + ")");
  •         }
  •         String pathname = war.toString().replace(‘\\‘, ‘/‘);
  •         if (pathname.endsWith("!/")) {
  •             pathname = pathname.substring(0, pathname.length() - 2);
  •         }
  •         int period = pathname.lastIndexOf(‘.‘);
  •         if (period >= pathname.length() - 4)
  •             pathname = pathname.substring(0, period);
  •         int slash = pathname.lastIndexOf(‘/‘);
  •         if (slash >= 0) {
  •             pathname = pathname.substring(slash + 1);
  •         }
  •         if (debug >= 1) {
  •             logger.log("  Proposed directory name: " + pathname);
  •         }
  •         return expand(host, war, pathname);

  •     }


  •     /**
  •      * Expand the WAR file found at the specified URL into an unpacked
  •      * directory structure, and return the absolute pathname to the expanded
  •      * directory.
  •      *
  •      * @param host Host war is being installed for
  •      * @param war URL of the web application archive to be expanded
  •      *  (must start with "jar:")
  •      * @param pathname Context path name for web application
  •      *
  •      * @exception IllegalArgumentException if this is not a "jar:" URL
  •      * @exception IOException if an input/output error was encountered
  •      *  during expansion
  •      */
  •     public static String expand(Host host, URL war, String pathname)
  •         throws IOException {

  •         int debug = 0;
  •         Logger logger = host.getLogger();

  •         if (host instanceof StandardHost) {
  •             debug = ((StandardHost) host).getDebug();
  •         }

  •         // Make sure that there is no such directory already existing
  •         File appBase = new File(host.getAppBase());
  •         if (!appBase.isAbsolute()) {
  •             appBase = new File(System.getProperty("catalina.base"),
  •                                host.getAppBase());
  •         }
  •         if (!appBase.exists() || !appBase.isDirectory()) {
  •             throw new IOException
  •                 (sm.getString("hostConfig.appBase",
  •                               appBase.getAbsolutePath()));
  •         }
  •         File docBase = new File(appBase, pathname);
  •         if (docBase.exists()) {
  •             // War file is already installed
  •             return (docBase.getAbsolutePath());
  •         }

  •         // Create the new document base directory
  •         docBase.mkdir();
  •         if (debug >= 2) {
  •             logger.log("  Have created expansion directory " +
  •                 docBase.getAbsolutePath());
  •         }

  •         // Expand the WAR into the new document base directory
  •         JarURLConnection juc = (JarURLConnection) war.openConnection();
  •         juc.setUseCaches(false);
  •         JarFile jarFile = null;
  •         InputStream input = null;
  •         try {
  •             jarFile = juc.getJarFile();
  •             if (debug >= 2) {
  •                 logger.log("  Have opened JAR file successfully");
  •             }
  •             Enumeration jarEntries = jarFile.entries();
  •             if (debug >= 2) {
  •                 logger.log("  Have retrieved entries enumeration");
  •             }
  •             while (jarEntries.hasMoreElements()) {
  •                 JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
  •                 String name = jarEntry.getName();
  •                 if (debug >= 2) {
  •                     logger.log("  Am processing entry " + name);
  •                 }
  •                 int last = name.lastIndexOf(‘/‘);
  •                 if (last >= 0) {
  •                     File parent = new File(docBase,
  •                                            name.substring(0, last));
  •                     if (debug >= 2) {
  •                         logger.log("  Creating parent directory " + parent);
  •                     }
  •                     parent.mkdirs();
  •                 }
  •                 if (name.endsWith("/")) {
  •                     continue;
  •                 }
  •                 if (debug >= 2) {
  •                     logger.log("  Creating expanded file " + name);
  •                 }
  •                 input = jarFile.getInputStream(jarEntry);
  •                 expand(input, docBase, name);
  •                 input.close();
  •                 input = null;
  •             }
  •         } catch (IOException e) {
  •             // If something went wrong, delete expanded dir to keep things
  •             // clean
  •             deleteDir(docBase);
  •             throw e;
  •         } finally {
  •             if (input != null) {
  •                 try {
  •                     input.close();
  •                 } catch (Throwable t) {
  •                     ;
  •                 }
  •                 input = null;
  •             }
  •             if (jarFile != null) {
  •                 try {
  •                     jarFile.close();
  •                 } catch (Throwable t) {
  •                     ;
  •                 }
  •                 jarFile = null;
  •             }
  •         }

  •         // Return the absolute path to our new document base directory
  •         return (docBase.getAbsolutePath());

  •     }


  •     /**
  •      * Delete the specified directory, including all of its contents and
  •      * subdirectories recursively.
  •      *
  •      * @param dir File object representing the directory to be deleted
  •      */
  •     public static void deleteDir(File dir) {

  •         String files[] = dir.list();
  •         if (files == null) {
  •             files = new String[0];
  •         }
  •         for (int i = 0; i < files.length; i++) {
  •             File file = new File(dir, files);
  •             if (file.isDirectory()) {
  •                 deleteDir(file);
  •             } else {
  •                 file.delete();
  •             }
  •         }
  •         dir.delete();

  •     }


  •     /**
  •      * Expand the specified input stream into the specified directory, creating
  •      * a file named from the specified relative path.
  •      *
  •      * @param input InputStream to be copied
  •      * @param docBase Document base directory into which we are expanding
  •      * @param name Relative pathname of the file to be created
  •      *
  •      * @exception IOException if an input/output error occurs
  •      */
  •     protected static void expand(InputStream input, File docBase, String name)
  •         throws IOException {

  •         File file = new File(docBase, name);
  •         BufferedOutputStream output = null;
  •         try {
  •             output =
  •                 new BufferedOutputStream(new FileOutputStream(file));
  •             byte buffer[] = new byte[2048];
  •             while (true) {
  •                 int n = input.read(buffer);               
  •                 if (n <= 0)
  •                     break;
  •                 output.write(buffer, 0, n);
  •             }
  •         } finally {
  •             if (output != null) {
  •                 try {
  •                     output.close();
  •                 } catch (IOException e) {
  •                     // Ignore
  •                 }
  •             }
  •         }

  •     }


  • }
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-97660-1-1.html 上篇帖子: Java web实现TOMCAT启动时加载程序里的定时器小记 下篇帖子: tomcat webdav
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表