TakahikoKawasaki / nv-websocket-client

High-quality WebSocket client implementation in Java.
Apache License 2.0
2.03k stars 292 forks source link

Crashes on API < 24 with new AGP that is needed for API 33 #242

Open polivmi1 opened 2 years ago

polivmi1 commented 2 years ago

Linking to work done in https://github.com/TakahikoKawasaki/nv-websocket-client/pull/225

For some reason, AGP included these dependencies also for lower versions, but the newest build system removes them and we shouldn't call them on API < 24:

@TakahikoKawasaki this PR doesn't seem to fix the issue as `private static void initialize() throws Exception { // Constructor which represents javax.net.ssl.SNIHostName(String). // The class is available since Java 1.8 / Android API Level 24 (Android 7.0) sSNIHostNameConstructor = Misc.getConstructor( "javax.net.ssl.SNIHostName", new Class<?>[] { String.class });

    // Method which represents javax.net.ssl.SSLParameters.setServerNames(List<SNIServerName>).
    // The method is available since Java 1.8 / Android API Level 24 (Android 7.0)
    sSetServerNamesMethod = Misc.getMethod(
            "javax.net.ssl.SSLParameters", "setServerNames", new Class<?>[] { List.class });
}`

is still called. This causes a crash on the newest AGP used with Android 33 - 7.3.x

java.lang.NoClassDefFoundError at javax.net.ssl.SNIServerName.<clinit>(Unknown Source) at java.lang.Class.classForName(Native Method) at java.lang.Class.forName(Class.java:308) at java.lang.Class.forName(Class.java:272)

and NoClassDefFoundError is an Error and not an exception

https://developer.android.com/reference/javax/net/ssl/SNIServerName was added with API 24

A fix is to either catch the error, or better prevent this code to run on API < 24

andrew-ld commented 1 year ago

https://github.com/TakahikoKawasaki/nv-websocket-client/blob/f9cc33032851edae4115f17417201e78f144db0d/src/main/java/com/neovisionaries/ws/client/SNIHelper.java#L102

polivmi1 commented 1 year ago

@andrew-ld this is true, but because https://github.com/TakahikoKawasaki/nv-websocket-client/blob/f9cc33032851edae4115f17417201e78f144db0d/src/main/java/com/neovisionaries/ws/client/SNIHelper.java#L56 is called in the initialization and that method isn't available for < 24, it will throw a NoClassDefFoundError which isn't caught. So my suggestion is to either catch this or better remove the code for API < 24

andrew-ld commented 1 year ago

there is a try catch in static initialization

https://github.com/TakahikoKawasaki/nv-websocket-client/blob/f9cc33032851edae4115f17417201e78f144db0d/src/main/java/com/neovisionaries/ws/client/SNIHelper.java#L34-L44

polivmi1 commented 1 year ago

@andrew-ld as I wrote in the first message, that catch is useless, because NoClassDefFoundError is an Error and not an exception, so it will not catch it.

andrew-ld commented 1 year ago

I missed the point, you are right, it should be handled directly throwable to avoid future problems.

polivmi1 commented 1 year ago

@andrew-ld will you be able to add it or should I create a PR? It looks like the repository is dead...

yandeqing commented 1 year ago

Linking to work done in #225

I download the source project add it to my project then skip the "initialize" method on API < 24

like

    private static void initialize() throws Exception {
        if (Build.VERSION.SDK_INT < 24) {
            Log.e("SNIHelper", "The class is available since Java 1.8 / Android API Level 24 (Android 7.0)");
            return;
        }
        // Constructor which represents javax.net.ssl.SNIHostName(String).
        // The class is available since Java 1.8 / Android API Level 24 (Android 7.0)
        sSNIHostNameConstructor = Misc.getConstructor(
                "javax.net.ssl.SNIHostName", new Class<?>[]{String.class});

        // Method which represents javax.net.ssl.SSLParameters.setServerNames(List<SNIServerName>).
        // The method is available since Java 1.8 / Android API Level 24 (Android 7.0)
        sSetServerNamesMethod = Misc.getMethod(
                "javax.net.ssl.SSLParameters", "setServerNames", new Class<?>[]{List.class});
    }
yandeqing commented 1 year ago

there is a try catch in static initialization

https://github.com/TakahikoKawasaki/nv-websocket-client/blob/f9cc33032851edae4115f17417201e78f144db0d/src/main/java/com/neovisionaries/ws/client/SNIHelper.java#L34-L44

static 
 { 
     try 
     { 
        if (Build.VERSION.SDK_INT < 24) {
            return;
        }
         initialize(); 
     } 
     catch (Exception e) 
     { 
         e.printStackTrace(); 
     } 
 }