Skip to content

Commit e489f4d

Browse files
committed
Import of Cloud Functions JVM from Git-on-Borg.
- 0b5e0e335b3a58b848eebae4c025926e0aa9d33f Fix warnings about reflection on platform classes. by Éamonn McManus <[email protected]> PiperOrigin-RevId: 288948744
1 parent 3fa709f commit e489f4d

File tree

2 files changed

+40
-29
lines changed

2 files changed

+40
-29
lines changed

invoker-core/core/src/main/java/com/google/cloud/functions/invoker/http/HttpResponseImpl.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
import java.io.BufferedWriter;
77
import java.io.IOException;
88
import java.io.OutputStream;
9-
import java.io.PrintWriter;
10-
import java.io.Writer;
11-
import java.lang.reflect.Field;
129
import java.util.AbstractMap.SimpleEntry;
1310
import java.util.ArrayList;
1411
import java.util.Collection;
@@ -70,26 +67,14 @@ public OutputStream getOutputStream() throws IOException {
7067

7168
@Override
7269
public synchronized BufferedWriter getWriter() throws IOException {
73-
if (writer != null) {
74-
return writer;
70+
if (writer == null) {
71+
// Unfortunately this means that we get two intermediate objects between the object we return
72+
// and the underlying Writer that response.getWriter() wraps. We could try accessing the
73+
// PrintWriter.out field via reflection, but that sort of access to non-public fields of
74+
// platform classes is now frowned on and may draw warnings or even fail in subsequent
75+
// versions.
76+
writer = new BufferedWriter(response.getWriter());
7577
}
76-
// We could just wrap a BufferedWriter around the PrintWriter that the Servlet API gives us,
77-
// but this slightly clunky alternative potentially avoids two intermediate objects in the
78-
// writer chain.
79-
PrintWriter printWriter = response.getWriter();
80-
Writer wrappedWriter;
81-
try {
82-
// This is a protected field, so it is part of the documented API and we know it will be
83-
// there, but we need to use reflection to get at it.
84-
Field outField = PrintWriter.class.getDeclaredField("out");
85-
outField.setAccessible(true);
86-
wrappedWriter = (Writer) outField.get(printWriter);
87-
} catch (ReflectiveOperationException e) {
88-
throw new IOException("Reflection failed", e);
89-
}
90-
this.writer = (wrappedWriter instanceof BufferedWriter)
91-
? (BufferedWriter) wrappedWriter
92-
: new BufferedWriter(wrappedWriter);
93-
return this.writer;
78+
return writer;
9479
}
9580
}

invoker-core/core/src/test/java/com/google/cloud/functions/invoker/IntegrationTest.java

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import java.util.List;
2929
import java.util.Map;
3030
import java.util.concurrent.CountDownLatch;
31+
import java.util.concurrent.ExecutorService;
32+
import java.util.concurrent.Executors;
33+
import java.util.concurrent.Future;
3134
import java.util.concurrent.TimeUnit;
3235
import java.util.regex.Pattern;
3336
import org.eclipse.jetty.client.HttpClient;
@@ -47,6 +50,8 @@ public class IntegrationTest {
4750

4851
private static final String SERVER_READY_STRING = "Started ServerConnector";
4952

53+
private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
54+
5055
private static int serverPort;
5156

5257
/**
@@ -264,7 +269,7 @@ private void testFunction(
264269
String target,
265270
ImmutableList<String> extraArgs,
266271
TestCase... testCases) throws Exception {
267-
Process server = startServer(signatureType, target, extraArgs);
272+
ServerProcess serverProcess = startServer(signatureType, target, extraArgs);
268273
try {
269274
HttpClient httpClient = new HttpClient();
270275
httpClient.start();
@@ -280,9 +285,11 @@ private void testFunction(
280285
assertThat(response.getContentAsString()).isEqualTo(testCase.expectedResponseText());
281286
}
282287
} finally {
283-
server.destroy();
284-
server.waitFor();
288+
serverProcess.close();
285289
}
290+
// Wait for the output monitor task to terminate. If it threw an exception, we will get an
291+
// ExecutionException here.
292+
serverProcess.outputMonitorResult().get();
286293
}
287294

288295
private enum SignatureType {
@@ -301,7 +308,22 @@ public String toString() {
301308
}
302309
}
303310

304-
private Process startServer(
311+
@AutoValue
312+
abstract static class ServerProcess implements AutoCloseable {
313+
abstract Process process();
314+
abstract Future<?> outputMonitorResult();
315+
316+
static ServerProcess of(Process process, Future<?> outputMonitorResult) {
317+
return new AutoValue_IntegrationTest_ServerProcess(process, outputMonitorResult);
318+
}
319+
320+
@Override
321+
public void close() {
322+
process().destroy();
323+
}
324+
}
325+
326+
private ServerProcess startServer(
305327
SignatureType signatureType, String target, ImmutableList<String> extraArgs)
306328
throws IOException, InterruptedException {
307329
File javaHome = new File(System.getProperty("java.home"));
@@ -325,10 +347,11 @@ private Process startServer(
325347
processBuilder.environment().putAll(environment);
326348
Process serverProcess = processBuilder.start();
327349
CountDownLatch ready = new CountDownLatch(1);
328-
new Thread(() -> monitorOutput(serverProcess.getInputStream(), ready)).start();
350+
Future<?> outputMonitorResult = EXECUTOR.submit(
351+
() -> monitorOutput(serverProcess.getInputStream(), ready));
329352
boolean serverReady = ready.await(5, TimeUnit.SECONDS);
330353
assertWithMessage("Waiting for server to be ready").that(serverReady).isTrue();
331-
return serverProcess;
354+
return ServerProcess.of(serverProcess, outputMonitorResult);
332355
}
333356

334357
private void monitorOutput(InputStream processOutput, CountDownLatch ready) {
@@ -339,6 +362,9 @@ private void monitorOutput(InputStream processOutput, CountDownLatch ready) {
339362
ready.countDown();
340363
}
341364
System.out.println(line);
365+
if (line.contains("WARNING")) {
366+
throw new AssertionError("Found warning in server output:\n" + line);
367+
}
342368
}
343369
} catch (IOException e) {
344370
e.printStackTrace();

0 commit comments

Comments
 (0)