terminate with a build exception before entering an infinte loop PR: 14863 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274103 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -336,6 +336,14 @@ If you wish to attach a listener from the command line you may use the | |||||
| <p>will run Ant with a listener that generates an XML representation of the build progress. This | <p>will run Ant with a listener that generates an XML representation of the build progress. This | ||||
| listener is included with Ant, as is the default listener, which generates the logging to standard output.</p> | listener is included with Ant, as is the default listener, which generates the logging to standard output.</p> | ||||
| <p><b>Note: </b>A listener must not access System.out and System.err directly since ouput on | |||||
| these streams is redirected by Ant's core to the build event system. Accessing these | |||||
| streams can cause an infinite loop in Ant. Depending on the version of Ant, this will | |||||
| either cause the build to terminate or the Java VM to run out of Stack space. A logger, also, may | |||||
| not access System.out and System.err directly. It must use the streams with which it has | |||||
| been configured. | |||||
| </p> | |||||
| <hr> | <hr> | ||||
| <h2><a name="integration">Source code integration</a></h2> | <h2><a name="integration">Source code integration</a></h2> | ||||
| @@ -253,6 +253,11 @@ public class Project { | |||||
| /** Instance of a utility class to use for file operations. */ | /** Instance of a utility class to use for file operations. */ | ||||
| private FileUtils fileUtils; | private FileUtils fileUtils; | ||||
| /** | |||||
| * Flag which catches Listeners which try to use System.out or System.err | |||||
| */ | |||||
| private boolean loggingMessage = false; | |||||
| /** | /** | ||||
| * Creates a new Ant project. | * Creates a new Ant project. | ||||
| */ | */ | ||||
| @@ -2055,9 +2060,18 @@ public class Project { | |||||
| int priority) { | int priority) { | ||||
| event.setMessage(message, priority); | event.setMessage(message, priority); | ||||
| Vector listeners = getBuildListeners(); | Vector listeners = getBuildListeners(); | ||||
| for (int i = 0; i < listeners.size(); i++) { | |||||
| BuildListener listener = (BuildListener) listeners.elementAt(i); | |||||
| listener.messageLogged(event); | |||||
| synchronized(this) { | |||||
| if (loggingMessage) { | |||||
| throw new BuildException("Listener attempted to access " | |||||
| + (priority == MSG_ERR ? "System.err" : "System.out") | |||||
| + " - infinite loop terminated"); | |||||
| } | |||||
| loggingMessage = true; | |||||
| for (int i = 0; i < listeners.size(); i++) { | |||||
| BuildListener listener = (BuildListener) listeners.elementAt(i); | |||||
| listener.messageLogged(event); | |||||
| } | |||||
| loggingMessage = false; | |||||
| } | } | ||||
| } | } | ||||