I have a trivial question for all of you. I have several build.xml files that compiles hundreds of classes, and whenever I run the build a log file is saved on the server.
Now so far so good, if for example anything fails I can go through the log files... BUT sometime I am faced with many errors, thus scanning through the log file is painful.
I wanted to know if it is possible to say to ant (even at run time) or through the javac task if it is possible to give a list of classes that failed to compile (I do not mean the all error stack but just a list of classes that failed)
--- Edited to include concrete example ---
This example should give you a major head start in logging. Remember you must add it to your CLASSPATH prior to invoking ant. If possible, add it to only the CLASSPATH that your copy of ant uses, but wrapping the normal ANT call in a script that sets the CLASSPATH and then calls ANT.
Then run ant with this logger like so
ant -logger com.edwinbuck.JavacFileLogger
and the following code will produce a list of files that didn't compile. It makes a number of assumptions (some good, some that might use improvement).
You will likely have to modify the following code to open a file and write to it, as you see fit.
package com.edwinbuck;
import java.io.PrintStream;
import java.util.HashSet;
import java.util.Set;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.util.StringUtils;
public class JavacFileLogger implements BuildLogger {
protected PrintStream out;
protected PrintStream err;
protected static final String eol = StringUtils.LINE_SEP;
private Set<String> errorFiles = new HashSet<String>();
private boolean ignoringMessages = true;
public void buildStarted(BuildEvent event) {
}
public void buildFinished(BuildEvent event) {
}
public void targetStarted(BuildEvent event) {
}
public void targetFinished(BuildEvent event) {
}
public void taskStarted(BuildEvent event) {
if (event.getTask().getTaskName().equals("javac")) {
ignoringMessages = false;
}
}
public void taskFinished(BuildEvent event) {
if (event.getTask().getTaskName().equals("javac")) {
ignoringMessages = true;
// flush the set of files with errors
for (String filename : errorFiles) {
out.print(filename);
out.print(eol);
}
}
}
public void messageLogged(BuildEvent event) {
// we don't care about non-javac messages
if (!ignoringMessages) {
// error messages have a distinct ".java:" in the line containing the file name.
if (event.getMessage().contains(".java:")) {
// just add the (string) name to the set to condense multiple reported errors in the same file
errorFiles.add(event.getMessage().substring(0, event.getMessage().indexOf(":")));
}
}
}
public void setErrorPrintStream(PrintStream err) {
this.err = err;
}
public void setEmacsMode(boolean emacsMode) {
}
public void setOutputPrintStream(PrintStream output) {
this.out = output;
}
public void setMessageOutputLevel(int level) {
// this logger ignores message levels
}
}
--- Original post follows ---
Depending on what you want to do, you probably need a custom Ant Listener or Logger.
If you want a Log file that only mentions the failed classes, you can add your own Logger to ant that waits for a javac
task and then captures the logging events, parses out the failed class names, and appends those to a file.
If you want that information internal to Ant, you can add a Listener which basically collects the necessary data and somehow makes it available to ANT (perhaps by defining a property).
Look to this page on custom Ant Loggers to get an idea, and take note of this posting to see how one listened for a specific task (javac in this case) to automatically run a different task (even when it wasn't specified in the build.xml file).