We may want to have an attribute to indicate that a web.xml file is needed, or that we dont want to see the warning message. Say nowebxml="fail", "warn" or "skip", with the default being fail for backwards compatibility. Thoughts? Now is the time to add it... git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@468180 13f79535-47bb-0310-9956-ffa450edef68master
@@ -33,7 +33,20 @@ treatment for files that should end up in the | |||
<p>(The War task is a shortcut for specifying the particular layout of a WAR file. | |||
The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i> | |||
attributes of zipfilesets in a Zip or Jar task.)</p> | |||
<p>The extended zipfileset element from the zip task (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>) is available in the War task.</p> | |||
<p>The extended zipfileset element from the zip task | |||
(with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>) | |||
is available in the War task. The task is also resource-enabled | |||
and will add nested resources and resource collections to the archive.</p> | |||
<p> | |||
Before Servlet API 2.5/Java EE 5, a WEB-INF/web.xml file was mandatory in a | |||
WAR file, so this task failed if the <code>webxml</code> attribute was missing. | |||
As the web.xml file is now optional, the <code>webxml</code> attribute is now | |||
downgraded to being optional. The task will warn if the file is not | |||
included as an attribute or in a fileset, but still succeed. The task | |||
will also complain if more than one web.xml file is added to the JAR. | |||
</p> | |||
<p><b>Please note that the zip format allows multiple files of the same | |||
fully-qualified name to exist within a single archive. This has been | |||
@@ -55,13 +68,13 @@ to a value other than its default, <code>"add"</code>.</b></p> | |||
</tr> | |||
<tr> | |||
<td valign="top">warfile</td> | |||
<td valign="top"><i>Deprecated<i> name of the file to create | |||
<td valign="top"><i>Deprecated</i> name of the file to create | |||
-use <tt>destfile</tt> instead.</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">webxml</td> | |||
<td valign="top">The deployment descriptor to use (WEB-INF/web.xml).</td> | |||
<td valign="top" align="center">Yes, unless update is set to true</td> | |||
<td valign="top" align="center">No (since Ant1.7)</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">basedir</td> | |||
@@ -231,7 +244,7 @@ using Ant's default manifest file. The content of | |||
directory, and thus it is our fault your webapp doesn't work. The cause | |||
of these complaints lies in WinZip, which turns an all upper-case | |||
directory into an all lower case one in a fit of helpfulness. Please check that | |||
jar xvf yourwebapp.war shows the same behaviour before filing another | |||
<code>jar xvf yourwebapp.war</code> shows the same behaviour before filing another | |||
report.<br/> | |||
Winzip has an option allowing all uppercase names (which is off by default!). It can be enabled by: | |||
Menu "Options" -> "Configuration", "View" property/tab page, then "General" group box has an option called "Allow all uppercase file names". | |||
@@ -20,6 +20,7 @@ package org.apache.tools.ant.taskdefs; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Locale; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.types.ZipFileSet; | |||
@@ -55,8 +56,10 @@ public class War extends Jar { | |||
* flag set if the descriptor is added | |||
*/ | |||
private boolean descriptorAdded; | |||
private File addedWebXmlFile; | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
private static final String XML_DESCRIPTOR_PATH = "web-inf/web.xml"; | |||
/** Constructor for the War Task. */ | |||
public War() { | |||
@@ -93,7 +96,7 @@ public class War extends Jar { | |||
// Create a ZipFileSet for this file, and pass it up. | |||
ZipFileSet fs = new ZipFileSet(); | |||
fs.setFile(deploymentDescriptor); | |||
fs.setFullpath("WEB-INF/web.xml"); | |||
fs.setFullpath(XML_DESCRIPTOR_PATH); | |||
super.addFileset(fs); | |||
} | |||
@@ -137,16 +140,18 @@ public class War extends Jar { | |||
*/ | |||
protected void initZipOutputStream(ZipOutputStream zOut) | |||
throws IOException, BuildException { | |||
// If no webxml file is specified, it's an error. | |||
if (deploymentDescriptor == null && !isInUpdateMode()) { | |||
throw new BuildException("webxml attribute is required", getLocation()); | |||
} | |||
super.initZipOutputStream(zOut); | |||
} | |||
/** | |||
* Overridden from Zip class to deal with web.xml | |||
* | |||
* Here are cases that can arise | |||
* -not a web.xml file : add | |||
* -first web.xml : add, remember we added it | |||
* -same web.xml again: skip | |||
* -alternate web.xml : warn and skip | |||
* | |||
* @param file the file to add to the archive | |||
* @param zOut the stream to write to | |||
* @param vPath the name this entry shall have in the archive | |||
@@ -160,29 +165,51 @@ public class War extends Jar { | |||
// not the one specified in the "webxml" attribute - or if | |||
// it's being added twice, meaning the same file is specified | |||
// by the "webxml" attribute and in a <fileset> element. | |||
if (vPath.equalsIgnoreCase("WEB-INF/web.xml")) { | |||
if (deploymentDescriptor == null | |||
|| !FILE_UTILS.fileNameEquals(deploymentDescriptor, file) | |||
|| descriptorAdded) { | |||
log("Warning: selected " + archiveType | |||
+ " files include a WEB-INF/web.xml which will be ignored " | |||
+ "(please use webxml attribute to " | |||
+ archiveType + " task)", Project.MSG_WARN); | |||
String vPathLowerCase = vPath.toLowerCase(Locale.ENGLISH); | |||
//by default, we add the file. | |||
boolean addFile = true; | |||
if (XML_DESCRIPTOR_PATH.equals(vPathLowerCase)) { | |||
//a web.xml file was found. See if it is a duplicate or not | |||
if (addedWebXmlFile != null) { | |||
//a second web.xml file, so skip it | |||
addFile = false; | |||
//check to see if we warn or not | |||
if (!FILE_UTILS.fileNameEquals(addedWebXmlFile, file)) { | |||
log("Warning: selected " + archiveType | |||
+" files include a second " +XML_DESCRIPTOR_PATH | |||
+ " which will be ignored.\n" | |||
+ "The duplicate entry is at " +file +'\n' | |||
+ "The file that will be used is " | |||
+ addedWebXmlFile, | |||
Project.MSG_WARN); | |||
} | |||
} else { | |||
super.zipFile(file, zOut, vPath, mode); | |||
//no added file, yet | |||
addedWebXmlFile=file; | |||
//there is no web.xml file, so add it | |||
addFile = true; | |||
//and remember that we did | |||
descriptorAdded = true; | |||
deploymentDescriptor = file; | |||
} | |||
} else { | |||
} | |||
if (addFile) { | |||
super.zipFile(file, zOut, vPath, mode); | |||
} | |||
} | |||
/** | |||
* Make sure we don't think we already have a web.xml next time this task | |||
* gets executed. | |||
*/ | |||
protected void cleanUp() { | |||
descriptorAdded = false; | |||
if(addedWebXmlFile==null) { | |||
log("No WEB-INF/web.xml file was added.\n" | |||
+"This WAR file is only valid on Java EE 5+ runtimes\n" | |||
+"and web servers that support v2.5 Web Applications"); | |||
} | |||
addedWebXmlFile = null; | |||
super.cleanUp(); | |||
} | |||
} |
@@ -0,0 +1,113 @@ | |||
<?xml version="1.0"?> | |||
<project name="war-test" basedir="." default="all" | |||
xmlns:au="antlib:org.apache.ant.antunit"> | |||
<property name="working.dir" value="working"/> | |||
<target name="all"> | |||
<au:antunit> | |||
<fileset file="${ant.file}"/> | |||
<au:plainlistener/> | |||
</au:antunit> | |||
</target> | |||
<target name="init"> | |||
<delete dir="${working.dir}"/> | |||
<mkdir dir="${working.dir}"/> | |||
<property name="warfile" location="${working.dir}/test.war"/> | |||
<property name="web.xml" location="web.xml"/> | |||
<property name="webxml.generated" location="${working.dir}/WEB-INF/web.xml"/> | |||
<!--failing on duplicates is half our testing--> | |||
<presetdef name="mkwar"> | |||
<war destfile="${warfile}" duplicate="fail"/> | |||
</presetdef> | |||
<presetdef name="expandwar"> | |||
<unzip src="${working.dir}/test.war" dest="${working.dir}"/> | |||
</presetdef> | |||
</target> | |||
<target name="tearDown"> | |||
<delete dir="${working.dir}"/> | |||
</target> | |||
<!--test that you can patch a fileset reference into a lib element--> | |||
<target name="testlibrefs" depends="init"> | |||
<mkwar webxml="${web.xml}"> | |||
<fileset id="test" dir="." includes="web.xml"/> | |||
<lib refid="test"/> | |||
</mkwar> | |||
<expandwar/> | |||
<au:assertFileExists file="${webxml.generated}" /> | |||
</target> | |||
<!-- | |||
This checks that as of Java EE 5, the web.xml attr is optional. | |||
Here there is a web.xml, in the webinf fileset, rather than a fileset | |||
--> | |||
<target name="testWebXmlInWebinf" depends="init"> | |||
<mkwar> | |||
<webinf dir="." includes="web.xml"/> | |||
</mkwar> | |||
<expandwar/> | |||
<au:assertFileExists file="${webxml.generated}" /> | |||
</target> | |||
<target name="testDuplicateWebXml" depends="init"> | |||
<mkwar webxml="${web.xml}" > | |||
<webinf dir="." includes="web.xml"/> | |||
<webinf file="${web.xml}"/> | |||
<zipfileset file="${web.xml}" prefix="WEB-INF"/> | |||
</mkwar> | |||
<expandwar/> | |||
<au:assertFileExists file="${webxml.generated}" /> | |||
</target> | |||
<target name="testDifferentDuplicateWebXml" depends="init"> | |||
<copy file="${web.xml}" todir="${working.dir}" /> | |||
<mkwar webxml="${web.xml}" > | |||
<webinf dir="${working.dir}" includes="web.xml"/> | |||
<webinf file="${web.xml}"/> | |||
<zipfileset file="${web.xml}" prefix="WEB-INF"/> | |||
</mkwar> | |||
<expandwar/> | |||
<au:assertFileExists file="${webxml.generated}" /> | |||
<au:assertLogContains text="The duplicate entry is"/> | |||
</target> | |||
<!-- | |||
this target does not have a web.xml file. | |||
Instead it pulls in | |||
--> | |||
<target name="testWebXmlOptional" depends="init"> | |||
<mkwar > | |||
<classes dir="." includes="web.xml"/> | |||
</mkwar> | |||
<expandwar/> | |||
<au:assertFileExists file="${working.dir}/WEB-INF/classes/web.xml" /> | |||
<au:assertFalse> | |||
<available file="${webxml.generated}" /> | |||
</au:assertFalse> | |||
<au:assertLogContains text="This WAR file is only valid on Java EE 5+ runtimes"/> | |||
</target> | |||
<target name="testClassesElement" depends="init"> | |||
<mkwar > | |||
<classes dir="." includes="web.xml"/> | |||
</mkwar> | |||
<expandwar/> | |||
<au:assertFileExists file="${working.dir}/WEB-INF/classes/web.xml" /> | |||
</target> | |||
<target name="testLibElement" depends="init"> | |||
<mkwar > | |||
<lib dir="." includes="web.xml"/> | |||
</mkwar> | |||
<expandwar/> | |||
<au:assertFileExists file="${working.dir}/WEB-INF/lib/web.xml" /> | |||
</target> | |||
</project> |
@@ -0,0 +1,5 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<web-app xmlns="http://java.sun.com/xml/ns/javaee" | |||
version="2.5" metadata-complete="true"> | |||
</web-app> |