I want to give Kotlin a try, so I decided to try to convert a single class of my project to Kotlin and see how it integrates with my workflow before trying to convert my entire project. I am able to build and my app works properly, but on every subsequent build after the first, I get the below exception from ClassLoader. The app only works properly after cleaning, and worked fine before I converted anything. I'm able to run a HelloWorld project on the same machine multiple times without error. The responses in this question did not help: ClassNotFoundException in custom flavor using kotlin
07-31 14:35:41.563 1878-1878/com.ddiehl.android.htn.debug
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.ddiehl.android.htn.debug, PID: 1878
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.ddiehl.android.htn.debug/com.ddiehl.android.htn.view.activities.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.ddiehl.android.htn.view.activities.MainActivity" on path: DexPathList[[zip file "/data/app/com.ddiehl.android.htn.debug-1/base.apk"],nativeLibraryDirectories=[/data/app/com.ddiehl.android.htn.debug-1/lib/arm, /vendor/lib, /system/lib]]
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
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:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.ddiehl.android.htn.view.activities.MainActivity" on path: DexPathList[[zip file "/data/app/com.ddiehl.android.htn.debug-1/base.apk"],nativeLibraryDirectories=[/data/app/com.ddiehl.android.htn.debug-1/lib/arm, /vendor/lib, /system/lib]]
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.newActivity(Instrumentation.java:1065)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
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:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Suppressed: java.lang.ClassNotFoundException: com.ddiehl.android.htn.view.activities.MainActivity
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
Anyone have an idea why my app might work on first build, but not on subsequent builds? Here is my build.gradle, manifest, and activity, for reference.
build.gradle (app module)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.jakewharton.hugo'
apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'me.tatarka.retrolambda'
android {
compileSdkVersion 22
buildToolsVersion "23 rc3"
defaultConfig {
applicationId "com.ddiehl.android.htn"
minSdkVersion 15
targetSdkVersion 22
versionCode 4
versionName "0.3.0-dev"
ndk {
moduleName "app"
}
}
signingConfigs {
release {
storeFile file(ANDROID_KEYSTORE_PATH)
storePassword ANDROID_KEYSTORE_PWD
keyAlias HTN_KEYSTORE_ALIAS
keyPassword HTN_KEYSTORE_PWD
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
minifyEnabled false
}
release {
debuggable false
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
debug.java.srcDirs += 'src/debug/kotlin'
}
}
def getLocalProperty(s) {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
return properties.getProperty(s)
}
retrolambda {
jdk getLocalProperty("jdk8.dir")
}
dependencies {
compile project(':reddit')
compile project(':mopub')
compile project(':flurry')
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:support-v4:22.2.1'
compile 'com.android.support:design:22.2.0'
compile 'com.android.support:recyclerview-v7:22.2.1'
compile 'com.android.support:cardview-v7:22.2.1'
compile 'com.google.android.gms:play-services-ads:7.5.0'
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.squareup:otto:1.3.5'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.jakewharton:butterknife:7.0.0'
compile 'com.jakewharton:kotterknife:0.1.0-SNAPSHOT'
compile 'io.reactivex:rxandroid:0.25.0'
compile 'com.facebook.stetho:stetho:1.1.1'
compile 'com.facebook.stetho:stetho-okhttp:1.1.1'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
}
buildscript {
ext.kotlin_version = '0.12.1230'
repositories {
mavenCentral()
maven {
url 'http://oss.sonatype.org/content/repositories/snapshots'
}
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
repositories {
mavenCentral()
maven {
url 'http://oss.sonatype.org/content/repositories/snapshots'
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ddiehl.android.htn" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:name="com.ddiehl.android.htn.HoldTheNarwhal"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:supportsRtl="true">
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name="com.ddiehl.android.htn.view.activities.MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="www.damiendiehl.net"
android:scheme="http" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.kt (I redacted most of the View-related logic, it was 400 lines and this is a closed-source project at the moment. I can pastebin the full file, though, if necessary).
package com.ddiehl.android.htn.view.activities
import android.app.Dialog
import android.app.ProgressDialog
import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.support.design.widget.NavigationView
import android.support.design.widget.Snackbar
import android.support.v4.content.ContextCompat
import android.support.v4.view.GravityCompat
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.MenuItem
import android.view.View
import android.view.Window
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import butterknife.Bind
import butterknife.ButterKnife
import butterknife.OnClick
import butterknife.bindView
import com.flurry.android.FlurryAgent
import com.flurry.android.FlurryAgentListener
import com.mopub.common.MoPub
import com.mopub.mobileads.MoPubConversionTracker
import hugo.weaving.DebugLog
import java.util.HashMap
import kotlin.properties.Delegates
public class MainActivity : AppCompatActivity(), MainView, ConfirmSignOutDialog.Callbacks, NavigationView.OnNavigationItemSelectedListener {
private val mBus = BusProvider.getInstance()
private var mMainPresenter: MainPresenter? = null
private var mLastAuthCode: String? = null
private var mProgressBar: ProgressDialog? = null
private var mSubredditNavigationDialog: Dialog? = null
val mDrawerLayout: DrawerLayout by bindView(R.id.drawer_layout)
private var mAccessTokenManager: AccessTokenManager? = null
DebugLog
override fun onCreate(savedInstanceState: Bundle?) {
super<AppCompatActivity>.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ButterKnife.bind(this@MainActivity)
Init().execute()
}
private inner class Init : AsyncTask<Void, Void, Void>() {
override fun onPreExecute() {
super.onPreExecute()
mNavigationView.setNavigationItemSelectedListener(this@MainActivity)
val toolbar = ButterKnife.findById<Toolbar>(this@MainActivity, R.id.toolbar)
setSupportActionBar(toolbar)
val actionBar = getSupportActionBar()
if (actionBar != null) {
actionBar.setHomeAsUpIndicator(R.drawable.ic_navigation_menu)
actionBar.setDisplayHomeAsUpEnabled(true)
}
}
override fun doInBackground(vararg params: Void): Void? {
mAccessTokenManager = AccessTokenManager.getInstance(this@MainActivity)
return null
}
override fun onPostExecute(aVoid: Void?) {
super.onPostExecute(aVoid)
onAppInitialized()
}
}
override fun onStart() {
super<AppCompatActivity>.onStart()
if (mAccessTokenManager == null) {
showSpinner(R.string.application_loading)
} else {
onAppInitialized()
}
}
private fun onAppInitialized() {
mBus.register(mAccessTokenManager)
FlurryAgent.onStartSession(this)
dismissSpinner()
updateUserIdentity()
showSubredditIfEmpty(null)
}
override fun onStop() {
super<AppCompatActivity>.onStop()
FlurryAgent.onEndSession(this)
mBus.unregister(mAccessTokenManager)
}
companion object {
public val TAG: String = javaClass<MainActivity>().getSimpleName()
private val DIALOG_CONFIRM_SIGN_OUT = "dialog_confirm_sign_out"
private val FLURRY_SESSION_TIMEOUT_SECONDS = 30
}
}