I have updated my project's minSdkVersion from 19 to 21. This has caused an issue on 5.0/5.1 devices where I can't run the app. I keep getting a ClassNotFoundException on my Application class. The full log, Application class, and gradle file are below. If I revert my project back to minSdkVersion 19 then the app will run on 4.4+ with no problems.
What I have tried
Cleaning/Rebuilding
Updating and downgrading the build tools version
All support library's across projects have same version number
Making all my manifest classes relative and then absolute
Updated all Sdk and build tools
Log
04-27 14:37:07.152 6278-6278/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.package.testapp, PID: 6278
java.lang.RuntimeException: Unable to instantiate application com.package.TestApplication: java.lang.ClassNotFoundException: Didn't find class "com.package.Application" on path: DexPathList[[zip file "/data/app/com.package.testapp-1/base.apk"],nativeLibraryDirectories=[/data/app/com.package.testapp-1/lib/x86_64, /vendor/lib64, /system/lib64]]
at android.app.LoadedApk.makeApplication(LoadedApk.java:563)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4526)
at android.app.ActivityThread.access$1500(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.package.TestApplication" on path: DexPathList[[zip file "/data/app/com.package.testapp-1/base.apk"],nativeLibraryDirectories=[/data/app/com.package.testapp-1/lib/x86_64, /vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at android.app.Instrumentation.newApplication(Instrumentation.java:980)
at android.app.LoadedApk.makeApplication(LoadedApk.java:558)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4526)
at android.app.ActivityThread.access$1500(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Suppressed: java.lang.ClassNotFoundException: com.package.testapp.welcome.TestClaimApplication
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 13 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
Gradle
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion 25
buildToolsVersion '25.0.3'
defaultConfig {
applicationId "com.package.testapp"
minSdkVersion 21
multiDexEnabled = true
targetSdkVersion 25
versionCode 2
versionName "0.7"
renderscriptTargetApi 18 // support mode not supported 21+
renderscriptSupportModeEnabled true
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
dexOptions {
javaMaxHeapSize "4g"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
productFlavors {
companylocal
companymaven
}
}
dependencies {
def ext = rootProject.ext;
compile fileTree(include: ['*.jar'], dir: 'libs')
compile "com.android.support:appcompat-v7:${ext.supportLibraryVersion}"
compile "com.android.support:design:${ext.supportLibraryVersion}"
compile 'com.romandanylyk:pageindicatorview:0.0.9'
compile "com.jakewharton:butterknife:${ext.butterknifeLibraryVersion}"
annotationProcessor "com.jakewharton:butterknife-compiler:${ext.butterknifeLibraryVersion}"
compile "uk.co.chrisjenx:calligraphy:2.2.0"
compile 'com.android.support:multidex:1.0.1'
// Crashlytics Kit - for crash handling
compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') {
transitive = true
}
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.0'
testCompile "com.squareup.okhttp3:mockwebserver:${ext.okHttp3LibraryVersion}"
testCompile('com.squareup.assertj:assertj-android:1.1.1') {
exclude module: 'support-annotations'
}
}
Application
public class TestApplication extends Application {
Engine engine;
@Override
public void onCreate() {
super.onCreate();
String privateServerUrlLocal = getString(R.string.server_url);
ProfileLauncher profileLauncher = getProfileLauncher();
LoginLauncher loginLauncher = getLoginLauncher();
// Set up Crash Analytics
final CrashlyticsCore crashlyticsCore = new CrashlyticsCore.Builder().disabled(DEBUG).build();
Fabric.with(this, new Crashlytics.Builder().core(crashlyticsCore).build());
Intent intent = new Intent(this, LogoutService.class);
startService(intent);
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("")
.add("")
.build();
engine = new Engine.Builder(privateServerUrlLocal, getString(R.string.other_server_url))
.setCertificatePinner(certificatePinner)
.setSDKPartnerSetupManager(getSdkPartnerManager())
.setLogoutActionHandler(getLogoutActionHandler())
.setVLocationManager(new VLocationManagerImp())
.setDebug(DEBUG)
.addDeepLinkHandler(new ClaimDeepLinkHandler(loginLauncher, profileLauncher))
.addDeepLinkHandler(new LinkGiftCodeDeeplinkHandler(loginLauncher, profileLauncher))
.addDeepLinkHandler(new OpenLinkDeepLinkHandler())
.addDeepLinkHandler(new DetailsDeepLinkHandler())
.addClaimConfig(new ClaimConfig(false, false, false, false, true))
.build();
engine.startup(this);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
}
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.package.testapp">
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.flash"
android:required="false" />
<!-- Required for g+ login -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:name=".TestApplication"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name="com.package.companycommon.ui.LogoutService"
android:stopWithTask="true" />
<activity
android:name=".LaunchActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".welcome.WelcomeActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".RegisterActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".LoginActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ActivationActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".AddPhoneNumberActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ForgotPasswordActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".GiftHistoryActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name="com.package.PartnerLoginHiddenActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".tutorial.TutorialActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".CreateNewPasswordActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar.ClearStatus" />
<activity
android:name=".settings.SettingsActivity"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".GiftHistoryActivity" />
</activity>
<activity
android:name=".settings.ExtraSettingsActivity"
android:label="@string/settings"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".settings.SettingsActivity" />
</activity>
<activity
android:name="companyapp.company.NewsActivity"
android:label="@string/notifications"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name=".termsandconditions.CompanyTermsAndConditionsActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name="com.package.companycommon.ui.PhotoViewerActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name="com.package.company.details.CompanyDetailActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
<activity
android:name="com.package.company.details.CompanyDetailActivityLocation"
android:screenOrientation="portrait"
android:theme="@style/AppTheme">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.package.company.details.CompanyDetailActivity" />
</activity>
<activity
android:name="com.package.company.ClaimActivity"
android:theme="@style/AppTheme.NoActionBar"
tools:replace="android:theme" />
</application>
</manifest>
When targeting api 21 the compiler has a limit of 100 dex files it will read. So a simple solution I found was to add this to your dexOptions in your gradle file. This will merge all your dex files into the lowest possible amount.
In your build.gradle file add the following
android {
...
dexOptions {
preDexLibraries = false
}
}