diff --git a/src/main/org/apache/tools/ant/taskdefs/Copy.java b/src/main/org/apache/tools/ant/taskdefs/Copy.java index 477792e72..c4a112b70 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Copy.java +++ b/src/main/org/apache/tools/ant/taskdefs/Copy.java @@ -788,6 +788,9 @@ public class Copy extends Task { for (int i = 0; i < toCopy.length; i++) { final File src = new File(fromDir, toCopy[i]); final String[] mappedFiles = mapper.mapFileName(toCopy[i]); + if (mappedFiles == null || mappedFiles.length == 0) { + continue; + } if (!enableMultipleMappings) { map.put(src.getAbsolutePath(), @@ -831,7 +834,7 @@ public class Copy extends Task { } for (int i = 0; i < toCopy.length; i++) { final String[] mappedFiles = mapper.mapFileName(toCopy[i].getName()); - if (mappedFiles == null) { + if (mappedFiles == null || mappedFiles.length == 0) { throw new BuildException("Can't copy a resource without a" + " name if the mapper doesn't" + " provide one."); diff --git a/src/main/org/apache/tools/ant/taskdefs/CopyPath.java b/src/main/org/apache/tools/ant/taskdefs/CopyPath.java index 53596fd98..bad9e5d93 100644 --- a/src/main/org/apache/tools/ant/taskdefs/CopyPath.java +++ b/src/main/org/apache/tools/ant/taskdefs/CopyPath.java @@ -182,6 +182,9 @@ public class CopyPath extends Task { String sourceFileName = sourceFiles[sources]; File sourceFile = new File(sourceFileName); String[] toFiles = (String[]) mapper.mapFileName(sourceFileName); + if (toFiles == null) { + continue; + } for (int i = 0; i < toFiles.length; i++) { String destFileName = toFiles[i]; diff --git a/src/main/org/apache/tools/ant/taskdefs/Rmic.java b/src/main/org/apache/tools/ant/taskdefs/Rmic.java index c42ad419c..aa762b188 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Rmic.java +++ b/src/main/org/apache/tools/ant/taskdefs/Rmic.java @@ -705,6 +705,9 @@ public class Rmic extends MatchingTask { String classFileName = classname.replace('.', File.separatorChar) + ".class"; String[] generatedFiles = adapter.getMapper().mapFileName(classFileName); + if (generatedFiles == null) { + return; + } for (String generatedFile : generatedFiles) { if (!generatedFile.endsWith(".class")) { diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java index 2c7e9de78..b50674cf1 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java @@ -256,7 +256,10 @@ public class Native2Ascii extends MatchingTask { + (count != 1 ? "s" : "") + " from "; log(message + srcDir + " to " + destDir); for (int i = 0; i < files.length; i++) { - convert(files[i], m.mapFileName(files[i])[0]); + String[] dest = m.mapFileName(files[i]); + if (dest != null && dest.length > 0) { + convert(files[i], dest[0]); + } } } diff --git a/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java b/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java index 052a0379e..1b9839181 100644 --- a/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java +++ b/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java @@ -66,6 +66,9 @@ public class CutDirsMapper implements FileNameMapper { throw new BuildException("dirs must be set to a positive number"); } final char fileSep = File.separatorChar; + if (sourceFileName == null) { + return null; + } final String fileSepCorrected = sourceFileName.replace('/', fileSep).replace('\\', fileSep); int nthMatch = fileSepCorrected.indexOf(fileSep); diff --git a/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java b/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java index b4c07e942..3a0109bb6 100644 --- a/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java +++ b/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java @@ -66,6 +66,9 @@ public class FilterMapper extends FilterChain implements FileNameMapper { */ @Override public String[] mapFileName(String sourceFileName) { + if (sourceFileName == null) { + return null; + } try { Reader stringReader = new StringReader(sourceFileName); ChainReaderHelper helper = new ChainReaderHelper(); diff --git a/src/main/org/apache/tools/ant/util/ChainedMapper.java b/src/main/org/apache/tools/ant/util/ChainedMapper.java index 8b3e32f76..cec4f2e48 100644 --- a/src/main/org/apache/tools/ant/util/ChainedMapper.java +++ b/src/main/org/apache/tools/ant/util/ChainedMapper.java @@ -32,6 +32,9 @@ public class ChainedMapper extends ContainerMapper { /** {@inheritDoc}. */ @Override public String[] mapFileName(String sourceFileName) { + // we invoke the chain even if the sourceFileName is null. Some + // resources have a null name and users may use a mapper like + // MergeMapper to provide a name for it. String[] result = getMappers().stream() .reduce(new String[] { sourceFileName }, (i, m) -> Stream.of(i) .map(m::mapFileName).filter(Objects::nonNull).flatMap(Stream::of).toArray(String[]::new), diff --git a/src/main/org/apache/tools/ant/util/FileNameMapper.java b/src/main/org/apache/tools/ant/util/FileNameMapper.java index bbd826141..ec85f9d5d 100644 --- a/src/main/org/apache/tools/ant/util/FileNameMapper.java +++ b/src/main/org/apache/tools/ant/util/FileNameMapper.java @@ -52,7 +52,9 @@ public interface FileNameMapper { * omit the source file in question.

* * @param sourceFileName the name of the source file relative to - * some given basedirectory. + * some given basedirectory. Might be {@code + * null} for resources that don't provide a + * name. * @return an array of strings if the rule applies to the source file, or * null if it does not. */ diff --git a/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java b/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java index 8465c7869..37383b631 100644 --- a/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java +++ b/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java @@ -53,5 +53,7 @@ public class FlatFileNameMapper implements FileNameMapper { @Override public String[] mapFileName(String sourceFileName) { return new String[] { new java.io.File(sourceFileName).getName() }; + return sourceFileName == null ? null + : new String[] {new java.io.File(sourceFileName).getName()}; } } diff --git a/src/main/org/apache/tools/ant/util/GlobPatternMapper.java b/src/main/org/apache/tools/ant/util/GlobPatternMapper.java index 8e470ac8d..63a8f36e0 100644 --- a/src/main/org/apache/tools/ant/util/GlobPatternMapper.java +++ b/src/main/org/apache/tools/ant/util/GlobPatternMapper.java @@ -155,6 +155,9 @@ public class GlobPatternMapper implements FileNameMapper { */ @Override public String[] mapFileName(String sourceFileName) { + if (sourceFileName == null) { + return null; + } String modName = modifyName(sourceFileName); if (fromPrefix == null || (sourceFileName.length() < (prefixLength + postfixLength)) diff --git a/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java b/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java index 82bc109db..495a644b9 100644 --- a/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java +++ b/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java @@ -115,6 +115,9 @@ public class RegexpPatternMapper implements FileNameMapper { */ @Override public String[] mapFileName(String sourceFileName) { + if (sourceFileName == null) { + return null; + } if (handleDirSep) { if (sourceFileName.indexOf("\\") != -1) { sourceFileName = sourceFileName.replace('\\', '/');