Skip to content

Commit ff79958

Browse files
authored
fix: improve fatjar export (jbangdev#2228)
1 parent ecb63ea commit ff79958

File tree

3 files changed

+117
-37
lines changed

3 files changed

+117
-37
lines changed

src/main/java/dev/jbang/cli/Export.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,17 @@ int apply(BuildContext ctx) throws IOException {
372372
Util.verboseMsg("Unpacking artifact: " + dep);
373373
UnpackUtil.unzip(dep.getFile(), tmpDir, false, null, ExportFatjar::handleExistingFile);
374374
}
375+
// Remove all signature files
376+
Path metaInf = tmpDir.resolve("META-INF");
377+
if (Files.exists(metaInf) && Files.isDirectory(metaInf)) {
378+
try (DirectoryStream<Path> stream = Files.newDirectoryStream(metaInf, "*.{SF,DSA,RSA}")) {
379+
for (Path entry : stream) {
380+
Util.verboseMsg("Removing signature file: " + entry);
381+
Files.delete(entry);
382+
}
383+
}
384+
}
385+
Util.verboseMsg("Creating jar: " + outputPath);
375386
JarUtil.createJar(outputPath, tmpDir, null, prj.getMainClass(),
376387
exportMixin.buildMixin.getProjectJdk(prj));
377388
} finally {
@@ -389,6 +400,10 @@ int apply(BuildContext ctx) throws IOException {
389400
}
390401

391402
public static void handleExistingFile(ZipFile zipFile, ZipArchiveEntry zipEntry, Path outFile) throws IOException {
403+
if (Files.isDirectory(outFile) != zipEntry.isDirectory()) {
404+
Util.warnMsg("Skipping conflicting duplicate file vs directory: " + zipEntry.getName());
405+
return;
406+
}
392407
if (zipEntry.getName().startsWith("META-INF/services/")) {
393408
Util.verboseMsg("Merging service files: " + zipEntry.getName());
394409
try (ReadableByteChannel readableByteChannel = Channels.newChannel(zipFile.getInputStream(zipEntry));

src/main/java/dev/jbang/util/UnpackUtil.java

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.FileInputStream;
44
import java.io.IOException;
55
import java.io.InputStream;
6+
import java.nio.file.FileAlreadyExistsException;
67
import java.nio.file.Files;
78
import java.nio.file.Path;
89
import java.nio.file.Paths;
@@ -86,26 +87,40 @@ public static void unzip(Path zip, Path outputDir, boolean stripRootFolder, Path
8687
if (!entry.startsWith(outputDir)) {
8788
throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
8889
}
89-
if (zipEntry.isDirectory()) {
90-
Files.createDirectories(entry);
91-
} else if (zipEntry.isUnixSymlink()) {
92-
Scanner s = new Scanner(zipFile.getInputStream(zipEntry)).useDelimiter("\\A");
93-
String result = s.hasNext() ? s.next() : "";
94-
Files.createSymbolicLink(entry, Paths.get(result));
95-
} else {
96-
if (!Files.isDirectory(entry.getParent())) {
97-
Files.createDirectories(entry.getParent());
98-
}
99-
if (Files.isRegularFile(entry)) {
100-
onExisting.handle(zipFile, zipEntry, entry);
90+
try {
91+
if (zipEntry.isDirectory() && checkValidParent(entry)) {
92+
Files.createDirectories(entry);
93+
} else if (zipEntry.isUnixSymlink()) {
94+
Scanner s = new Scanner(zipFile.getInputStream(zipEntry)).useDelimiter("\\A");
95+
String result = s.hasNext() ? s.next() : "";
96+
Files.createSymbolicLink(entry, Paths.get(result));
10197
} else {
102-
defaultZipEntryCopy(zipFile, zipEntry, entry);
98+
if (checkValidParent(entry.getParent())) {
99+
Files.createDirectories(entry.getParent());
100+
}
101+
if (Files.exists(entry)) {
102+
onExisting.handle(zipFile, zipEntry, entry);
103+
} else {
104+
defaultZipEntryCopy(zipFile, zipEntry, entry);
105+
}
103106
}
107+
} catch (FileAlreadyExistsException e) {
108+
onExisting.handle(zipFile, zipEntry, entry);
104109
}
105110
}
106111
}
107112
}
108113

114+
private static boolean checkValidParent(Path path) throws FileAlreadyExistsException {
115+
while (path != null && !Files.exists(path)) {
116+
path = path.getParent();
117+
}
118+
if (path != null && !Files.isDirectory(path)) {
119+
throw new FileAlreadyExistsException("Parent path is not a directory: " + path);
120+
}
121+
return true;
122+
}
123+
109124
public interface ExistingZipFileHandler {
110125
void handle(ZipFile zipFile, ZipArchiveEntry zipEntry, Path outFile) throws IOException;
111126
}

0 commit comments

Comments
 (0)