private boolean failOnMissingClasses = true;
private boolean ignoreEmptyFileset = false;
@Override
public void execute() throws BuildException {
AntClassLoader antLoader = null;
try {
final ClassLoader loader;
if (classpath != null) {
classpath.setProject(getProject());
loader = antLoader = getProject().createClassLoader(ClassLoader.getSystemClassLoader(), classpath);
antLoader.setParentFirst(true); // use default classloader delegation
} else {
loader = ClassLoader.getSystemClassLoader();
}
classFiles.setProject(getProject());
apiSignatures.setProject(getProject());
final Checker checker = new Checker(loader, internalRuntimeForbidden, failOnMissingClasses, true) {
@Override
protected void logError(String msg) {
log(msg, Project.MSG_ERR);
}
@Override
protected void logWarn(String msg) {
// ANT has no real log levels printed, so prefix with "WARNING":
log("WARNING: " + msg, Project.MSG_WARN);
}
@Override
protected void logInfo(String msg) {
log(msg, Project.MSG_INFO);
}
};
if (!checker.isSupportedJDK) {
final String msg = String.format(Locale.ENGLISH,
"Your Java runtime (%s %s) is not supported by <%s/>. Please run the checks with a supported JDK!",
System.getProperty("java.runtime.name"), System.getProperty("java.runtime.version"), getTaskName());
if (failOnUnsupportedJava) {
throw new BuildException(msg);
} else {
log("WARNING: " + msg, Project.MSG_WARN);
return;
}
}
try {
for (BundledSignaturesType bs : bundledSignatures) {
final String name = bs.getName();
if (name == null) {
throw new BuildException("<bundledSignatures/> must have the mandatory attribute 'name' referring to a bundled signatures file.");
}
log("Reading bundled API signatures: " + name, Project.MSG_INFO);
checker.parseBundledSignatures(name, null);
}
@SuppressWarnings("unchecked")
final Iterator<Resource> iter = (Iterator<Resource>) apiSignatures.iterator();
while (iter.hasNext()) {
final Resource r = iter.next();
if (r instanceof StringResource) {
final String s = ((StringResource) r).getValue();
if (s != null && s.trim().length() > 0) {
log("Reading inline API signatures...", Project.MSG_INFO);
checker.parseSignaturesString(s);
}
} else {
log("Reading API signatures: " + r, Project.MSG_INFO);
checker.parseSignaturesFile(r.getInputStream());
}
}
} catch (IOException ioe) {
throw new BuildException("IO problem while reading files with API signatures: " + ioe);
} catch (ParseException pe) {
throw new BuildException("Parsing signatures failed: " + pe.getMessage());
}
if (checker.hasNoSignatures()) {
throw new BuildException("No API signatures found; use signaturesFile=, <signaturesFileSet/>, <bundledSignatures/> or inner text to define those!");
}
log("Loading classes to check...", Project.MSG_INFO);
try {
@SuppressWarnings("unchecked")
final Iterator<Resource> iter = (Iterator<Resource>) classFiles.iterator();
boolean foundClass = false;
while (iter.hasNext()) {
final Resource r = iter.next();
final String name = r.getName();
if (restrictClassFilename && name != null && !name.endsWith(".class")) {
continue;
}
checker.addClassToCheck(r.getInputStream());
foundClass = true;
}
if (!foundClass) {
if (ignoreEmptyFileset) {
log("There is no <fileset/> or other resource collection given, or the collection does not contain any class files to check.", Project.MSG_WARN);
log("Scanned 0 class files.", Project.MSG_INFO);
return;
} else {
throw new BuildException("There is no <fileset/> or other resource collection given, or the collection does not contain any class files to check.");
}
}
} catch (IOException ioe) {
throw new BuildException("Failed to load one of the given class files: " + ioe);
}
log("Scanning for API signatures and dependencies...", Project.MSG_INFO);
try {
checker.run();
} catch (ForbiddenApiException fae) {
throw new BuildException(fae.getMessage());
}
} finally {
if (antLoader != null) antLoader.cleanup();
}
}