Skip to content

Commit 8dd95c4

Browse files
meltsufinClément Denis
andauthored
feat: support for java17 and java21 runtimes (#936)
Fixes: #935. Co-authored-by: Clément Denis <clement@altirnao.com>
1 parent 52dd5aa commit 8dd95c4

File tree

7 files changed

+84
-19
lines changed

7 files changed

+84
-19
lines changed

.github/workflows/unit-tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
java: [8, 11, 17]
15+
java: [8, 11, 17, 21]
1616
env:
1717
CLOUDSDK_CORE_DISABLE_USAGE_REPORTING: true
1818
CLOUDSDK_CORE_DISABLE_PROMPTS: true

pom.xml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
<dependency>
106106
<groupId>org.mockito</groupId>
107107
<artifactId>mockito-core</artifactId>
108-
<version>4.4.0</version>
108+
<version>5.5.0</version>
109109
<scope>test</scope>
110110
</dependency>
111111
<dependency>
@@ -244,7 +244,7 @@
244244
<plugin>
245245
<groupId>org.jacoco</groupId>
246246
<artifactId>jacoco-maven-plugin</artifactId>
247-
<version>0.8.7</version>
247+
<version>0.8.10</version>
248248
<executions>
249249
<execution>
250250
<id>initialize</id>
@@ -329,12 +329,12 @@
329329
<path>
330330
<groupId>com.google.errorprone</groupId>
331331
<artifactId>error_prone_core</artifactId>
332-
<version>2.11.0</version>
332+
<version>2.22.0</version>
333333
</path>
334334
<path>
335335
<groupId>com.uber.nullaway</groupId>
336336
<artifactId>nullaway</artifactId>
337-
<version>0.7.8</version>
337+
<version>0.10.14</version>
338338
</path>
339339
</annotationProcessorPaths>
340340
<fork>true</fork>
@@ -420,6 +420,15 @@
420420
<activation>
421421
<jdk>1.8</jdk>
422422
</activation>
423+
<dependencies>
424+
<dependency>
425+
<groupId>org.mockito</groupId>
426+
<artifactId>mockito-core</artifactId>
427+
<!-- keep 4.x for JDK 8 tests as 5.x is for JDK 11+ -->
428+
<version>4.11.0</version>
429+
<scope>test</scope>
430+
</dependency>
431+
</dependencies>
423432
<build>
424433
<plugins>
425434
<plugin>

src/main/java/com/google/cloud/tools/appengine/operations/AppYamlProjectStaging.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.common.base.Splitter;
2828
import com.google.common.base.Strings;
2929
import com.google.common.collect.ImmutableList;
30+
import com.google.common.collect.ImmutableSet;
3031
import java.io.IOException;
3132
import java.io.InputStream;
3233
import java.nio.file.Files;
@@ -44,6 +45,9 @@ public class AppYamlProjectStaging {
4445

4546
private static final String APP_YAML = "app.yaml";
4647

48+
private static final ImmutableSet<String> GEN2_RUNTIMES =
49+
ImmutableSet.of("java11", "java17", "java21");
50+
4751
@VisibleForTesting
4852
static final ImmutableList<String> OTHER_YAMLS =
4953
ImmutableList.of("cron.yaml", "dos.yaml", "dispatch.yaml", "index.yaml", "queue.yaml");
@@ -76,7 +80,7 @@ public void stageArchive(AppYamlProjectStageConfiguration config) throws AppEngi
7680
stageFlexibleArchive(config, runtime);
7781
return;
7882
}
79-
if ("java11".equals(runtime) || "java17".equals(runtime)) {
83+
if (GEN2_RUNTIMES.contains(runtime)) {
8084
boolean isJar = config.getArtifact().getFileName().toString().endsWith(".jar");
8185
if (isJar) {
8286
stageStandardArchive(config);
@@ -88,7 +92,9 @@ public void stageArchive(AppYamlProjectStageConfiguration config) throws AppEngi
8892
}
8993
// I cannot deploy non-jars without custom entrypoints
9094
throw new AppEngineException(
91-
"Cannot process application with runtime: java11/java17."
95+
"Cannot process application with runtime: "
96+
+ runtime
97+
+ "."
9298
+ " A custom entrypoint must be defined in your app.yaml for non-jar artifact: "
9399
+ config.getArtifact().toString());
94100
}
@@ -248,10 +254,10 @@ static void copyArtifactJarClasspath(
248254
Iterable<String> classpathEntries = Splitter.onPattern("\\s+").split(jarClassPath.trim());
249255
for (String classpathEntry : classpathEntries) {
250256
// classpath entries are relative to artifact's position and relativeness should be
251-
// preserved
252-
// in the target directory
253-
Path jarSrc = artifact.getParent().resolve(classpathEntry);
254-
if (!Files.isRegularFile(jarSrc)) {
257+
// preserved in the target directory
258+
Path jarSrc =
259+
artifact.getParent() == null ? null : artifact.getParent().resolve(classpathEntry);
260+
if (jarSrc == null || !Files.isRegularFile(jarSrc)) {
255261
log.warning("Could not copy 'Class-Path' jar: " + jarSrc + " referenced in MANIFEST.MF");
256262
continue;
257263
}

src/main/java/com/google/cloud/tools/appengine/operations/DevAppServerRunner.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,11 @@ public void run(
7272
command.add(sdk.getJavaExecutablePath().toAbsolutePath().toString());
7373

7474
command.addAll(jvmArgs);
75-
command.add(
76-
"-Dappengine.sdk.root="
77-
+ sdk.getAppEngineSdkForJavaPath().getParent().toAbsolutePath().toString());
75+
if (sdk.getAppEngineSdkForJavaPath().getParent() != null) {
76+
command.add(
77+
"-Dappengine.sdk.root="
78+
+ sdk.getAppEngineSdkForJavaPath().getParent().toAbsolutePath().toString());
79+
}
7880
command.add("-cp");
7981
command.add(sdk.getAppEngineToolsJar().toAbsolutePath().toString());
8082
command.add("com.google.appengine.tools.development.DevAppServerMain");

src/test/java/com/google/cloud/tools/appengine/operations/AppYamlProjectStagingTest.java

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,24 @@ public void testStageArchive_flexPath() throws IOException, AppEngineException {
107107

108108
@Test
109109
public void testStageArchive_java11StandardPath() throws IOException, AppEngineException {
110+
stageArchive_gen2StandardPath("java11");
111+
}
112+
113+
@Test
114+
public void testStageArchive_java17StandardPath() throws IOException, AppEngineException {
115+
stageArchive_gen2StandardPath("java17");
116+
}
117+
118+
@Test
119+
public void testStageArchive_java21StandardPath() throws IOException, AppEngineException {
120+
stageArchive_gen2StandardPath("java21");
121+
}
122+
123+
private void stageArchive_gen2StandardPath(String runtime)
124+
throws IOException, AppEngineException {
110125
Files.write(
111126
appEngineDirectory.resolve("app.yaml"),
112-
"runtime: java11\n".getBytes(StandardCharsets.UTF_8),
127+
("runtime: " + runtime + "\n").getBytes(StandardCharsets.UTF_8),
113128
StandardOpenOption.CREATE_NEW);
114129

115130
// mock to watch internal calls
@@ -122,6 +137,21 @@ public void testStageArchive_java11StandardPath() throws IOException, AppEngineE
122137

123138
@Test
124139
public void testStageArchive_java11StandardBinaryPath() throws IOException, AppEngineException {
140+
stageArchive_gen2StandardBinaryPath("java11");
141+
}
142+
143+
@Test
144+
public void testStageArchive_java17StandardBinaryPath() throws IOException, AppEngineException {
145+
stageArchive_gen2StandardBinaryPath("java17");
146+
}
147+
148+
@Test
149+
public void testStageArchive_java21StandardBinaryPath() throws IOException, AppEngineException {
150+
stageArchive_gen2StandardBinaryPath("java21");
151+
}
152+
153+
private void stageArchive_gen2StandardBinaryPath(String runtime)
154+
throws IOException, AppEngineException {
125155
config =
126156
AppYamlProjectStageConfiguration.builder()
127157
.appEngineDirectory(appEngineDirectory)
@@ -132,7 +162,7 @@ public void testStageArchive_java11StandardBinaryPath() throws IOException, AppE
132162

133163
Files.write(
134164
appEngineDirectory.resolve("app.yaml"),
135-
"runtime: java11\nentrypoint: anything\n".getBytes(StandardCharsets.UTF_8),
165+
("runtime: " + runtime + "\nentrypoint: anything\n").getBytes(StandardCharsets.UTF_8),
136166
StandardOpenOption.CREATE_NEW);
137167

138168
// mock to watch internal calls
@@ -145,6 +175,20 @@ public void testStageArchive_java11StandardBinaryPath() throws IOException, AppE
145175

146176
@Test
147177
public void testStageArchive_java11BinaryWithoutEntrypoint() throws IOException {
178+
stageArchive_gen2BinaryWithoutEntrypoint("java11");
179+
}
180+
181+
@Test
182+
public void testStageArchive_java17BinaryWithoutEntrypoint() throws IOException {
183+
stageArchive_gen2BinaryWithoutEntrypoint("java17");
184+
}
185+
186+
@Test
187+
public void testStageArchive_java21BinaryWithoutEntrypoint() throws IOException {
188+
stageArchive_gen2BinaryWithoutEntrypoint("java21");
189+
}
190+
191+
private void stageArchive_gen2BinaryWithoutEntrypoint(String runtime) throws IOException {
148192
Path nonJarArtifact = temporaryFolder.newFile("myscript.sh").toPath();
149193
config =
150194
AppYamlProjectStageConfiguration.builder()
@@ -156,7 +200,7 @@ public void testStageArchive_java11BinaryWithoutEntrypoint() throws IOException
156200

157201
Files.write(
158202
appEngineDirectory.resolve("app.yaml"),
159-
"runtime: java11\n".getBytes(StandardCharsets.UTF_8),
203+
("runtime: " + runtime + "\n").getBytes(StandardCharsets.UTF_8),
160204
StandardOpenOption.CREATE_NEW);
161205

162206
AppYamlProjectStaging testStaging = new AppYamlProjectStaging();
@@ -166,8 +210,10 @@ public void testStageArchive_java11BinaryWithoutEntrypoint() throws IOException
166210
fail();
167211
} catch (AppEngineException ex) {
168212
assertEquals(
169-
"Cannot process application with runtime: java11/java17. A custom entrypoint must be defined in your app.yaml for non-jar artifact: "
170-
+ nonJarArtifact.toString(),
213+
"Cannot process application with runtime: "
214+
+ runtime
215+
+ ". A custom entrypoint must be defined in your app.yaml for non-jar artifact: "
216+
+ config.getArtifact().toString(),
171217
ex.getMessage());
172218
}
173219
}

src/test/java/com/google/cloud/tools/appengine/operations/DevServersRunnerTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.mockito.junit.MockitoJUnitRunner;
4040

4141
@RunWith(MockitoJUnitRunner.class)
42+
@SuppressWarnings("NullAway")
4243
public class DevServersRunnerTest {
4344

4445
@Rule public TemporaryFolder testFolder = new TemporaryFolder();

src/test/java/com/google/cloud/tools/appengine/operations/cloudsdk/PathResolverTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.junit.rules.TemporaryFolder;
3535
import org.mockito.Mockito;
3636

37+
@SuppressWarnings("NullAway")
3738
public class PathResolverTest {
3839

3940
@ClassRule public static TemporaryFolder symlinkTestArea = new TemporaryFolder();

0 commit comments

Comments
 (0)