sbt / sbt-assembly

Deploy über-JARs. Restart processes. (port of codahale/assembly-sbt)
MIT License
1.95k stars 224 forks source link

Assembly no longer creating directories defined in assemblyOutputPath #486

Closed etspaceman closed 5 months ago

etspaceman commented 1 year ago

Hello -

So I have a plugin that I have for managing my project's docker image, which uses sbt-assembly. I set the assemblyOutputPath to a different value, here:

https://github.com/etspaceman/kinesis-mock/blob/main/project/DockerImagePlugin.scala#L59

However, with the upgrade to 2.0.0 I've been getting errors like this:

[error] java.nio.file.NoSuchFileException: /home/runner/work/kinesis-mock/kinesis-mock/docker/image/lib/kinesis-mock.jar

https://github.com/etspaceman/kinesis-mock/pull/362 https://github.com/etspaceman/kinesis-mock/actions/runs/3322302608/jobs/5491131628

I was able to resolve this by creating the path docker/image/lib. If the path doesn't exist, the error is thrown. So basically, sbt-asembly isn't creating the directory structure like I'd expect anymore.

Is there a good way around this? Ideally i'd like to have the command itself have the old behavior. Any way i can do that in the plugin? And does anyone have context as to why this may have changed?

etspaceman commented 1 year ago

Stack trace seems to point here:

Stack Trace seems to point here: https://github.com/sbt/sbt-assembly/blame/v2.0.0/src/main/scala/sbtassembly/Assembly.scala#L67

Perhaps its not a "not creating directories" issue, but perhaps the refactor introduced a dependency on these paths prior to the jar creation.

jhnaldo commented 1 year ago

I have the same issue about creating not yet existing directory when setting the custom output path with assemblyOutputPath.

Our ESMeta project uses sbt-assembly to create a binary file into bin/esmeta. However, it does not work when using the 2.1.0 version with the following plugin setting:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.0")

and the build.sbt command:

assembly / assemblyOutputPath := file("bin/esmeta")

It throws a java.nio.file.NoSuchFileException error as follows:

[error] java.nio.file.NoSuchFileException: /Users/naldo/project/esmeta/bin/esmeta
[error]     at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
[error]     at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
[error]     at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
[error]     at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218)
[error]     at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:484)
[error]     at java.base/java.nio.file.Files.newOutputStream(Files.java:228)
[error]     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystem.<init>(ZipFileSystem.java:162)
[error]     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.getZipFileSystem(ZipFileSystemProvider.java:125)
[error]     at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:106)
[error]     at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:339)
[error]     at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:288)
[error]     at sbtassembly.Assembly$.$anonfun$jarFileSystemResource$1(Assembly.scala:70)
...

I think it is related to the directory creation because it works well after manually creating the bin directory.

markarasev commented 9 months ago

I think it is related to the directory creation because it works well after manually creating the bin directory

Same here, and sbt-assembly 1.2.0 is able to create the directory by itself.

arixmkii commented 6 months ago

I believe this was introduced with ZipFileSystem usage (in memory processing). https://github.com/sbt/sbt-assembly/blob/56f7e715ac3444237c8f1fd6c88abceeaf641e4a/src/main/scala/sbtassembly/Assembly.scala#L546 Before this line there should be a check that parent directory exists.

Because newFileSystem of ZipFileSystemProvider doesn't create paths https://github.com/openjdk/jdk/blob/21867c929a2f2c961148f2cd1e79d672ac278d27/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java#L95 and ZipFileSystem itself just tries to open FileOutputStream https://github.com/openjdk/jdk/blob/21867c929a2f2c961148f2cd1e79d672ac278d27/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java#L162 which will not create the parent directories. I will try to compose PR later on.