Okay, this is hard to put into words, but I'll try my best
To define a directory inclusion I'll use GNU Tar examples
$ mkdir gnutar
$ cd gnutar
$ touch simple.txt
$ tar cf - . | tar -tvf -
drwxr-xr-x 0/0 0 2026-03-11 22:24 ./
-rw-r--r-- 0/0 0 2026-03-11 22:24 ./simple.txt
You will notice that there is a root directory within tar itself, aka the first entry. You must also notice that there is a timestamp attached with a directory.
Now lets try something else
$ tar cf - * | tar -tvf -
-rw-r--r-- 0/0 0 2026-03-11 22:24 simple.txt
In this example, there is no root directory, file is stored directly at the root of the archive.
For fun, we can examine another example - tar.gz of latest release as generated by github
$ curl -sLo - https://github.com/fabric8io/docker-maven-plugin/archive/refs/tags/v0.48.1.tar.gz | tar -tzvf - | head -n5
drwxrwxr-x root/root 0 2026-02-07 18:47 docker-maven-plugin-0.48.1/
-rw-rw-r-- root/root 195 2026-02-07 18:47 docker-maven-plugin-0.48.1/.codecov.yml
-rw-rw-r-- root/root 85 2026-02-07 18:47 docker-maven-plugin-0.48.1/.gitattributes
drwxrwxr-x root/root 0 2026-02-07 18:47 docker-maven-plugin-0.48.1/.github/
-rw-rw-r-- root/root 484 2026-02-07 18:47 docker-maven-plugin-0.48.1/.github/ISSUE_TEMPLATE.md
There's no "./" in here either.
This brings us to the problem in D-M-P
Consider I define an assembly on a directory that is created by copying file (in the example, I'll use simple resources copied by maven plugin)
In the example below, I have used tar mode to demonstrate changed sha256sum that causes the layer invalidation
<assembly>
<name>src-asset2</name>
<targetDir>/src/asset2</targetDir>
<mode>tar</mode>
<inline>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/resources/asset2/</directory>
<outputDirectory>.</outputDirectory>
</fileSet>
</fileSets>
</inline>
</assembly>
<assembly>
<name>tgt-asset2</name>
<targetDir>/tgt/asset2</targetDir>
<mode>tar</mode>
<inline>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}/asset2/</directory>
<outputDirectory>.</outputDirectory>
</fileSet>
</fileSets>
</inline>
</assembly>
Directory state is as follows, before copying
$ ls -la src/main/resources/asset2/
total 1
drwxr-xr-x 1 0 0 0 Mar 11 21:28 ./
drwxr-xr-x 1 0 0 0 Mar 11 22:08 ../
-rw-r--r-- 1 0 0 24 Mar 11 21:29 example2.txt
Copied files are as follows
$ ls -la target/classes/asset2/
total 1
drwxr-xr-x 1 0 0 0 Mar 11 22:17 ./
drwxr-xr-x 1 0 0 0 Mar 11 22:17 ../
-rw-r--r-- 1 0 0 24 Mar 11 21:29 example2.txt
Which is expected, since resources plugin has to create target directories before copying files.
Lets now run D-M-P and examine tars created.
$ tar -tvf target/docker/layer-test/latest/build/src-asset2.tar
drwxr-xr-x 0/0 0 2026-03-11 21:28 ./
-rw-r--r-- 0/0 24 2026-03-11 21:29 ./example2.txt
$ sha256sum target/docker/layer-test/latest/build/src-asset2.tar
984c444d3d2db5742a5f7127dc0e2fccc30f5b413e373ee92b0e44442ea41bbc *target/docker/layer-test/latest/build/src-asset2.tar
$ tar -tvf target/docker/layer-test/latest/build/tgt-asset2.tar
drwxr-xr-x 0/0 0 2026-03-11 22:32 ./
-rw-r--r-- 0/0 24 2026-03-11 21:29 ./example2.txt
$ sha256sum target/docker/layer-test/latest/build/tgt-asset2.tar
5e168f1ac3833cd9522bce7cf0c6bb9423a61cb8dc864a18608ba63a341c69d3 *target/docker/layer-test/latest/build/tgt-asset2.tar
Second run, asset within the src folder remains the same, however same is not true (obviously) for second asset
$ tar -tvf target/docker/layer-test/latest/build/tgt-asset2.tar
drwxr-xr-x 0/0 0 2026-03-11 22:36 ./
-rw-r--r-- 0/0 24 2026-03-11 21:29 ./example2.txt
$ sha256sum target/docker/layer-test/latest/build/tgt-asset2.tar
0c7828aa91c34866a4a845a5e1abc2239de762376565a2fcf4c218fdd0619ee1 *target/docker/layer-test/latest/build/tgt-asset2.tar
As you can see, the layer that was supposed to have same file copied over - the file that was not modified in any regard - has its sha256sum changed because it includes ./ whose timestamp changes on every run.
It is the same with the directory mode. It always creates a different layer since it uses COPY /directory and not COPY /directory/* to copy files, transferring the timestamp of the owning directories as well.
You can find the full example here https://github.com/ZIRAKrezovic/dmp-layers
I would appreciate any help on how to handle this scenario. We have an artifact that gets downloaded by another maven plugin and extracted into target/, and its parent directory is always "current". Using assembly with them always results in layer invalidation as demonstrated above.
Okay, this is hard to put into words, but I'll try my best
To define a directory inclusion I'll use GNU Tar examples
You will notice that there is a root directory within tar itself, aka the first entry. You must also notice that there is a timestamp attached with a directory.
Now lets try something else
In this example, there is no root directory, file is stored directly at the root of the archive.
For fun, we can examine another example - tar.gz of latest release as generated by github
There's no "./" in here either.
This brings us to the problem in D-M-P
Consider I define an assembly on a directory that is created by copying file (in the example, I'll use simple resources copied by maven plugin)
In the example below, I have used tar mode to demonstrate changed sha256sum that causes the layer invalidation
Directory state is as follows, before copying
Copied files are as follows
Which is expected, since resources plugin has to create target directories before copying files.
Lets now run D-M-P and examine tars created.
$ tar -tvf target/docker/layer-test/latest/build/src-asset2.tar drwxr-xr-x 0/0 0 2026-03-11 21:28 ./ -rw-r--r-- 0/0 24 2026-03-11 21:29 ./example2.txt $ sha256sum target/docker/layer-test/latest/build/src-asset2.tar 984c444d3d2db5742a5f7127dc0e2fccc30f5b413e373ee92b0e44442ea41bbc *target/docker/layer-test/latest/build/src-asset2.tar$ tar -tvf target/docker/layer-test/latest/build/tgt-asset2.tar drwxr-xr-x 0/0 0 2026-03-11 22:32 ./ -rw-r--r-- 0/0 24 2026-03-11 21:29 ./example2.txt $ sha256sum target/docker/layer-test/latest/build/tgt-asset2.tar 5e168f1ac3833cd9522bce7cf0c6bb9423a61cb8dc864a18608ba63a341c69d3 *target/docker/layer-test/latest/build/tgt-asset2.tarSecond run, asset within the src folder remains the same, however same is not true (obviously) for second asset
$ tar -tvf target/docker/layer-test/latest/build/tgt-asset2.tar drwxr-xr-x 0/0 0 2026-03-11 22:36 ./ -rw-r--r-- 0/0 24 2026-03-11 21:29 ./example2.txt $ sha256sum target/docker/layer-test/latest/build/tgt-asset2.tar 0c7828aa91c34866a4a845a5e1abc2239de762376565a2fcf4c218fdd0619ee1 *target/docker/layer-test/latest/build/tgt-asset2.tarAs you can see, the layer that was supposed to have same file copied over - the file that was not modified in any regard - has its sha256sum changed because it includes
./whose timestamp changes on every run.It is the same with the directory mode. It always creates a different layer since it uses
COPY /directoryand notCOPY /directory/*to copy files, transferring the timestamp of the owning directories as well.You can find the full example here https://github.com/ZIRAKrezovic/dmp-layers
I would appreciate any help on how to handle this scenario. We have an artifact that gets downloaded by another maven plugin and extracted into target/, and its parent directory is always "current". Using assembly with them always results in layer invalidation as demonstrated above.