sbt-assembly
sbt-assembly copied to clipboard
Failure running assembly with ShadeRules inside Windows Subsystem for Linux (Ubuntu)
Steps:
git clone [email protected]:nivekastoreth/sbt-performance-project.git
cd sbt-performance-project
sbt clean assembly
Expected results:
Assembly jar is built.
Actual results:
Two scenarios, both similar.
- Shading claims file does not exist, file does exist
- Shading fails because the expected file is a directory
Notes:
- This same build works on the same physical drive / directory structure when run via cygwin or otherwise not in the WSL layer.
- I've attempted this using both
-Dsbt.io.jdktimestamps=false
and-Dsbt.io.jdktimestamps=true
, neither of which seems to have any real impact. - I've attempted this using
-Dsbt.version=1.1.0
and-Dsbt.version=1.1.6
with similar results - If I re-run
assembly
repeatedly without cleaning in between, it will eventually complete its run without failures - The file that is fails on is not consistent (in either scenario), nor is it a path length issue since other files with longer names exist in the same folder and the same file will succeed in a subsequent run
Scenario No. 1: Shading claims file does not exist, file does exist
jmaki@jmaki-pc /build/wsl/akashi
$ sbt -Dsbt.log.noformat=true clean assembly | tee sbt-assembly.log
[error] java.io.FileNotFoundException: /build/wsl/akashi/akashi-assembler/target/streams/$global/assemblyOption/$global/streams/assembly/d0da05e6b00b2d3451689652163711f0901137a8_487a90889a8cc17f04a2ab8a290882c255a32c44_dc564712cc91549a72808653b6df35683be7efbf/scalaz/EphemeralStream$$anonfun$findMapM$2.class (No such file or directory)
[error] at java.io.FileOutputStream.open0(Native Method)
[error] at java.io.FileOutputStream.open(FileOutputStream.java:270)
[error] at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
[error] at sbt.io.Using$.$anonfun$fileOutputStream$1(Using.scala:86)
[error] at sbt.io.Using$$anon$2.openImpl(Using.scala:76)
[error] at sbt.io.OpenFile.open(Using.scala:43)
[error] at sbt.io.OpenFile.open$(Using.scala:39)
[error] at sbt.io.Using$$anon$2.open(Using.scala:75)
[error] at sbt.io.Using$$anon$2.open(Using.scala:75)
[error] at sbt.io.Using.apply(Using.scala:21)
[error] at sbt.io.IO$.writeBytes(IO.scala:820)
[error] at sbt.io.IO$.write(IO.scala:817)
[error] at sbtassembly.Shader$.$anonfun$shadeDirectory$7(Shader.scala:103)
[error] at sbtassembly.Shader$.$anonfun$shadeDirectory$7$adapted(Shader.scala:97)
[error] at scala.collection.Iterator.foreach(Iterator.scala:944)
[error] at scala.collection.Iterator.foreach$(Iterator.scala:944)
[error] at scala.collection.AbstractIterator.foreach(Iterator.scala:1432)
[error] at scala.collection.IterableLike.foreach(IterableLike.scala:71)
[error] at scala.collection.IterableLike.foreach$(IterableLike.scala:70)
[error] at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
[error] at sbtassembly.Shader$.shadeDirectory(Shader.scala:97)
[error] at sbtassembly.Assembly$.$anonfun$assembleMappings$9(Assembly.scala:218)
[error] at scala.collection.parallel.AugmentedIterableIterator.map2combiner(RemainsIterator.scala:112)
[error] at scala.collection.parallel.AugmentedIterableIterator.map2combiner$(RemainsIterator.scala:109)
[error] at scala.collection.parallel.immutable.ParVector$ParVectorIterator.map2combiner(ParVector.scala:62)
[error] at scala.collection.parallel.ParIterableLike$Map.leaf(ParIterableLike.scala:1052)
[error] at scala.collection.parallel.Task.$anonfun$tryLeaf$1(Tasks.scala:49)
[error] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] at scala.util.control.Breaks$$anon$1.catchBreak(Breaks.scala:63)
[error] at scala.collection.parallel.Task.tryLeaf(Tasks.scala:52)
[error] at scala.collection.parallel.Task.tryLeaf$(Tasks.scala:46)
[error] at scala.collection.parallel.ParIterableLike$Map.tryLeaf(ParIterableLike.scala:1049)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.internal(Tasks.scala:166)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.internal$(Tasks.scala:153)
[error] at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.internal(Tasks.scala:436)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute(Tasks.scala:146)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute$(Tasks.scala:145)
[error] at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:436)
[error] at java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
[error] at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
[error] at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
[error] at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
[error] at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
[error] (assembler / assembly / assembledMappings) java.io.FileNotFoundException: /build/wsl/akashi/akashi-assembler/target/streams/$global/assemblyOption/$global/streams/assembly/d0da05e6b00b2d3451689652163711f0901137a8_487a90889a8cc17f04a2ab8a290882c255a32c44_dc564712cc91549a72808653b6df35683be7efbf/scalaz/EphemeralStream$$anonfun$findMapM$2.class (No such file or directory)
jmaki@jmaki-pc /build/wsl/akashi
$ grep 'EphemeralStream$$anonfun$findMapM$2.class' sbt-assembly.log -C 2
[debug] scalaz/EphemeralStream$$anonfun$findMapM$2$$anonfun$apply$10.class
[debug] /build/wsl/akashi/akashi-preprocessor/target/streams/$global/assemblyOption/$global/streams/assembly/d0da05e6b00b2d3451689652163711f0901137a8_487a90889a8cc17f04a2ab8a290882c255a32c44_dc564712cc91549a72808653b6df35683be7efbf/scalaz/EphemeralStream$$anonfun$findMapM$2$$anonfun$apply$10.class
[debug] scalaz/EphemeralStream$$anonfun$findMapM$2.class
[debug] /build/wsl/akashi/akashi-preprocessor/target/streams/$global/assemblyOption/$global/streams/assembly/d0da05e6b00b2d3451689652163711f0901137a8_487a90889a8cc17f04a2ab8a290882c255a32c44_dc564712cc91549a72808653b6df35683be7efbf/scalaz/EphemeralStream$$anonfun$findMapM$2.class
[debug] scalaz/EphemeralStream$$anonfun$flatMap$1.class
[debug] /build/wsl/akashi/akashi-preprocessor/target/streams/$global/assemblyOption/$global/streams/assembly/d0da05e6b00b2d3451689652163711f0901137a8_487a90889a8cc17f04a2ab8a290882c255a32c44_dc564712cc91549a72808653b6df35683be7efbf/scalaz/EphemeralStream$$anonfun$flatMap$1.class
--
[debug] Including: macro-compat_2.11-1.1.1.jar
[info] Done packaging.
[error] java.io.FileNotFoundException: /build/wsl/akashi/akashi-assembler/target/streams/$global/assemblyOption/$global/streams/assembly/d0da05e6b00b2d3451689652163711f0901137a8_487a90889a8cc17f04a2ab8a290882c255a32c44_dc564712cc91549a72808653b6df35683be7efbf/scalaz/EphemeralStream$$anonfun$findMapM$2.class (No such file or directory)
[error] at java.io.FileOutputStream.open0(Native Method)
[error] at java.io.FileOutputStream.open(FileOutputStream.java:270)
--
[error] at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
[error] at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
[error] (assembler / assembly / assembledMappings) java.io.FileNotFoundException: /build/wsl/akashi/akashi-assembler/target/streams/$global/assemblyOption/$global/streams/assembly/d0da05e6b00b2d3451689652163711f0901137a8_487a90889a8cc17f04a2ab8a290882c255a32c44_dc564712cc91549a72808653b6df35683be7efbf/scalaz/EphemeralStream$$anonfun$findMapM$2.class (No such file or directory)
[error] Total time: 272 s, completed Aug 2, 2018 8:36:56 PM
Scenario No. 2: Shading fails because the expected file is a directory
[error] java.io.FileNotFoundException: /build/wsl/akashi/akashi-assembler/target/streams/$global/assemblyOption/$global/streams/assembly/28139657d8472fc9db06ed0b9d0df2eaefed629f_5fa98cd1a63c99a44dd8d3b77e4762b066a5d0c5_dc564712cc91
549a72808653b6df35683be7efbf/com/google/common/util/concurrent (Is a directory)
[error] at java.io.FileInputStream.open0(Native Method)
[error] at java.io.FileInputStream.open(FileInputStream.java:195)
[error] at java.io.FileInputStream.<init>(FileInputStream.java:138)
[error] at sbt.io.Using$.$anonfun$fileInputStream$1(Using.scala:88)
[error] at sbt.io.Using$$anon$2.openImpl(Using.scala:76)
[error] at sbt.io.OpenFile.open(Using.scala:43)
[error] at sbt.io.OpenFile.open$(Using.scala:39)
[error] at sbt.io.Using$$anon$2.open(Using.scala:75)
[error] at sbt.io.Using$$anon$2.open(Using.scala:75)
[error] at sbt.io.Using.apply(Using.scala:21)
[error] at sbt.io.IO$.readBytes(IO.scala:789)
[error] at sbtassembly.Shader$.$anonfun$shadeDirectory$7(Shader.scala:98)
[error] at sbtassembly.Shader$.$anonfun$shadeDirectory$7$adapted(Shader.scala:97)
[error] at scala.collection.Iterator.foreach(Iterator.scala:944)
[error] at scala.collection.Iterator.foreach$(Iterator.scala:944)
[error] at scala.collection.AbstractIterator.foreach(Iterator.scala:1432)
[error] at scala.collection.IterableLike.foreach(IterableLike.scala:71)
[error] at scala.collection.IterableLike.foreach$(IterableLike.scala:70)
[error] at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
[error] at sbtassembly.Shader$.shadeDirectory(Shader.scala:97)
[error] at sbtassembly.Assembly$.$anonfun$assembleMappings$9(Assembly.scala:218)
[error] at scala.collection.parallel.AugmentedIterableIterator.map2combiner(RemainsIterator.scala:112)
[error] at scala.collection.parallel.AugmentedIterableIterator.map2combiner$(RemainsIterator.scala:109)
[error] at scala.collection.parallel.immutable.ParVector$ParVectorIterator.map2combiner(ParVector.scala:62)
[error] at scala.collection.parallel.ParIterableLike$Map.leaf(ParIterableLike.scala:1052)
[error] at scala.collection.parallel.Task.$anonfun$tryLeaf$1(Tasks.scala:49)
[error] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] at scala.util.control.Breaks$$anon$1.catchBreak(Breaks.scala:63)
[error] at scala.collection.parallel.Task.tryLeaf(Tasks.scala:52)
[error] at scala.collection.parallel.Task.tryLeaf$(Tasks.scala:46)
[error] at scala.collection.parallel.ParIterableLike$Map.tryLeaf(ParIterableLike.scala:1049)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.internal(Tasks.scala:156)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.internal$(Tasks.scala:153)
[error] at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.internal(Tasks.scala:436)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute(Tasks.scala:146)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute$(Tasks.scala:145)
[error] at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:436)
[error] at java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
[error] at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
[error] at java.util.concurrent.ForkJoinTask.doJoin(ForkJoinTask.java:389)
[error] at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:719)
[error] at scala.collection.parallel.ForkJoinTasks$WrappedTask.sync(Tasks.scala:375)
[error] at scala.collection.parallel.ForkJoinTasks$WrappedTask.sync$(Tasks.scala:375)
[error] at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.sync(Tasks.scala:436)
[error] at scala.collection.parallel.ForkJoinTasks.executeAndWaitResult(Tasks.scala:419)
[error] at scala.collection.parallel.ForkJoinTasks.executeAndWaitResult$(Tasks.scala:412)
[error] at scala.collection.parallel.ForkJoinTaskSupport.executeAndWaitResult(TaskSupport.scala:56)
[error] at scala.collection.parallel.ExecutionContextTasks.executeAndWaitResult(Tasks.scala:551)
[error] at scala.collection.parallel.ExecutionContextTasks.executeAndWaitResult$(Tasks.scala:551)
[error] at scala.collection.parallel.ExecutionContextTaskSupport.executeAndWaitResult(TaskSupport.scala:80)
[error] at scala.collection.parallel.ParIterableLike$ResultMapping.leaf(ParIterableLike.scala:956)
[error] at scala.collection.parallel.Task.$anonfun$tryLeaf$1(Tasks.scala:49)
[error] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] at scala.util.control.Breaks$$anon$1.catchBreak(Breaks.scala:63)
[error] at scala.collection.parallel.Task.tryLeaf(Tasks.scala:52)
[error] at scala.collection.parallel.Task.tryLeaf$(Tasks.scala:46)
[error] at scala.collection.parallel.ParIterableLike$ResultMapping.tryLeaf(ParIterableLike.scala:951)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute(Tasks.scala:149)
[error] at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask.compute$(Tasks.scala:145)
[error] at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:436)
[error] at java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
[error] at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
[error] at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
[error] at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
[error] at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
[error] (assembler / assembly / assembledMappings) java.io.FileNotFoundException: /build/wsl/akashi/akashi-assembler/target/streams/$global/assemblyOption/$global/streams/assembly/28139657d8472fc9db06ed0b9d0df2eaefed629f_5fa98cd1a63c99a44dd8d3b77e4762b066a5d0c5_dc564712cc91549a72808653b6df35683be7efbf/com/google/common/util/concurrent (Is a directory)
Naive Analysis
Both scenarios have the same stacktrace, centered around around:
[error] at sbt.io.IO$.readBytes(IO.scala:789)
[error] at sbtassembly.Shader$.$anonfun$shadeDirectory$7(Shader.scala:98)
[error] at sbtassembly.Shader$.$anonfun$shadeDirectory$7$adapted(Shader.scala:97)
[error] at scala.collection.Iterator.foreach(Iterator.scala:944)
[error] at scala.collection.Iterator.foreach$(Iterator.scala:944)
[error] at scala.collection.AbstractIterator.foreach(Iterator.scala:1432)
[error] at scala.collection.IterableLike.foreach(IterableLike.scala:71)
[error] at scala.collection.IterableLike.foreach$(IterableLike.scala:70)
[error] at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
[error] at sbtassembly.Shader$.shadeDirectory(Shader.scala:97)
[error] at sbtassembly.Assembly$.$anonfun$assembleMappings$9(Assembly.scala:218)
This section of code is of specific interest since line 97 should preclude directory files from being included in the set being read: https://github.com/sbt/sbt-assembly/blob/661fee89d1fb9c84fe25919cb92fc6bb9438b825/src/main/scala/sbtassembly/Shader.scala#L97-L98
This contradicts the error being reported by scenario no. 2, in which IO.readBytes
is invoked with a directory path.
This, in some part, is because _.isDirectory
returns false for all situations in which the file being checked isn't a directory, including not existing.
/**
* Tests whether the file denoted by this abstract pathname is a
* directory.
*
* <p> Where it is required to distinguish an I/O exception from the case
* that the file is not a directory, or where several attributes of the
* same file are required at the same time, then the {@link
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @return <code>true</code> if and only if the file denoted by this
* abstract pathname exists <em>and</em> is a directory;
* <code>false</code> otherwise
*
* @throws SecurityException
* If a security manager exists and its <code>{@link
* java.lang.SecurityManager#checkRead(java.lang.String)}</code>
* method denies read access to the file
*/
public boolean isDirectory()
Which relies on:
/**
* Return the simple boolean attributes for the file or directory denoted
* by the given abstract pathname, or zero if it does not exist or some
* other I/O error occurs.
*/
public abstract int getBooleanAttributes(File f);
This all seems to point to some race condition in which a list of files/paths is built by sbtassembly.AssemblyUtils#getMappings
while, somehow, those files/paths are still being created, and it's down to a race condition as to whether or not those folders/files will be completely flushed to disk by the time getMappings
is called (and/or by the time shadeDirectory
starts iterating over those mappings).
But, as the title of this section points out, this is only my naive analysis.
Environment:
WSL Environment:
jmaki@jmaki-pc /build/wsl/akashi
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.5 LTS
Release: 16.04
Codename: xenial
jmaki@jmaki-pc /build/wsl/akashi
$ sbt sbtVersion
[info] Loading settings for project akashi-build from plugin-resolvers.sbt,plugins.sbt ...
[info] Loading project definition from /build/wsl/akashi/project
[info] Loading settings for project root from build.sbt,version.sbt ...
[info] Set current project to akashi (in build file:/build/wsl/akashi/)
[info] common / sbtVersion
[info] 1.2.0
[info] preprocessor / sbtVersion
[info] 1.2.0
[info] assembler / sbtVersion
[info] 1.2.0
[info] sbtVersion
[info] 1.2.0
jmaki@jmaki-pc /build/wsl/akashi
$ java -version
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)
Windows Environment
OS Name Microsoft Windows 10 Pro
Version 10.0.17134 Build 17134
Processor Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz, 4008 Mhz, 4 Core(s), 8 Logical Processor(s)
I've updated the description (reproduction steps) to include a link to the repo I've updated to reproduce this issue: https://github.com/nivekastoreth/sbt-performance-project