Skip to content
This repository has been archived by the owner on May 30, 2024. It is now read-only.

LDClient fails to initialize when used with Azul Zulu 8.46 (OpenJDK 8.0.252) and newer #204

Closed
BradRoot opened this issue Aug 31, 2020 · 3 comments

Comments

@BradRoot
Copy link

BradRoot commented Aug 31, 2020

LDClient fails to initialize when used with Azul Zulu 8.46 (OpenJDK 8.0.252)+ and the runtime is configured with to run in FIPS mode with BouncyCastle cryptography providers.

Describe the bug
LDClient fails to initialize when used with Azul Zulu 8.46 (OpenJDK 8.0.252) and newer. This is due to a back-ported JDK 9 fix which causes OkHttp to detect the 8 runtime as 9. This is fixed in OkHttp 3.14.8+ and 4.6.0+. See square/okhttp#5970 for more information. The java-server-sdk library includes shadowed OkHttp classes.

To reproduce
Download Azul Zulu 8.46 (OpenJDK 8.0.252) and BouncyCastle FIPS libraries(https://www.azul.com/downloads/zulu-community/?version=java-8-lts&architecture=x86-64-bit&package=jdk, https://www.bouncycastle.org/fips-java/). Put these, as well as LD java-server-sdk 4.14.1 on the class path. Configure a custom java.security.override file:

jdk.tls.disabledAlgorithms=SSLv2Hello, SSLv3, TLSv1, RC4, MD5withRSA, DH keySize < 1024, EC keySize < 224, DES, 3DES
crypto.policy=unlimited
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider C:DEFRND[HMACSHA256];ENABLE{ALL};
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=sun.security.provider.Sun
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI
securerandom.source=file:/dev/urandom
jceks.key.serialFilter = org.bouncycastle.**;java.lang.Enum;java.security.KeyRep;
java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*

Run LDClientTest with Azul Zulu:
java -cp LDClientTest.class:bc-fips-1.0.1.jar:bcprov-jdk16-sahdow-1.38.jar:bctls-fips-1.0.4.jar:launchdarkly-java-server-sdk-4.14.1-patched.jar:launchdarkly-java-server-sdk-4.14.1-all.jar:. -Djava.security.properties=./java.security.override LDClientTest

import com.launchdarkly.client.LDClient;
import com.launchdarkly.client.LDUser;

class LDClientTest {
public static void main(String[] args) {
final String key = "my_sdk_key";
LDClient client = new LDClient(key);
System.out.println("Initialized: " + client.initialized());
LDUser user = new LDUser("1234");
System.out.println("Evaluated to: " + client.boolVariation("my.flag", user, true));
}
}

Expected behavior
The LDClient initializes and gets feature flag without issue.

Logs
Exception in thread "okhttp-eventsource-stream-[]-0" java.lang.AssertionError: unable to get selected protocols
at com.launchdarkly.shaded.okhttp3.internal.Util.assertionError(Util.java:504)
at com.launchdarkly.shaded.okhttp3.internal.platform.Jdk9Platform.getSelectedProtocol(Jdk9Platform.java:72)
at com.launchdarkly.shaded.okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:347)
at com.launchdarkly.shaded.okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:284)
at com.launchdarkly.shaded.okhttp3.internal.connection.RealConnection.connect(RealConnection.java:169)
at com.launchdarkly.shaded.okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:258)
at com.launchdarkly.shaded.okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at com.launchdarkly.shaded.okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at com.launchdarkly.shaded.okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at com.launchdarkly.shaded.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at com.launchdarkly.shaded.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.launchdarkly.shaded.okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at com.launchdarkly.shaded.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at com.launchdarkly.shaded.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.launchdarkly.shaded.okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at com.launchdarkly.shaded.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at com.launchdarkly.shaded.okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:127)
at com.launchdarkly.shaded.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at com.launchdarkly.shaded.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.launchdarkly.shaded.okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:257)
at com.launchdarkly.shaded.okhttp3.RealCall.execute(RealCall.java:93)
at com.launchdarkly.shaded.com.launchdarkly.eventsource.EventSource.connect(EventSource.java:270)
at com.launchdarkly.shaded.com.launchdarkly.eventsource.EventSource.access$1300(EventSource.java:54)
at com.launchdarkly.shaded.com.launchdarkly.eventsource.EventSource$2.run(EventSource.java:157)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.launchdarkly.shaded.okhttp3.internal.platform.Jdk9Platform.getSelectedProtocol(Jdk9Platform.java:62)
... 25 more
Caused by: java.lang.UnsupportedOperationException
at javax.net.ssl.SSLSocket.getApplicationProtocol(SSLSocket.java:691)
... 30 more

SDK version
4.14.1, 5.0.3

Language version, developer tools
Azul Zulu 8.46 (OpenJDK 8.0.252) and newer. BouncyCastle cryptography libraries.

OS/platform
Not OS-specific. Issue affects all OS platforms which run Azul Zulu.

Additional context
Can be resolved by explicitly declaring dependency on okhttp 3.14.8 (or newer) in java-server-sdk. java-server-sdk has transitive dependency on okhttp by way of okthttp-eventsource. An alternative would be to update the okhttp dependency in okhttp-eventsource 1.11.1, then update the okhttp-eventsource dependency in java-server-sdk.

@eli-darkly
Copy link
Contributor

Thanks for reporting this. It sounds like it should be a fairly straightforward change and if so, we'll release patch versions for both 4.x and 5.x.

This was referenced Sep 1, 2020
LaunchDarklyCI pushed a commit that referenced this issue Sep 1, 2020
…-tests

(5.0 - #3.6) improve data store test logic
@eli-darkly
Copy link
Contributor

We've just released patches for both 4.x and 5.x. I didn't go through your suggested steps to reproduce the problem before doing this, because updating OkHttp would be a desirable thing to do in any case and it's a known issue that's mentioned in their changelog. Could you let me know when you've had a chance to retest with the new release?

@BradRoot
Copy link
Author

BradRoot commented Sep 1, 2020

Tested 4.14.2 using the procedure outlined above and in our own internal E2E tests. Works great, thanks for the quick turn-around.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants