Skip to content

Commit 095621f

Browse files
authored
Validate mrjar plugin versions (elastic#120823)
The mrjar plugin adds support for sourcesets named in the form mainNN, which adds the appropriate compiler and other settings for that version of Java, and produces a multi-release jar. Having multi-release jars only makes sense for versions of java newer than the minimum compile version. This commit adds validation that the version is not too old. Note that the check is slightly relaxed; it allows mainNN where NN is equal to the min java version. This is due to the desire to keep code using incubating modules separate because warnings must be disabled.
1 parent 4783d1f commit 095621f

File tree

4 files changed

+61
-125
lines changed

4 files changed

+61
-125
lines changed

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/MrjarPlugin.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,19 @@ public void apply(Project project) {
7272
var javaExtension = project.getExtensions().getByType(JavaPluginExtension.class);
7373
var isIdeaSync = System.getProperty("idea.sync.active", "false").equals("true");
7474
var ideaSourceSetsEnabled = project.hasProperty(MRJAR_IDEA_ENABLED) && project.property(MRJAR_IDEA_ENABLED).equals("true");
75+
int minJavaVersion = Integer.parseInt(buildParams.getMinimumCompilerVersion().getMajorVersion());
7576

7677
// Ignore version-specific source sets if we are importing into IntelliJ and have not explicitly enabled this.
7778
// Avoids an IntelliJ bug:
7879
// https://youtrack.jetbrains.com/issue/IDEA-285640/Compiler-Options-Settings-language-level-is-set-incorrectly-with-JDK-19ea
7980
if (isIdeaSync == false || ideaSourceSetsEnabled) {
80-
List<Integer> mainVersions = findSourceVersions(project);
81+
List<Integer> mainVersions = findSourceVersions(project, minJavaVersion);
8182
List<String> mainSourceSets = new ArrayList<>();
8283
mainSourceSets.add(SourceSet.MAIN_SOURCE_SET_NAME);
83-
configurePreviewFeatures(project, javaExtension.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME), 21);
84+
configurePreviewFeatures(project, javaExtension.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME), minJavaVersion);
8485
List<String> testSourceSets = new ArrayList<>(mainSourceSets);
8586
testSourceSets.add(SourceSet.TEST_SOURCE_SET_NAME);
86-
configurePreviewFeatures(project, javaExtension.getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME), 21);
87+
configurePreviewFeatures(project, javaExtension.getSourceSets().getByName(SourceSet.TEST_SOURCE_SET_NAME), minJavaVersion);
8788
for (int javaVersion : mainVersions) {
8889
String mainSourceSetName = SourceSet.MAIN_SOURCE_SET_NAME + javaVersion;
8990
SourceSet mainSourceSet = addSourceSet(project, javaExtension, mainSourceSetName, mainSourceSets, javaVersion, true);
@@ -103,6 +104,7 @@ public void apply(Project project) {
103104
}
104105

105106
private void configureMrjar(Project project) {
107+
106108
var jarTask = project.getTasks().withType(Jar.class).named(JavaPlugin.JAR_TASK_NAME);
107109
jarTask.configure(task -> { task.manifest(manifest -> { manifest.attributes(Map.of("Multi-Release", "true")); }); });
108110

@@ -222,7 +224,7 @@ private void createTestTask(
222224
project.getTasks().named("check").configure(checkTask -> checkTask.dependsOn(testTaskProvider));
223225
}
224226

225-
private static List<Integer> findSourceVersions(Project project) {
227+
private static List<Integer> findSourceVersions(Project project, int minJavaVersion) {
226228
var srcDir = project.getProjectDir().toPath().resolve("src");
227229
List<Integer> versions = new ArrayList<>();
228230
try (var subdirStream = Files.list(srcDir)) {
@@ -231,7 +233,23 @@ private static List<Integer> findSourceVersions(Project project) {
231233
String sourcesetName = sourceSetPath.getFileName().toString();
232234
Matcher sourcesetMatcher = MRJAR_SOURCESET_PATTERN.matcher(sourcesetName);
233235
if (sourcesetMatcher.matches()) {
234-
versions.add(Integer.parseInt(sourcesetMatcher.group(1)));
236+
int version = Integer.parseInt(sourcesetMatcher.group(1));
237+
if (version < minJavaVersion) {
238+
// NOTE: We allow mainNN for the min java version so that incubating modules can be used without warnings.
239+
// It is a workaround for https://bugs.openjdk.org/browse/JDK-8187591. Once min java is 22, we
240+
// can use the SuppressWarnings("preview") in the code using incubating modules and this check
241+
// can change to <=
242+
throw new IllegalArgumentException(
243+
"Found src dir '"
244+
+ sourcesetName
245+
+ "' for Java "
246+
+ version
247+
+ " but multi-release jar sourceset should have version "
248+
+ minJavaVersion
249+
+ " or greater"
250+
);
251+
}
252+
versions.add(version);
235253
}
236254
}
237255
} catch (IOException e) {

libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNetworkChecks.java

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,51 @@
1414
import java.net.http.HttpClient;
1515
import java.net.http.HttpRequest;
1616
import java.net.http.HttpResponse;
17+
import java.net.spi.InetAddressResolver;
18+
import java.net.spi.InetAddressResolverProvider;
1719

1820
class VersionSpecificNetworkChecks {
19-
static void createInetAddressResolverProvider() {}
21+
static void createInetAddressResolverProvider() {
22+
var x = new InetAddressResolverProvider() {
23+
@Override
24+
public InetAddressResolver get(Configuration configuration) {
25+
return null;
26+
}
27+
28+
@Override
29+
public String name() {
30+
return "TEST";
31+
}
32+
};
33+
}
2034

2135
static void httpClientSend() throws InterruptedException {
22-
HttpClient httpClient = HttpClient.newBuilder().build();
23-
try {
24-
httpClient.send(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding());
25-
} catch (IOException e) {
26-
// Expected, the send action may fail with these parameters (but after it run the entitlement check in the prologue)
36+
try (HttpClient httpClient = HttpClient.newBuilder().build()) {
37+
// Shutdown the client, so the send action will shortcut before actually executing any network operation
38+
// (but after it run our check in the prologue)
39+
httpClient.shutdown();
40+
try {
41+
httpClient.send(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding());
42+
} catch (IOException e) {
43+
// Expected, since we shut down the client
44+
}
2745
}
2846
}
2947

3048
static void httpClientSendAsync() {
31-
HttpClient httpClient = HttpClient.newBuilder().build();
32-
httpClient.sendAsync(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding());
49+
try (HttpClient httpClient = HttpClient.newBuilder().build()) {
50+
// Shutdown the client, so the send action will return before actually executing any network operation
51+
// (but after it run our check in the prologue)
52+
httpClient.shutdown();
53+
var future = httpClient.sendAsync(
54+
HttpRequest.newBuilder(URI.create("http://localhost")).build(),
55+
HttpResponse.BodyHandlers.discarding()
56+
);
57+
assert future.isCompletedExceptionally();
58+
future.exceptionally(ex -> {
59+
assert ex instanceof IOException;
60+
return null;
61+
});
62+
}
3363
}
3464
}

libs/entitlement/qa/entitlement-test-plugin/src/main18/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNetworkChecks.java

Lines changed: 0 additions & 48 deletions
This file was deleted.

libs/entitlement/qa/entitlement-test-plugin/src/main21/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNetworkChecks.java

Lines changed: 0 additions & 64 deletions
This file was deleted.

0 commit comments

Comments
 (0)