Bug 62330

Summary: output="nul" no longer works
Product: Ant Reporter: Roedy Green <roedyg>
Component: Core tasksAssignee: Ant Notifications List <notifications>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 1.10.3   
Target Milestone: 1.10.10   
Hardware: PC   
OS: All   

Description Roedy Green 2018-04-26 12:50:07 UTC
<exec executable="jarlook.exe" dir="com/mindprod/batik" output="nul">
no longer works.  In 1.10.1 it would work, as would output="nul:".

When I try it I get the following error message
BUILD FAILED
E:\com\mindprod\batik\build.xml:93: Execute failed: java.nio.file.FileSystemExce
ption: E:\nul: Incorrect function.
Comment 1 Jaikiran Pai 2018-04-27 06:24:35 UTC
Hi Roedy,

I can't seem to find any documentation which states that this was supported or what "nul" or "nul:" is meant to do. Is there some reference you can point me to, so that I can see what changed?
Comment 2 Stefan Bodewig 2018-04-27 07:08:29 UTC
most likely this is referring to the nul device on Windows. NUL: on DOS (and CP/M) was what is /dev/null on Unix-likes, I think Windows renamed it to nul without the colon, but may be wrong.

See https://en.wikipedia.org/wiki/Device_file#DOS,_TOS,_OS/2,_and_Windows

This looks as if we didn't try to resolve output's file name before 1.10.2. Maybe the file name resolution logic in FileUtils needs to special case "nul" and "nul:" on Windows (and with it "CON:", "PRN:", "COM1:" and some other things - yes, I am old ;-).

@Roedy if "discard the output" is what you want, can you use outputproperty as a workaround?
Comment 3 Roedy Green 2018-04-27 12:46:01 UTC
(In reply to Jaikiran Pai from comment #1)
> Hi Roedy,
> 
> I can't seem to find any documentation which states that this was supported
> or what "nul" or "nul:" is meant to do. Is there some reference you can
> point me to, so that I can see what changed?

="null" used to simply discard output.  In Windows, you can say >null on the commmand line discard System.out output or >somefile.txt to redirect it.  Null is a magic filename.
Comment 4 Jaikiran Pai 2018-05-01 06:02:10 UTC
Thanks Stefan, for those details. Although I did suspect it was something along the lines of /dev/null I wasn't aware that Windows literally uses "nul" or "nul:" to represent that.

>> Maybe the file name resolution logic in FileUtils needs to special case "nul" and "nul:" on Windows

I'm starting to wonder, given that this is a OS (filesystem) level construct, this probably should have been supported by the java.nio.file.Files/Path API which I guess is throwing this exception. 


@Roedy, can you paste the complete stacktrace (if needed, enable debug for the Ant build)? Also, does the workaround that Stefan mentioned work for you?
Comment 5 George Thomas 2021-03-14 04:48:21 UTC
We had encountered this after upgrading to Ant 1.10.5 from 1.10.1 and after some further investigation I confirmed that this had first broken in 1.10.2.

Here's a stacktrace from a simple build file I had written to reproduce this problem after we had encountered it:

        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
        at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
        at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434)
        at java.nio.file.Files.newOutputStream(Files.java:216)
        at org.apache.tools.ant.util.FileUtils.newOutputStream(FileUtils.java:1728)
        at org.apache.tools.ant.util.LazyFileOutputStream.ensureOpened(LazyFileOutputStream.java:162)
        at org.apache.tools.ant.util.LazyFileOutputStream.close(LazyFileOutputStream.java:113)
        at org.apache.tools.ant.taskdefs.Redirector.complete(Redirector.java:938)
        at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:642)
        at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:670)
        at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:498)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:346)
        at org.apache.tools.ant.Target.execute(Target.java:448)
        at org.apache.tools.ant.Target.performTasks(Target.java:469)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1370)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1260)
        at org.apache.tools.ant.Main.runBuild(Main.java:849)
        at org.apache.tools.ant.Main.startAnt(Main.java:228)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:283)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:101)
Comment 6 Jaikiran Pai 2021-03-16 06:46:43 UTC
Hello George,

Would you be able to share that build file which reproduces this issue on Windows?
Comment 7 Jaikiran Pai 2021-03-18 13:04:07 UTC
If anyone of you would be able to provide the build script to reproduce this, please also include the version and vendor of Java with which it was reproduced and also the version of Windows OS in use.
Comment 8 Stefan Bodewig 2021-03-19 16:53:53 UTC
<project>
  <exec executable="java.exe" output="nul"/>
</project>

> java -fullversion
openjdk full version "1.8.0_265-b01"

I can try a different JDK, if you want.

Stacktrace starts with

C:\Users\Stefan Bodewig\ant\test.xml:2: Execute failed: java.nio.file.FileSystemException: C:\Users\Stefan Bodewig\ant\nul: Incorrect function.

        at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
        at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
        at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
        at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434)
        at java.nio.file.Files.newOutputStream(Files.java:216)
        at org.apache.tools.ant.util.LazyFileOutputStream.ensureOpened(LazyFileOutputStream.java:162)
Comment 9 Stefan Bodewig 2021-03-19 16:54:44 UTC
Windows 10 (Professional 20H2) that is
Comment 10 Jaikiran Pai 2021-03-20 03:13:24 UTC
Thank you Stefan for that example. Let me try and reproduce this on a system where I can try a few things.
Comment 11 Jaikiran Pai 2021-03-20 10:30:10 UTC
Thank you Stefan for that example. My earlier numerous experiments to get this reproduced on Windows hadn't been productive because I kept assuming "append" to be true in the code at https://github.com/apache/ant/blob/master/src/main/org/apache/tools/ant/util/FileUtils.java#L1856 and tried to replicate that in a simple application. Now that you provided this example, I managed to reproduce this and it turns out to be a bug in Java with Files.newOutputStream(Path) API when the null device is involved in Windows. I've filed https://bugs.openjdk.java.net/browse/JDK-8263898 to track this.


While we are at this, there's some useful additional information about null device usage on Windows in this mailing list discussion here https://mail.openjdk.java.net/pipermail/core-libs-dev/2021-March/075386.html, specifically the java.nio.file.Path API won't support the "nul:" (colon construct).
Comment 12 Stefan Bodewig 2021-03-20 11:06:26 UTC
Great, thanks.

As indicated on the mailing list I'd like to solve the underlying issue in a different way (make it possible to discard output using new attributes rather than null devices).

I'm not sure we really can reasonably work around the issue if it is a JDK problem. We could check the file size and omit TRUNC_EXISTING (i.e. asking for WRITE only) for existing zero length files if I understand Alan's comment to your JDK issue correctly.
Comment 13 Jaikiran Pai 2021-03-20 12:36:27 UTC
Hello Stefan,

> We could check the file size and omit TRUNC_EXISTING (i.e. asking for WRITE only) for existing zero length files if I understand Alan's comment to your JDK issue correctly.

Alan's comment is meant for the JDK developers and not us (the users of the API). He mentions it in the context of the JDK internal implementation code.

> As indicated on the mailing list I'd like to solve the underlying issue in a different way (make it possible to discard output using new attributes rather than null devices).

> I'm not sure we really can reasonably work around the issue if it is a JDK problem.

I think we should solve it the way you mentioned in our recent Ant dev mailing list discussion, instead of trying any workaround. The additional advantage of going with your approach, discussed in the Ant dev mailing list, is that it will be platform agnostic and users won't have to use platform specific null device identifiers.
Comment 14 Stefan Bodewig 2021-03-20 13:21:15 UTC
I know Alan's comment was meant for the JDK developers, but it could provide a workaround for us as well.

In either case, using the new "discard" option I'm about to add this weekend seems to be the way to go anyway.
Comment 15 Jaikiran Pai 2021-05-16 03:51:26 UTC
> I've filed https://bugs.openjdk.java.net/browse/JDK-8263898 to track this.

The issue in the JDK has been fixed and available in a early access release of JDK 17.

Additionally, in our recently released Ant 1.10.10 we now have new "discardOutput" and "discardError" attributes which are the recommended way to discard any output and/or error generated by the launched programs. More details is available in the tasks' manual like the exec task https://ant.apache.org/manual/Tasks/exec.html
Comment 16 Jaikiran Pai 2021-08-13 06:50:57 UTC
Marking this as resolved, since starting 1.10.10 of Ant we now have explicit "discardError" and "discardOutput" attributes which is the recommended way instead of using "nul" to redirect the output/error.