Java NoClassDefFoundError с соединением SSL
У нас есть приложение, которое использует клиентскую библиотеку JAX-RPC и работает на устаревшей версии Java (1.4.2) и получает следующую ошибку SSL:
java.lang.NoClassDefFoundError
javax.crypto.Cipher.a(DashoA6275)
javax.crypto.Cipher.getInstance(DashoA6275)
com.sun.net.ssl.internal.ssl.SunJSSE_i.a(DashoA12275)
com.sun.net.ssl.internal.ssl.CipherBox$JCECipherBox.<init>(DashoA12275)
com.sun.net.ssl.internal.ssl.CipherRC4.a(DashoA12275)
com.sun.net.ssl.internal.ssl.SunJSSE_h.a(DashoA12275)
com.sun.net.ssl.internal.ssl.CipherSuite$BulkCipher.a(DashoA12275)
com.sun.net.ssl.internal.ssl.SunJSSE_ax.c(DashoA12275)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.f(DashoA12275)
com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA12275)
com.sun.net.ssl.internal.ssl.SunJSSE_az.j(DashoA12275)
com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA12275)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA12275)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(DashoA12275)
sun.net.www.protocol.https.HttpsClient.afterConnect(DashoA12275)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(DashoA12275)
sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:569)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(DashoA12275)
com.sun.xml.rpc.client.http.HttpClientTransport.writeMessageToConnection(HttpClientTransport.java:278)
com.sun.xml.rpc.client.http.HttpClientTransport.invoke(HttpClientTransport.java:64)
com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:69)
[ ... trace continues into internal application code ... ]
Это работало для нас раньше, и единственные изменения в клиентской библиотеке связаны с используемым протоколом аутентификации и требуют обновления до последней сборки BouncyCastle. Все эти изменения были на более высоком уровне, чем протокол SSL, и эта ошибка, по-видимому, даже не связана с BouncyCastle.
Кто-нибудь видел такую ошибку раньше и, возможно, есть какие-нибудь мысли или предложения? Я пытался добавить сертификат в cacerts
, Это прекрасно работает, если вы работаете с Java 1.6, однако, к сожалению, производственная система, в которой это работает, пока что привязана к Java 1.4.
Кроме того, наш код JAX-RPC и его аутентификация работают правильно, если мы подключаемся к нашим системам разработки без SSL.
[править - дополнительная информация] Теперь я вижу, что с новыми версиями BouncyCastle происходит конфликт, вызывающий проблему. Я попытался использовать древнюю (1.18) версию, и мне кажется, что я не получаю ошибку SSL, а вместо этого получаю ее из нашего приложения, потому что она требует более новых алгоритмов.
2 ответа
Итак, после долгих исследований я, наконец, обнаружил, что глубоко в нашем коде мы вставили поставщика BC в качестве поставщика номер 1.
Security.insertProviderAt(prov, 1);
Вместо того, чтобы делать это, просто добавив провайдера, исправили проблему.
Security.addProvider(prov);
javax.crypto.Cipher
находится в отдельном (от rt.jar) файле JAR с именем jce.jar. Возможно, загрузчик классов не может найти этот файл, или для этого сервера производственных приложений не заданы разрешения на чтение для этого файла.