https://issues.apache.org/bugzilla/show_bug.cgi?id=51985
Bug #: 51985
Summary: System.out.print is adding an extra line feed when
flushed as a result of a System.in.readLine() call
Product: Ant
Version: 1.8.2
Platform: PC
Status: NEW
Severity: normal
Priority: P2
Component: Core
AssignedTo: [email protected]
ReportedBy: [email protected]
Classification: Unclassified
Here's a custom task definition that asks the user to input their name and then
dupes it back:
package com.runamok.tools.taskdefs;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
*
*/
public class ConfirmInputTask extends Task
{
private BufferedReader _in = new BufferedReader( new InputStreamReader(
System.in ) );
public void execute() throws BuildException
{
System.out.print("Enter your name:");
try
{
String name = _in.readLine();
System.out.println("You entered: " + name);
}
catch (IOException e)
{
log(e, Project.MSG_ERR);
}
}
}
The expected behavior is as follows:
C:\niku\main.next\tools>ant -f test-confirm.xml build
Buildfile: C:\niku\main.next\tools\test-confirm.xml
build:
Enter your name:test
You entered: test
BUILD SUCCESSFUL
Total time: 2 seconds
C:\niku\main.next\tools>
The actual behavior is:
C:\niku\main.next\tools>ant -f test-confirm.xml build
Buildfile: C:\niku\main.next\tools\test-confirm.xml
build:
Enter your name:
test
You entered: test
BUILD SUCCESSFUL
Total time: 2 seconds
C:\niku\main.next\tools>
The DemuxOutputStream class that ANT uses to take over System.out appears to do
a println() when it is called to flush the buffer as a result of the
DemuxInputStream readLine() call.
If I remove the two lines in org.apache.tools.ant.Main.runBuild() that override
System.out and System.err I get the expected behavior (see commented out lines
below)
private void runBuild(ClassLoader coreLoader) throws BuildException {
if (!readyToRun) {
return;
}
final Project project = new Project();
project.setCoreLoader(coreLoader);
Throwable error = null;
try {
addBuildListeners(project);
addInputHandler(project);
PrintStream savedErr = System.err;
PrintStream savedOut = System.out;
InputStream savedIn = System.in;
// use a system manager that prevents from System.exit()
SecurityManager oldsm = null;
oldsm = System.getSecurityManager();
//SecurityManager can not be installed here for backwards
//compatibility reasons (PD). Needs to be loaded prior to
//ant class if we are going to implement it.
//System.setSecurityManager(new NoExitSecurityManager());
try {
if (allowInput) {
project.setDefaultInputStream(System.in);
}
System.setIn(new DemuxInputStream(project));
// SA System.setOut(new PrintStream(new
DemuxOutputStream(project, false)));
// SA System.setErr(new PrintStream(new
DemuxOutputStream(project, true)));
if (!projectHelp) {
project.fireBuildStarted();
}
// set the thread priorities
if (threadPriority != null) {
try {
project.log("Setting Ant's thread priority to "
+ threadPriority, Project.MSG_VERBOSE);
Thread.currentThread().setPriority(threadPriority.intValue());
} catch (SecurityException swallowed) {
//we cannot set the priority here.
project.log("A security manager refused to set the
-nice value");
}
}
project.init();
// resolve properties
PropertyHelper propertyHelper
= (PropertyHelper)
PropertyHelper.getPropertyHelper(project);
HashMap props = new HashMap(definedProps);
new ResolvePropertyMap(project, propertyHelper,
propertyHelper.getExpanders())
.resolveAllProperties(props, null, false);
// set user-define properties
for (Iterator e = props.entrySet().iterator(); e.hasNext(); ) {
Map.Entry ent = (Map.Entry) e.next();
String arg = (String) ent.getKey();
Object value = ent.getValue();
project.setInheritedProperty(arg, String.valueOf(value));
}
project.setInheritedProperty(MagicNames.ANT_FILE,
buildFile.getAbsolutePath());
project.setInheritedProperty(MagicNames.ANT_FILE_TYPE,
MagicNames.ANT_FILE_TYPE_FILE);
project.setKeepGoingMode(keepGoingMode);
if (proxy) {
//proxy setup if enabled
ProxySetup proxySetup = new ProxySetup(project);
proxySetup.enableProxies();
}
ProjectHelper.configureProject(project, buildFile);
if (projectHelp) {
printDescription(project);
printTargets(project, msgOutputLevel > Project.MSG_INFO,
msgOutputLevel > Project.MSG_VERBOSE);
return;
}
// make sure that we have a target to execute
if (targets.size() == 0) {
if (project.getDefaultTarget() != null) {
targets.addElement(project.getDefaultTarget());
}
}
project.executeTargets(targets);
} finally {
// put back the original security manager
//The following will never eval to true. (PD)
if (oldsm != null) {
System.setSecurityManager(oldsm);
}
System.setOut(savedOut);
System.setErr(savedErr);
System.setIn(savedIn);
}
} catch (RuntimeException exc) {
error = exc;
throw exc;
} catch (Error e) {
error = e;
throw e;
} finally {
if (!projectHelp) {
try {
project.fireBuildFinished(error);
} catch (Throwable t) {
// yes, I know it is bad style to catch Throwable,
// but if we don't, we lose valuable information
System.err.println("Caught an exception while logging the"
+ " end of the build. Exception was:");
t.printStackTrace();
if (error != null) {
System.err.println("There has been an error prior to"
+ " that:");
error.printStackTrace();
}
throw new BuildException(t);
}
} else if (error != null) {
project.log(error.toString(), Project.MSG_ERR);
}
}
}
--
Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.