Thursday, May 31, 2012

java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b in SSL HTTPS Solved


log4j:WARN No appenders could be found for logger (org.springframework.web.client.RestTemplate).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class javax.crypto.SunJCE_b
at javax.crypto.KeyGenerator.a(DashoA13*..)
at javax.crypto.KeyGenerator.(DashoA13*..)
at javax.crypto.KeyGenerator.getInstance(DashoA13*..)
at com.sun.net.ssl.internal.ssl.JsseJce.getKeyGenerator(JsseJce.java:223)
at com.sun.net.ssl.internal.ssl.RSAClientKeyExchange.(RSAClientKeyExchange.java:89)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:744)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:238)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
at org.springframework.http.client.SimpleClientHttpRequest.executeInternal(SimpleClientHttpRequest.java:69)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:52)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:438)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:401)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:377)
at com.test.TestSecureHTTP.main(TestSecureHTTP.java:42)




I received the above error when i was trying to call a RESTFUL Webservice using restTemplate.exchange. 


REASON FOR THIS : Sun has changed the location of SUNJCE_b in Java 6 and above so it is no more able to find this class in the path specified as HTTPClient which underlies resttemplate is searching for this class in wrong package. 


SOLUTION:
I tried fixing this by adding old jce.jar which contains the class above JDK in Eclipse configure build path setting but it dis not work . 


Finally i got the code working by adding the following lines of code in my program

             try {
Class.forName("javax.crypto.SunJCE_b");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Complete program below



package com.test;


import java.util.Properties;


import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;


import com.cisco.swtg.bss.util.Base64Coder;


public class TestSecureHTTP {

public static void main(String[] args) {

Properties props= new Properties();
props.put("javax.net.ssl.trustStoreType","jks");
   props.put("javax.net.ssl.trustStore","C:\\trust.jks");

   props.put("java.home", "C:\\Program Files\\Java\\jdk1.7.0_04");
   try {
Class.forName("javax.crypto.SunJCE_b");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
   System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
   props.put("javax.net.ssl.trustStorePassword","changeit");
   System.setProperties(props);
   HttpHeaders entityHeaders = new HttpHeaders();


entityHeaders.set("content-type", "application/json");

HttpEntity requestEntity = new HttpEntity(entityHeaders);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity result= restTemplate.exchange("THE URL", HttpMethod.GET, requestEntity, String.class);
System.out.println(result.getBody());

   
}


}


No comments: