diff --git a/CHANGELOG.md b/CHANGELOG.md
index 182ac1e..eb5587e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+# 2.2.0
+* Added an explicit option for enabling the Windows NTFS junction fix: ``useWinNTFSJunctionFixIfApplicable`` #155
+ * Enabling it also requires adding ``--add-exports java.base/sun.nio.fs=ALL-UNNAMED`` or performance will be impacted by ~20x due to non-accessible file attributes cache
+ * This option is temporary and will be removed once the underlying JDK bug was fixed
+* The default logger of ``AdvancedImageFromDockerFile`` now also includes ``dockerImageName`` to make it easier to distinguish between parallel builds
+
# 2.1.1
* Addresses a JDK bug which results in a crash or "infinite" loop when encountering recursive NTFS junctions on Windows #155
diff --git a/pom.xml b/pom.xml
index a84f5d9..ac991bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
software.xdev
testcontainers-advanced-imagebuilder-root
- 2.1.2-SNAPSHOT
+ 2.2.0-SNAPSHOT
pom
diff --git a/testcontainers-advanced-imagebuilder-demo/pom.xml b/testcontainers-advanced-imagebuilder-demo/pom.xml
index baa8899..30c81c6 100644
--- a/testcontainers-advanced-imagebuilder-demo/pom.xml
+++ b/testcontainers-advanced-imagebuilder-demo/pom.xml
@@ -7,11 +7,11 @@
software.xdev
testcontainers-advanced-imagebuilder-root
- 2.1.2-SNAPSHOT
+ 2.2.0-SNAPSHOT
testcontainers-advanced-imagebuilder-demo
- 2.1.2-SNAPSHOT
+ 2.2.0-SNAPSHOT
jar
diff --git a/testcontainers-advanced-imagebuilder-dummy-app/pom.xml b/testcontainers-advanced-imagebuilder-dummy-app/pom.xml
index b81da89..c9a8f71 100644
--- a/testcontainers-advanced-imagebuilder-dummy-app/pom.xml
+++ b/testcontainers-advanced-imagebuilder-dummy-app/pom.xml
@@ -6,7 +6,7 @@
software.xdev
testcontainers-advanced-imagebuilder-dummy-app
- 2.1.2-SNAPSHOT
+ 2.2.0-SNAPSHOT
jar
diff --git a/testcontainers-advanced-imagebuilder/pom.xml b/testcontainers-advanced-imagebuilder/pom.xml
index 0795ada..c795d05 100644
--- a/testcontainers-advanced-imagebuilder/pom.xml
+++ b/testcontainers-advanced-imagebuilder/pom.xml
@@ -6,7 +6,7 @@
software.xdev
testcontainers-advanced-imagebuilder
- 2.1.2-SNAPSHOT
+ 2.2.0-SNAPSHOT
jar
testcontainers-advanced-imagebuilder
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerFile.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerFile.java
index 5516e48..f35ab4c 100644
--- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerFile.java
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/AdvancedImageFromDockerFile.java
@@ -96,8 +96,8 @@ public class AdvancedImageFromDockerFile
StringsTrait,
DockerfileTrait
{
- protected static final Logger LOGGER = LoggerFactory.getLogger(AdvancedImageFromDockerFile.class);
protected final String dockerImageName;
+ protected final Logger defaultLogger;
protected final boolean deleteOnExit;
protected final Map transferables = new HashMap<>();
@@ -121,6 +121,7 @@ public class AdvancedImageFromDockerFile
protected Optional target = Optional.empty();
protected final Set> buildImageCmdModifiers = new LinkedHashSet<>();
protected Set externalDependencyImageNames = Collections.emptySet();
+ protected boolean useWinNTFSJunctionFixIfApplicable;
@SuppressWarnings("checkstyle:MagicNumber")
public AdvancedImageFromDockerFile()
@@ -134,9 +135,18 @@ public AdvancedImageFromDockerFile(final String dockerImageName)
}
public AdvancedImageFromDockerFile(final String dockerImageName, final boolean deleteOnExit)
+ {
+ this(
+ dockerImageName,
+ deleteOnExit,
+ LoggerFactory.getLogger(AdvancedImageFromDockerFile.class.getName() + "." + dockerImageName));
+ }
+
+ public AdvancedImageFromDockerFile(final String dockerImageName, final boolean deleteOnExit, final Logger logger)
{
this.dockerImageName = dockerImageName;
this.deleteOnExit = deleteOnExit;
+ this.defaultLogger = logger;
}
@Override
@@ -355,7 +365,8 @@ protected void configure(final BuildImageCmd buildImageCmd)
this.preGitIgnoreLines,
this.ignoreFileLineFilter,
this.postGitIgnoreLines,
- alwaysIncludePaths);
+ alwaysIncludePaths,
+ this.useWinNTFSJunctionFixIfApplicable);
this.log().info(
"{}x files will be transferred (determination took {}ms)",
@@ -489,7 +500,7 @@ protected boolean canImageNameBePulled(final String imageName)
protected Logger log()
{
- return LOGGER;
+ return this.defaultLogger;
}
public AdvancedImageFromDockerFile withBuildArg(final String key, final String value)
@@ -599,4 +610,17 @@ public AdvancedImageFromDockerFile withBuildImageCmdModifier(final Consumer
+ * See {@link software.xdev.testcontainers.imagebuilder.transfer.java.nio.file.winntfs} for details
+ *
+ */
+ public AdvancedImageFromDockerFile withUseWinNTFSJunctionFixIfApplicable(
+ final boolean useWinNTFSJunctionFixIfApplicable)
+ {
+ this.useWinNTFSJunctionFixIfApplicable = useWinNTFSJunctionFixIfApplicable;
+ return this;
+ }
}
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/DefaultTransferFilesCreator.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/DefaultTransferFilesCreator.java
index a28c7a3..c23aa64 100644
--- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/DefaultTransferFilesCreator.java
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/DefaultTransferFilesCreator.java
@@ -82,7 +82,8 @@ public Map determineFilesToTransfer(
final Set preGitIgnoreLines,
final Predicate ignoreFileLineFilter,
final Set postGitIgnoreLines,
- final Set alwaysIncludedRelativePaths)
+ final Set alwaysIncludedRelativePaths,
+ final boolean useWinNTFSJunctionFixIfApplicable)
{
try
{
@@ -100,7 +101,8 @@ public Map determineFilesToTransfer(
return this.walkFilesAndDetermineTransfer(
ignoreNode,
- alwaysIncludedRelativePaths);
+ alwaysIncludedRelativePaths,
+ useWinNTFSJunctionFixIfApplicable);
}
catch(final IOException ioe)
{
@@ -133,9 +135,11 @@ protected IgnoreNode createIgnoreNode(final Set ignoreLines)
protected Map walkFilesAndDetermineTransfer(
final IgnoreNode ignoreNode,
- final Set alwaysIncludedRelativePaths) throws IOException
+ final Set alwaysIncludedRelativePaths,
+ final boolean useWinNTFSJunctionFixIfApplicable) throws IOException
{
try(final Stream walk = findFiles(
+ useWinNTFSJunctionFixIfApplicable,
this.baseDir,
Integer.MAX_VALUE,
// Ignore directories
@@ -161,13 +165,14 @@ protected Map walkFilesAndDetermineTransfer(
}
protected static Stream findFiles(
+ final boolean useWinNTFSJunctionFixIfApplicable,
final Path start,
final int maxDepth,
final BiPredicate matcher,
final FileVisitOption... options)
throws IOException
{
- return WinNTFSJunctionFiles.shouldBeApplied(start)
+ return useWinNTFSJunctionFixIfApplicable && WinNTFSJunctionFiles.shouldBeApplied(start)
? WinNTFSJunctionFiles.find(start, maxDepth, matcher, options)
: Files.find(start, maxDepth, matcher, options);
}
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/TransferFilesCreator.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/TransferFilesCreator.java
index 90c1b10..b764e70 100644
--- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/TransferFilesCreator.java
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/TransferFilesCreator.java
@@ -28,7 +28,8 @@ Map determineFilesToTransfer(
Set preGitIgnoreLines,
Predicate ignoreFileLineFilter,
Set postGitIgnoreLines,
- Set alwaysIncludedRelativePaths);
+ Set alwaysIncludedRelativePaths,
+ boolean useWinNTFSJunctionFixIfApplicable);
InputStream getAllFilesToTransferAsTarInputStream(
Map filesToTransfer,
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/FileTreeWalker.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/FileTreeWalker.java
index 459655c..0a4651d 100644
--- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/FileTreeWalker.java
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/FileTreeWalker.java
@@ -55,6 +55,9 @@
import java.util.Collection;
import java.util.Iterator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Walks a file tree, generating a sequence of events corresponding to the files in the tree.
@@ -240,43 +243,59 @@ IOException ioeException()
}
// region Reflect access BasicFileAttributesHolder
- private boolean initializedBasicFileAttributesHolderClazz;
- private Class> basicFileAttributesHolderClazz;
- private Method mBasicFileAttributesHolderGet;
+ private static boolean initializedBasicFileAttributesHolderClazz;
+ private static Class> basicFileAttributesHolderClazz;
+ private static Method mBasicFileAttributesHolderGet;
+ private static boolean wasBasicFileAttributesHolderGetAccessSuccess;
- private void initBasicFileAttributesHolderClazz()
+ private static void initBasicFileAttributesHolderClazz()
{
- if(!this.initializedBasicFileAttributesHolderClazz)
+ if(!initializedBasicFileAttributesHolderClazz)
{
try
{
- this.basicFileAttributesHolderClazz = Class.forName("sun.nio.fs.BasicFileAttributesHolder");
- this.mBasicFileAttributesHolderGet = this.basicFileAttributesHolderClazz.getMethod("get");
- this.mBasicFileAttributesHolderGet.setAccessible(true);
+ basicFileAttributesHolderClazz = Class.forName("sun.nio.fs.BasicFileAttributesHolder");
+ mBasicFileAttributesHolderGet = basicFileAttributesHolderClazz.getMethod("get");
+ mBasicFileAttributesHolderGet.setAccessible(true);
}
catch(final Exception ignored)
{
// Ignored
}
- this.initializedBasicFileAttributesHolderClazz = true;
+ initializedBasicFileAttributesHolderClazz = true;
}
}
- private boolean isBasicFileAttributesHolder(final Path file)
+ private static boolean isBasicFileAttributesHolder(final Path file)
{
- this.initBasicFileAttributesHolderClazz();
+ initBasicFileAttributesHolderClazz();
- return this.basicFileAttributesHolderClazz != null
- && this.basicFileAttributesHolderClazz.isInstance(file);
+ return basicFileAttributesHolderClazz != null
+ && basicFileAttributesHolderClazz.isInstance(file);
}
- private BasicFileAttributes extractFromBasicFileAttributesHolder(final Path file)
+ private static BasicFileAttributes extractFromBasicFileAttributesHolder(final Path file)
{
try
{
- return (BasicFileAttributes)this.mBasicFileAttributesHolderGet.invoke(file);
+ final BasicFileAttributes attrs = (BasicFileAttributes)mBasicFileAttributesHolderGet.invoke(file);
+ wasBasicFileAttributesHolderGetAccessSuccess = true;
+ return attrs;
+ }
+ catch(final IllegalAccessException ex)
+ {
+ // Did we ever access it successfully?
+ if(!wasBasicFileAttributesHolderGetAccessSuccess)
+ {
+ basicFileAttributesHolderClazz = null;
+ mBasicFileAttributesHolderGet = null;
+ final Logger logger = LoggerFactory.getLogger(FileTreeWalker.class);
+ logger.warn("Failed to access BasicFileAttributesHolder", ex);
+ logger.warn("To fix this add '--add-exports java.base/sun.nio.fs=ALL-UNNAMED' as VM options");
+ }
+ return null;
}
- catch(final IllegalAccessException | InvocationTargetException ignored)
+ catch(final InvocationTargetException ignored)
{
return null;
}
diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/package-info.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/package-info.java
index cade447..1774ed0 100644
--- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/package-info.java
+++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/transfer/java/nio/file/winntfs/package-info.java
@@ -18,6 +18,11 @@
*
* recursive NTFS junctions on Windows
* .
+ *
+ * Please note:
+ * Enabling it also requires adding ``--add-exports java.base/sun.nio.fs=ALL-UNNAMED`` or performance will be
+ * impacted by ~20x due non-accessible file attributes cache
+ *
*
* @see NTFS junction
*/