July 18, 2013

PowerMock and SSL Context : NoSuchAlgorithmException

I was  trying to unit test a method that's sending an HTTP message to a potentially secured URI. Therefore, somewhere in the process the javax SSL Context interface is used.

I obvisouly want to mock that call, because I'm testing the method and not the call itself. When ryunning the test, I get the exception below :

com....TechnicalException: java.security.NoSuchAlgorithmException: class configured for SSLContext: com.sun.net.ssl.internal.ssl.SSLContextImpl not a SSLContext

...

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:69)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:312)

at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)

at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTestInSuper(PowerMockJUnit49RunnerDelegateImpl.java:117)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl$PowerMockJUnit49MethodRunner.executeTest(PowerMockJUnit49RunnerDelegateImpl.java:77)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:285)

at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:91)

at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:210)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:123)

at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)

at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)

at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:125)

at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:102)

at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)

at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)

at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:684)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:391)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Caused by: java.security.NoSuchAlgorithmException: class configured for SSLContext: com.sun.net.ssl.internal.ssl.SSLContextImpl not a SSLContext

at sun.security.jca.GetInstance.checkSuperClass(GetInstance.java:242)

at sun.security.jca.GetInstance.getInstance(GetInstance.java:221)

at sun.security.jca.GetInstance.getInstance(GetInstance.java:147)

... 31 more




This is related to the SSLCOntext loading stuff from the upstream classloader - which is Power Mock's one when running the test.

Solution : use @PowerMockIgnore annotation on the top of your test class :

@PowerMockIgnore({"javax.net.ssl.*","javax.security.*"})

public class MessageProcessorTest { ... }


Found the solution thanks to this thread and that issue.
Edit : added javax.security as an exclusion for Apache HttpClient (thanks to William Darby comment - see below).

HTH

Mathieu.