PowerMock java.lang.ClassCastException: sun.net.www.protocol.https.HttpsURLConnectionImpl cannot be cast to javax.net.ssl.HttpsURLConnection

Donal Lafferty

I created a mock HttpsURLConnection based on an StackExchange answer:

import java.net.URL;
import javax.net.ssl.HttpsURLConnection;

...

@RunWith(PowerMockRunner.class)
public class DialogTest {
    public void mockHttpsUrlConnectionExample() throws Exception
    {
        URL mockUrl = PowerMockito.mock(URL.class);
        PowerMockito.whenNew(URL.class).withAnyArguments().thenReturn(mockUrl);
        HttpsURLConnection mockUrlConnection = PowerMockito.mock(HttpsURLConnection.class);
        PowerMockito.when(mockUrl.openConnection()).thenReturn(mockUrlConnection);
        PowerMockito.when(mockUrlConnection.getResponseCode()).thenReturn(200);

        // Create and call my objects ...

    }
}

However, when I use it, I'm seeing a cast exception:

java.lang.ClassCastException: sun.net.www.protocol.https.HttpsURLConnectionImpl cannot be cast to javax.net.ssl.HttpsURLConnection

The problem lies in this code:

import java.net.URL;
import javax.net.ssl.HttpsURLConnection;

...

private Boolean sendRequest(String endpoint, JSONObject requestData, Boolean throwOnAuthException) throws JSONException, IOException {
    this.responseData = null;

    try {
        String serviceURI = getServiceURI();
        String dialogUri = String.format("%s%s", serviceURI, endpoint);
        URL url = new URL(dialogUri);

        // Exception source is this cast
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();

However, when I look at the source code, I see that sun.net.www.protocol.https.HttpsURLConnectionImpl implements javax.net.ssl.HttpsURLConnection

Any suggestions on how to remedy this problem?

Donal Lafferty

The issue a conflict between the regular class loader and PowerMock's

The drawback to PowerMock is the use of a custom class loader. This class loader can modify type signatures in a way that is incompatible with the default class loader.

In certain circumstances, instantiation by reflection will cause the default class loader to be used to load a type. That class loader will not know that a type has already be loaded by PowerMock, because of the use of different signatures. The result can be casting errors for objects that should implement the cast type.

To avoid this problem, first stop PowerMock from loading javax.net.ssl.HttpsURLConnection

To prevent the cast exception, use ensure javax.net.ssl.HttpsURLConnection is only loaded by one class loader. Since I cannot stop the regular class loader from being used, the best approach is to stop the PowerMock loader from acting using the @PowerMockIgnore annotation. E.g.

@PowerMockIgnore({"javax.net.ssl.*"})
@PrepareForTest(android.util.Log.class)
public class DialogTest {
...

The side effect is that PowerMock is no longer able to provide it's version of HttpsURLConnection

Next, expose HttpsURLConnection construction, and substitute a mock object

Introduce a factory for HttpsURLConnection. E.g.

public class HttpsUrlConnectionProvider {
    public HttpsURLConnection getHttpsURLConnection(String dialogUri) throws IOException {
        URL url = new URL(dialogUri);
        return (HttpsURLConnection) url.openConnection();
    }
}

Create a mock of the HttpsURLConnection object used for HTTP request E.g.

final HttpsURLConnection mockUrlConnection = PowerMockito.mock(HttpsURLConnection.class);
PowerMockito.when(mockUrlConnection, "getResponseCode").thenReturn(200);
PowerMockito.when(mockUrlConnection, "getOutputStream").thenReturn(outputStream);

// Replace the HttpsURLConnection factory with one that returns our mock HttpsURLConnection
HttpsUrlConnectionProvider mockConnFactory = new HttpsUrlConnectionProvider() {
    public HttpsURLConnection getHttpsURLConnection(String dialogUri) throws
            IOException {
       return mockUrlConnection;
    }
};
dialog.setHttpsUrlConnectionProvider(mockConnFactory);

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

java.lang.ClassCastException: com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl cannot be cast to javax.net.ssl.HttpsURLConnection

From Dev

java.lang.NoClassDefFoundError: sun/net/www/protocol/https/DefaultHostnameVerifier

From Dev

java.lang.ClassCastException: Cannot cast com.sun.faces.config.FacesInitializer to javax.servlet.ServletContainerInitializer

From Dev

java.lang.ClassCastException: com.sun.mail.handlers.multipart_mixed cannot be cast to javax.activation.DataContentHandler

From Dev

javax.net.ssl.SSLHandshakeException while HttpsURLConnection from java code

From Dev

Error ClassCastException: java.net.Socket can not be cast to javax.net.ssl.SSLSocket in the getPage method of the WebClient object (HtmlUnit)

From Dev

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class

From Dev

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class

From Dev

Java exception: java.lang.ClassCastException: javax.swing.Timer cannot be cast to javax.swing.JButton

From Dev

java.lang.ClassCastException: java.lang.String cannot be cast to javax.mail.Multipart

From Dev

java.lang.ClassCastException: javax.faces.component.StateHolderSaver cannot be cast to [Ljava.lang.Object;

From Dev

java.lang.ClassCastException: com.sun.proxy.$Proxy47 cannot be cast to

From Dev

java.lang.ClassCastException: org.glassfish.jersey.servlet.ServletContainer cannot be cast to javax.servlet.Servlet

From Dev

java.lang.ClassCastException: Servlet.Telnet cannot be cast to javax.servlet.Servlet

From Dev

javax.net.ssl.HttpsURLConnection when are the request fired

From Dev

java.lang.ClassCastException: com.sun.faces.facelets.compiler.UIInstructions cannot be cast to org.primefaces.model.menu.MenuElement

From Dev

Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy13 cannot be cast to CustomeClass

From Dev

java.lang.ClassCastException: cannot be cast to java.lang.Object

From Dev

java.lang.ClassCastException: oracle.j2ee.ws.saaj.soap.TextImpl cannot be cast to javax.xml.soap.SOAPElement

From Dev

java.lang.ClassCastException: org.hibernate.ejb.HibernatePersistence cannot be cast to javax.persistence.spi.PersistenceProvider in WebLogic

From Dev

java.lang.ClassCastException: oracle.j2ee.ws.saaj.soap.TextImpl cannot be cast to javax.xml.soap.SOAPElement

From Dev

java.lang.ClassCastException: org.hibernate.ejb.HibernatePersistence cannot be cast to javax.persistence.spi.PersistenceProvider in WebLogic

From Dev

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast

From Dev

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JTable$1 cannot be cast to javax.swing.table.DefaultTableModel

From Dev

Greenfoot: java.lang.ClassCastException: Obstacle cannot be cast to BallProjectile

From Dev

java.lang.ClassCastException: JedisConnectionFactory cannot be cast to ConnectionFactory

From Dev

java.lang.ClassCastException: DTOObject cannot be cast to DTOObject

From Dev

java.lang.ClassCastException: CLASS/Activity cannot be cast to MainActivity

From Dev

ClassCastException: JSONArray cannot be cast to java.lang.String[]

Related Related

  1. 1

    java.lang.ClassCastException: com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl cannot be cast to javax.net.ssl.HttpsURLConnection

  2. 2

    java.lang.NoClassDefFoundError: sun/net/www/protocol/https/DefaultHostnameVerifier

  3. 3

    java.lang.ClassCastException: Cannot cast com.sun.faces.config.FacesInitializer to javax.servlet.ServletContainerInitializer

  4. 4

    java.lang.ClassCastException: com.sun.mail.handlers.multipart_mixed cannot be cast to javax.activation.DataContentHandler

  5. 5

    javax.net.ssl.SSLHandshakeException while HttpsURLConnection from java code

  6. 6

    Error ClassCastException: java.net.Socket can not be cast to javax.net.ssl.SSLSocket in the getPage method of the WebClient object (HtmlUnit)

  7. 7

    java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class

  8. 8

    java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class

  9. 9

    Java exception: java.lang.ClassCastException: javax.swing.Timer cannot be cast to javax.swing.JButton

  10. 10

    java.lang.ClassCastException: java.lang.String cannot be cast to javax.mail.Multipart

  11. 11

    java.lang.ClassCastException: javax.faces.component.StateHolderSaver cannot be cast to [Ljava.lang.Object;

  12. 12

    java.lang.ClassCastException: com.sun.proxy.$Proxy47 cannot be cast to

  13. 13

    java.lang.ClassCastException: org.glassfish.jersey.servlet.ServletContainer cannot be cast to javax.servlet.Servlet

  14. 14

    java.lang.ClassCastException: Servlet.Telnet cannot be cast to javax.servlet.Servlet

  15. 15

    javax.net.ssl.HttpsURLConnection when are the request fired

  16. 16

    java.lang.ClassCastException: com.sun.faces.facelets.compiler.UIInstructions cannot be cast to org.primefaces.model.menu.MenuElement

  17. 17

    Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy13 cannot be cast to CustomeClass

  18. 18

    java.lang.ClassCastException: cannot be cast to java.lang.Object

  19. 19

    java.lang.ClassCastException: oracle.j2ee.ws.saaj.soap.TextImpl cannot be cast to javax.xml.soap.SOAPElement

  20. 20

    java.lang.ClassCastException: org.hibernate.ejb.HibernatePersistence cannot be cast to javax.persistence.spi.PersistenceProvider in WebLogic

  21. 21

    java.lang.ClassCastException: oracle.j2ee.ws.saaj.soap.TextImpl cannot be cast to javax.xml.soap.SOAPElement

  22. 22

    java.lang.ClassCastException: org.hibernate.ejb.HibernatePersistence cannot be cast to javax.persistence.spi.PersistenceProvider in WebLogic

  23. 23

    java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast

  24. 24

    Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JTable$1 cannot be cast to javax.swing.table.DefaultTableModel

  25. 25

    Greenfoot: java.lang.ClassCastException: Obstacle cannot be cast to BallProjectile

  26. 26

    java.lang.ClassCastException: JedisConnectionFactory cannot be cast to ConnectionFactory

  27. 27

    java.lang.ClassCastException: DTOObject cannot be cast to DTOObject

  28. 28

    java.lang.ClassCastException: CLASS/Activity cannot be cast to MainActivity

  29. 29

    ClassCastException: JSONArray cannot be cast to java.lang.String[]

HotTag

Archive