|
97 | 97 | import java.util.concurrent.TimeUnit; |
98 | 98 | import javax.net.ssl.SSLException; |
99 | 99 | import javax.net.ssl.SSLHandshakeException; |
| 100 | +import javax.net.ssl.TrustManagerFactory; |
100 | 101 | import org.junit.After; |
101 | 102 | import org.junit.Before; |
102 | 103 | import org.junit.Rule; |
@@ -687,16 +688,32 @@ public void run() { |
687 | 688 | return settableFuture; |
688 | 689 | } |
689 | 690 |
|
690 | | - private void setTrustStoreSystemProperties(String trustStoreFilePath) { |
| 691 | + private void setTrustStoreSystemProperties(String trustStoreFilePath) throws Exception { |
691 | 692 | System.setProperty("javax.net.ssl.trustStore", trustStoreFilePath); |
692 | 693 | System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); |
693 | 694 | System.setProperty("javax.net.ssl.trustStoreType", "JKS"); |
| 695 | + createDefaultTrustManager(); |
694 | 696 | } |
695 | 697 |
|
696 | | - private void clearTrustStoreSystemProperties() { |
| 698 | + private void clearTrustStoreSystemProperties() throws Exception { |
697 | 699 | System.clearProperty("javax.net.ssl.trustStore"); |
698 | 700 | System.clearProperty("javax.net.ssl.trustStorePassword"); |
699 | 701 | System.clearProperty("javax.net.ssl.trustStoreType"); |
| 702 | + createDefaultTrustManager(); |
| 703 | + } |
| 704 | + |
| 705 | + /** |
| 706 | + * Workaround the JDK's TrustManagerStore race. TrustManagerStore has a cache for the default |
| 707 | + * certs based on the system properties. But updating the cache is not thread-safe and can cause a |
| 708 | + * half-updated cache to appear fully-updated. When both the client and server initialize their |
| 709 | + * trust store simultaneously, one can see a half-updated value. Creating the trust manager here |
| 710 | + * fixes the cache while no other threads are running and thus the client and server threads won't |
| 711 | + * race to update it. See https://github.com/grpc/grpc-java/issues/11678. |
| 712 | + */ |
| 713 | + private void createDefaultTrustManager() throws Exception { |
| 714 | + TrustManagerFactory factory = |
| 715 | + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
| 716 | + factory.init((KeyStore) null); |
700 | 717 | } |
701 | 718 |
|
702 | 719 | private static class SimpleServiceImpl extends SimpleServiceGrpc.SimpleServiceImplBase { |
|
0 commit comments