Skip to content

Commit b0150ea

Browse files
committed
Do not fail if a classpath entry is missing
The resource detection mechanism should be lenient with regards to entries which might be missing from the classpath. For example, in case of an empty `src/test/resources` directory, the Gradle test process resources task would not create a `build/test/resources` directory, which causes a failure. Fixes #175
1 parent c25339f commit b0150ea

File tree

4 files changed

+106
-16
lines changed

4 files changed

+106
-16
lines changed

common/utils/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ maven {
5252

5353
dependencies {
5454
implementation(libs.jackson.databind)
55+
implementation(platform(libs.test.junit.bom))
56+
implementation(libs.test.junit.jupiter.core)
57+
}
58+
59+
tasks.withType<Test>().configureEach {
60+
useJUnitPlatform()
5561
}
5662

5763
val generateVersionInfo = tasks.register("generateVersionInfo", org.graalvm.build.GenerateVersionClass::class.java) {

common/utils/src/main/java/org/graalvm/buildtools/model/resources/ClassPathDirectoryAnalyzer.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,14 @@ class ClassPathDirectoryAnalyzer extends ClassPathEntryAnalyzer {
6464
}
6565

6666
protected List<String> initialize() throws IOException {
67-
DirectoryVisitor visitor = new DirectoryVisitor();
68-
Files.walkFileTree(root, visitor);
69-
return visitor.hasNativeImageResourceFile && !ignoreExistingResourcesConfig ? Collections.emptyList() : visitor.resources;
67+
if (Files.exists(root)) {
68+
DirectoryVisitor visitor = new DirectoryVisitor();
69+
Files.walkFileTree(root, visitor);
70+
return visitor.hasNativeImageResourceFile && !ignoreExistingResourcesConfig ? Collections.emptyList() : visitor.resources;
71+
}
72+
else {
73+
return Collections.emptyList();
74+
}
7075
}
7176

7277
private class DirectoryVisitor extends SimpleFileVisitor<Path> {

common/utils/src/main/java/org/graalvm/buildtools/model/resources/JarAnalyzer.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,26 @@ class JarAnalyzer extends ClassPathEntryAnalyzer {
6363
}
6464

6565
protected List<String> initialize() throws IOException {
66-
List<String> resources = new ArrayList<>();
67-
boolean hasNativeImageResourceFile = false;
68-
try (JarInputStream zin = new JarInputStream(new FileInputStream(jarFile))) {
69-
ZipEntry entry;
70-
while ((entry = zin.getNextEntry()) != null) {
71-
hasNativeImageResourceFile = FileUtils.normalizePathSeparators(entry.getName()).startsWith(Helper.META_INF_NATIVE_IMAGE + "/")
72-
&& entry.getName().endsWith("resource-config.json");
66+
if (jarFile.exists()) {
67+
List<String> resources = new ArrayList<>();
68+
boolean hasNativeImageResourceFile = false;
69+
try (JarInputStream zin = new JarInputStream(new FileInputStream(jarFile))) {
70+
ZipEntry entry;
71+
while ((entry = zin.getNextEntry()) != null) {
72+
hasNativeImageResourceFile = FileUtils.normalizePathSeparators(entry.getName()).startsWith(Helper.META_INF_NATIVE_IMAGE + "/")
73+
&& entry.getName().endsWith("resource-config.json");
7374

74-
if (hasNativeImageResourceFile && !ignoreExistingResourcesConfig) {
75-
break;
76-
}
77-
if (!entry.isDirectory()) {
78-
maybeAddResource(entry.getName(), resources);
75+
if (hasNativeImageResourceFile && !ignoreExistingResourcesConfig) {
76+
break;
77+
}
78+
if (!entry.isDirectory()) {
79+
maybeAddResource(entry.getName(), resources);
80+
}
7981
}
8082
}
83+
return hasNativeImageResourceFile && !ignoreExistingResourcesConfig ? Collections.emptyList() : resources;
84+
} else {
85+
return Collections.emptyList();
8186
}
82-
return hasNativeImageResourceFile && !ignoreExistingResourcesConfig ? Collections.emptyList() : resources;
8387
}
8488
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package org.graalvm.buildtools.utils;
42+
43+
import org.graalvm.buildtools.model.resources.ClassPathEntryAnalyzer;
44+
import org.junit.jupiter.api.DisplayName;
45+
import org.junit.jupiter.api.Test;
46+
47+
import java.io.File;
48+
import java.io.IOException;
49+
import java.util.Collections;
50+
51+
import static org.junit.jupiter.api.Assertions.assertEquals;
52+
53+
public class ClassPathEntryAnalyzerTest {
54+
@Test
55+
@DisplayName("A non existent jar shouldn't cause an exception")
56+
public void testShouldAllowNonExistentJar() throws IOException {
57+
ClassPathEntryAnalyzer analyzer = ClassPathEntryAnalyzer.of(
58+
new File("dummy.jar"),
59+
s -> true,
60+
false
61+
);
62+
assertEquals(Collections.emptyList(), analyzer.getResources());
63+
}
64+
65+
@Test
66+
@DisplayName("A non existent directory shouldn't cause an exception")
67+
public void testShouldAllowNonExistentDir() throws IOException {
68+
ClassPathEntryAnalyzer analyzer = ClassPathEntryAnalyzer.of(
69+
new File("dummy-dir"),
70+
s -> true,
71+
false
72+
);
73+
assertEquals(Collections.emptyList(), analyzer.getResources());
74+
}
75+
}

0 commit comments

Comments
 (0)