Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Immediate crash in release builds #411

Closed
farindk opened this issue Mar 8, 2020 · 7 comments
Closed

Immediate crash in release builds #411

farindk opened this issue Mar 8, 2020 · 7 comments

Comments

@farindk
Copy link

farindk commented Mar 8, 2020

The library gives me the following crash on the first call. I tried to trace down the exact location where the crash happens, but ultimately, it seems to be in some static class initialization code somewhere in HttpConnectionManager or that area.

This only happens when building with proguard enabled, but I think I kept all apache related classes (see my config file below). It is also interesting that this crashes only on my Samsung S8 (Android 9), but not on the Nexus 5 (Android 6). Hence, I don't believe it is simply a missing class, but rather some code error.

I also tried old versions down to 1.3.0, but get the same error, which is strange because I was building this without this problem in April 2019. Hence, the issue might only occur with current versions of Android studio (v3.6.1).

Spent a whole day and night on this and am completely stuck.
Will have to remove Nextcloud support from my software until this is resolved.

Crash:

03-08 03:09:28.773 25982 26053 E AndroidRuntime: java.lang.ExceptionInInitializerError
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at com.owncloud.android.lib.common.OwnCloudClientFactory.createOwnCloudClient(SourceFile:18)
...
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at java.lang.Thread.run(Thread.java:764)
03-08 03:09:28.773 25982 26053 E AndroidRuntime: Caused by: org.apache.commons.logging.LogConfigurationException: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference (Caused by java.lang.NullPointerException: Attempt to invoke virtual\
 method 'java.lang.String java.lang.String.trim()' on a null object reference)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(SourceFile:7)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(SourceFile:3)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(SourceFile:1)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.logging.LogFactory.getLog(SourceFile:1)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.httpclient.HttpClient.<clinit>(SourceFile:1)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        ... 5 more
03-08 03:09:28.773 25982 26053 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(SourceFile:27)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(SourceFile:19)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(SourceFile:2)
03-08 03:09:28.773 25982 26053 E AndroidRuntime:        ... 9 more

proguard config (it's an enhanced version of a config previously posted here):

# Nextcloud
-keep,allowshrinking class com.owncloud.android.** { *; }
-keep,allowshrinking class org.parceler.** { *; }
-keep,allowshrinking class org.slf4j.** { *; }
-keep class org.apache.** { *; }

# --- these have no effect
#-keep class org.** { *; }
#-keep class javax.** { *; }
#-keep class com.squareup.**
#-keep class org.jetbrains.**
#-keep class twitter4j.** { *; }

# --- these options also have no effect
#-dontshrink
#-dontoptimize
#-dontpreverify
#-verbose


-dontwarn com.owncloud.android.lib.**
-dontwarn org.apache.jackrabbit.webdav.**
-dontwarn org.slf4j.**

-dontskipnonpubliclibraryclasses

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keepattributes InnerClasses
#end nextcloud

gradle:

configurations.all {
    exclude group: "log4j", module: "log4j"
    exclude group: 'org.slf4j', module: 'jcl-over-slf4j'

    exclude group: 'com.google.guava', module: 'listenablefuture'
}

...
    implementation project(":libs:nextcloud-android-library")
    implementation "commons-httpclient:commons-httpclient:3.1@jar" // remove after entire switch to lib v2
...
    implementation('com.google.api-client:google-api-client-android:1.26.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') {
        exclude group: 'org.apache.httpcomponents'
    }
...
@farindk
Copy link
Author

farindk commented Mar 8, 2020

PS: the issue might be due to a conflict with the Google Drive SDK or Android built-in classes.
If I REMOVE the Drive dependencies

/*
    implementation 'com.google.android.gms:play-services-auth:16.0.1'
    implementation 'com.google.http-client:google-http-client-gson:1.26.0'
    implementation('com.google.api-client:google-api-client-android:1.26.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') {
        exclude group: 'org.apache.httpcomponents'
    }
*/

I get the exception

03-08 12:08:28.410 30294 30714 E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/commons/logging/LogFactory;
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at org.apache.commons.httpclient.HttpClient.<clinit>(SourceFile:1)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at com.owncloud.android.lib.common.OwnCloudClientFactory.createOwnCloudClient(SourceFile:18)
...
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:764)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.commons.logging.LogFactory" on path: DexPathList[[zip file "/data/app/de.dirkfarin.imagemeterpro-YcKEFFUAhbTp0abHLMfXJw==/base.apk"],nativeLibraryDirectories=[/data/app/de.dirkfarin.imagemeterpro-YcKEFFUAhbTp0abHLMfXJw==/lib/arm64, /data/app/de.dirkfarin.imagemeterpro-YcKEFFUAhbTp0abHLMfXJw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/vendor/lib64]]
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	... 6 more

However, if I try to add this line to gradle:

implementation 'commons-logging:commons-logging:1.2'

It doesn't compile because of

Error: commons-logging defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for httpclient use HttpUrlConnection or okhttp instead), or repackaging the library using something like jarjar. [DuplicatePlatformClasses]

Sounds to me that there are several implementations of some classes floating around that do not fit together.

1 similar comment
@farindk
Copy link
Author

farindk commented Mar 8, 2020

PS: the issue might be due to a conflict with the Google Drive SDK or Android built-in classes.
If I REMOVE the Drive dependencies

/*
    implementation 'com.google.android.gms:play-services-auth:16.0.1'
    implementation 'com.google.http-client:google-http-client-gson:1.26.0'
    implementation('com.google.api-client:google-api-client-android:1.26.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') {
        exclude group: 'org.apache.httpcomponents'
    }
*/

I get the exception

03-08 12:08:28.410 30294 30714 E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/commons/logging/LogFactory;
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at org.apache.commons.httpclient.HttpClient.<clinit>(SourceFile:1)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at com.owncloud.android.lib.common.OwnCloudClientFactory.createOwnCloudClient(SourceFile:18)
...
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:764)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "org.apache.commons.logging.LogFactory" on path: DexPathList[[zip file "/data/app/de.dirkfarin.imagemeterpro-YcKEFFUAhbTp0abHLMfXJw==/base.apk"],nativeLibraryDirectories=[/data/app/de.dirkfarin.imagemeterpro-YcKEFFUAhbTp0abHLMfXJw==/lib/arm64, /data/app/de.dirkfarin.imagemeterpro-YcKEFFUAhbTp0abHLMfXJw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/vendor/lib64]]
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
03-08 12:08:28.410 30294 30714 E AndroidRuntime: 	... 6 more

However, if I try to add this line to gradle:

implementation 'commons-logging:commons-logging:1.2'

It doesn't compile because of

Error: commons-logging defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for httpclient use HttpUrlConnection or okhttp instead), or repackaging the library using something like jarjar. [DuplicatePlatformClasses]

Sounds to me that there are several implementations of some classes floating around that do not fit together.

@farindk
Copy link
Author

farindk commented Mar 8, 2020

Found a workaround for the problem. It's similar to the AWS problem described here: aws-amplify/aws-sdk-android#476

Adding the following statement to the Manifest at least provides a workaround that seems to work for me:

<uses-library
            android:name="org.apache.http.legacy"
            android:required="false"/>

@AndyScherzinger
Copy link
Member

Thanks for the detailed and thorough analysis of your issue @farindk 🙏

@tobiasKaminsky fancy taking a look? ❤️

@tobiasKaminsky
Copy link
Member

Adding the following statement to the Manifest at least provides a workaround that seems to work for me:

<uses-library
            android:name="org.apache.http.legacy"
            android:required="false"/>

Can you try this instead? #371
I think that we need right now the legacy system…

@farindk
Copy link
Author

farindk commented Mar 9, 2020

I had the gradle options from #371 already in my files (see original comment at the top of this issue).
So that does not solve it.

I still use OwnCloudClient. Does that make a difference? Haven't seen that there is now a NextcloudClient. However, I do not see a NextcloudClientFactory and I also need OwnCloudClientManagerFactory to set the UserAgent. Might be too early for me to switch to a new API.

@tobiasKaminsky
Copy link
Member

NextcloudClient is only for one api request, so there is no possibility to switch…

I had the gradle options from #371 already in my files (see original comment at the top of this issue).
So that does not solve it.

Then I add this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants