我在项目的开发过程中,发现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[i].equalsIgnoreCase( "META-INF" ))
- continue ;
- if (files[i].equalsIgnoreCase( " WEB- INF" ))
- continue ;
- if (deployed.contains(files[i]))
- continue ;
- File dir = new File (appBase, files[i]);
- if (files[i].toLowerCase().endsWith( ".war" )) {
- deployed.add(files[i]);
- // Calculate the context path and make sure it is unique
- String contextPath = "/" + files[i];
- 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[i].substring
- (0, files[i].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[i]));
- 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[i]));
- continue ;
- } catch ( Throwable t) {
- log.error(sm.getString
- ( "hostConfig.expand.error" , files[i]), 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[i]), t);
- }
- } else {
- // Deploy the application in this WAR file
- log.info(sm.getString( "hostConfig.deployJar" , files[i]));
- 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[i]), 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[i]);
- 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 ) {
- [b] int n = input.read(buffer);[/b]
- if (n <= 0)
- break ;
- output.write(buffer, 0, n);
- }
- } finally {
- if (output != null ) {
- try {
- output.close();
- } catch ( IOException e) {
- // Ignore
- }
- }
- }
- }
- }