简体   繁体   中英

tomcat ssl client handshake java error

The error: on the ssl handshake with the ssl server. After: client hello, server hello, certificate, server key exchange and server hello done. The web apps crashes with: java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b

The problem occurs on:
tomcat 6.0.29

Tried the following JVM:
1.5, 1.6_22, 1.6_25
now running:
java -version java version "1.6.0_25" Java(TM) SE Runtime Environment (build 1.6.0_25-b06) Java HotSpot(TM) Server VM (build 20.0-b11, mixed mode)

Operating System:
uname -a
SunOS hostname 5.10 Generic_118833-33 sun4v sparc sun4v

More details:

The stacktrace:

java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b
    javax.crypto.KeyGenerator.a(DashoA13*..)
javax.crypto.KeyGenerator.<init>(DashoA13*..)
javax.crypto.KeyGenerator.getInstance(DashoA13*..)
com.sun.net.ssl.internal.ssl.JsseJce.getKeyGenerator(JsseJce.java:223)
com.sun.net.ssl.internal.ssl.RSAClientKeyExchange.<init>(RSAClientKeyExchange.java:89)
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:744)
com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:238)
com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632)
com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:73)
com.gosselinchristian.SSLPokeServlet.doGet(SSLPokeServlet.java:86)

The code:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    try {

        System.out.println(getClasspathString());
        System.out.println(getPropertiesString());

        SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
                .getDefault();
        SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
                "some_server", 443);

        InputStream in = sslsocket.getInputStream();
        OutputStream out = sslsocket.getOutputStream();



        // Write a test byte to get a reaction :)
        out.write(1);

        while (in.available() > 0) {
            System.out.print(in.read());
        }

        System.out.println("Successfully connected");

    } catch (Exception exception) {
        exception.printStackTrace();
    }
}

Some tomcat startup options:

JAVA_OPTS='-server -Dapp.name=TEST -Dfile.encoding=ISO-8859-1 -XX:PermSize=128m  -XX:MaxPermSize=128m -Xms512m -Xmx2048m -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.ssl.trustStore=/export/home/user/some_server_certs -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.debug=all'

The same code, same jvm, same certificate works in other environments. Anyone has an idea of where this can go wrong?

-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol

Get rid of that for a start, it is seven years out of date. It was for JDK 1.3 only.

There is something wrong with your JRE installation. Reinstall, and then make sure Tomcat is using the newly installed version.

The javax.crypto.SunJCE_b class resides in <JAVA_HOME>/lib/jce.jar of the Sun JDK/JRE. It should ideally be loaded by the bootstrap classloader. The failure to load this class indicates something amiss with the classloading mechanism for your web-application, and possibly for Tomcat as well.

You might want to check

  • if the JRE/JDK contains this JAR.
  • if the CLASSPATH variable is being set in a manner, that causes a different archive to be loaded, or not be loaded at all. This point usually doesn't apply as the bootstrap classloader should load the class, instead of the system classloader (which relies on this environment variable).
  • if any of your applications is using AOP-style techniques to instrument the javax.crypto.* classes. You might want to configure such an application to exclude these classes (primarily) from instrumentation. In short, verify for custom classloader implementations.

This is an old post, but I'm just responding anyway, in case it's relevant for others who stumble upon this. We have encountered this error on our servers, and the issue was actually related to the open file limit. Check your open file limit. If it's something like 1024 then you probably have the same issue. Increase your open file limit for the user that Tomcat is running as.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM