@@ -38,6 +38,11 @@ public class MountableFile implements Transferable {
3838 @ Getter (lazy = true )
3939 private final String resolvedPath = resolvePath ();
4040
41+ @ Getter (lazy = true )
42+ private final String filesystemPath = resolveFilesystemPath ();
43+
44+ private String resourcePath ;
45+
4146 /**
4247 * Obtains a {@link MountableFile} corresponding to a resource on the classpath (including resources in JAR files)
4348 *
@@ -115,12 +120,7 @@ private static String unencodeResourceURIToFilePath(@NotNull final String resour
115120 * @return a volume-mountable path.
116121 */
117122 private String resolvePath () {
118- String result ;
119- if (path .contains (".jar!" )) {
120- result = extractClassPathResourceToTempLocation (this .path );
121- } else {
122- result = unencodeResourceURIToFilePath (path );
123- }
123+ String result = getResourcePath ();
124124
125125 if (SystemUtils .IS_OS_WINDOWS ) {
126126 result = PathUtils .createMinGWPath (result );
@@ -129,6 +129,32 @@ private String resolvePath() {
129129 return result ;
130130 }
131131
132+ /**
133+ * Obtain a path in local filesystem that the Docker daemon should be able to use to volume mount a file/resource
134+ * into a container. If this is a classpath resource residing in a JAR, it will be extracted to
135+ * a temporary location so that the Docker daemon is able to access it.
136+ *
137+ * @return
138+ */
139+ private String resolveFilesystemPath () {
140+ String result = getResourcePath ();
141+
142+ if (SystemUtils .IS_OS_WINDOWS && result .startsWith ("/" )) {
143+ result = result .substring (1 );
144+ }
145+
146+ return result ;
147+ }
148+
149+ private String getResourcePath () {
150+ if (path .contains (".jar!" )) {
151+ resourcePath = extractClassPathResourceToTempLocation (this .path );
152+ } else {
153+ resourcePath = unencodeResourceURIToFilePath (path );
154+ }
155+ return resourcePath ;
156+ }
157+
132158 /**
133159 * Extract a file or directory tree from a JAR file to a temporary location.
134160 * This allows Docker to mount classpath resources as files.
@@ -205,22 +231,22 @@ private void deleteOnExit(final Path path) {
205231 */
206232 @ Override
207233 public void transferTo (final TarArchiveOutputStream outputStream , String destinationPathInTar ) {
208- recursiveTar (destinationPathInTar , this .getResolvedPath (), this .getResolvedPath (), outputStream );
234+ recursiveTar (destinationPathInTar , this .getFilesystemPath (), this .getFilesystemPath (), outputStream );
209235 }
210236
211237 /*
212238 * Recursively copies a file/directory into a TarArchiveOutputStream
213239 */
214- private void recursiveTar (String destination , String sourceRootDir , String sourceCurrentItem , TarArchiveOutputStream tarArchive ) {
240+ private void recursiveTar (String entryFilename , String rootPath , String itemPath , TarArchiveOutputStream tarArchive ) {
215241 try {
216- final File sourceFile = new File (sourceCurrentItem ).getCanonicalFile (); // e.g. /foo/bar/baz
217- final File sourceRootFile = new File (sourceRootDir ).getCanonicalFile (); // e.g. /foo
242+ final File sourceFile = new File (itemPath ).getCanonicalFile (); // e.g. /foo/bar/baz
243+ final File sourceRootFile = new File (rootPath ).getCanonicalFile (); // e.g. /foo
218244 final String relativePathToSourceFile = sourceRootFile .toPath ().relativize (sourceFile .toPath ()).toFile ().toString (); // e.g. /bar/baz
219245
220- final TarArchiveEntry tarEntry = new TarArchiveEntry (sourceFile , destination + "/" + relativePathToSourceFile ); // entry filename e.g. /xyz/bar/baz
246+ final TarArchiveEntry tarEntry = new TarArchiveEntry (sourceFile , entryFilename + "/" + relativePathToSourceFile ); // entry filename e.g. /xyz/bar/baz
221247
222248 // TarArchiveEntry automatically sets the mode for file/directory, but we can update to ensure that the mode is set exactly (inc executable bits)
223- tarEntry .setMode (getUnixFileMode (sourceCurrentItem ));
249+ tarEntry .setMode (getUnixFileMode (itemPath ));
224250 tarArchive .putArchiveEntry (tarEntry );
225251
226252 if (sourceFile .isFile ()) {
@@ -233,19 +259,19 @@ private void recursiveTar(String destination, String sourceRootDir, String sourc
233259 if (children != null ) {
234260 // recurse into child files/directories
235261 for (final File child : children ) {
236- recursiveTar (destination , sourceRootDir + File . separator , child .getCanonicalPath (), tarArchive );
262+ recursiveTar (entryFilename , sourceRootFile . getCanonicalPath () , child .getCanonicalPath (), tarArchive );
237263 }
238264 }
239265 } catch (IOException e ) {
240- log .error ("Error when copying TAR file entry: {}" , sourceCurrentItem , e );
266+ log .error ("Error when copying TAR file entry: {}" , itemPath , e );
241267 throw new UncheckedIOException (e ); // fail fast
242268 }
243269 }
244270
245271 @ Override
246272 public long getSize () {
247273
248- final File file = new File (this .getResolvedPath ());
274+ final File file = new File (this .getFilesystemPath ());
249275 if (file .isFile ()) {
250276 return file .length ();
251277 } else {
@@ -260,7 +286,7 @@ public String getDescription() {
260286
261287 @ Override
262288 public int getFileMode () {
263- return getUnixFileMode (this .getResolvedPath ());
289+ return getUnixFileMode (this .getFilesystemPath ());
264290 }
265291
266292 private int getUnixFileMode (final String pathAsString ) {
0 commit comments