Summary: | output="nul" no longer works | ||
---|---|---|---|
Product: | Ant | Reporter: | Roedy Green <roedyg> |
Component: | Core tasks | Assignee: | 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
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? 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? (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. 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?
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) Hello George, Would you be able to share that build file which reproduces this issue on Windows? 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. <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)
Windows 10 (Professional 20H2) that is Thank you Stefan for that example. Let me try and reproduce this on a system where I can try a few things. 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). 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. 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. 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. > 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 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. |