diff --git a/context/build.gradle b/context/build.gradle index ed3a8d3b2f..67c5e1d327 100644 --- a/context/build.gradle +++ b/context/build.gradle @@ -2,5 +2,6 @@ description = 'gRPC: Context' dependencies { testCompile project(':grpc-testing') + testCompile project(':grpc-core').sourceSets.test.output signature "org.codehaus.mojo.signature:java16:1.1@signature" } diff --git a/context/src/test/java/io/grpc/ContextTest.java b/context/src/test/java/io/grpc/ContextTest.java index cb1fad61ba..c20d41afc4 100644 --- a/context/src/test/java/io/grpc/ContextTest.java +++ b/context/src/test/java/io/grpc/ContextTest.java @@ -45,6 +45,7 @@ import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; +import java.util.regex.Pattern; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -745,4 +746,52 @@ public class ContextTest { assertTrue(context.isCancelled()); assertThat(context.cancellationCause(), instanceOf(TimeoutException.class)); } + + /** + * Tests initializing the {@link Context} class with a custom logger which uses Context's storage + * when logging. + */ + @Test + public void initContextWithCustomClassLoaderWithCustomLogger() throws Exception { + StaticTestingClassLoader classLoader = + new StaticTestingClassLoader( + getClass().getClassLoader(), + Pattern.compile("(io\\.grpc\\.Context.*)|(io\\.grpc\\.ThreadLocalContextStorage.*)")); + Class runnable = + classLoader.loadClass(LoadMeWithStaticTestingClassLoader.class.getName()); + + ((Runnable) runnable.getDeclaredConstructor().newInstance()).run(); + } + + // UsedReflectively + public static final class LoadMeWithStaticTestingClassLoader implements Runnable { + @Override + public void run() { + Logger logger = Logger.getLogger(Context.class.getName()); + logger.setLevel(Level.ALL); + Handler handler = new Handler() { + @Override + public void publish(LogRecord record) { + Context ctx = Context.current(); + Context previous = ctx.attach(); + ctx.detach(previous); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + logger.addHandler(handler); + + try { + assertNotNull(Context.ROOT); + } finally { + logger.removeHandler(handler); + } + } + } }