ClassNotFoundException on subsequent builds after converting MainActivity to Kotlin
Asked Answered
C

4

6

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
    }

}
Chaffinch answered 31/7, 2015 at 22:25 Comment(0)
M
1

One possible cause could be an annotation processing library.

Maggie answered 2/10, 2015 at 8:59 Comment(3)
Thanks for the response, and this may very well have been the cause. Based on my build script at the time I posted this question it looks like I was attempting to use ButterKnife (and its Kotlin equivalent, Kotterknife) at the same time unintentionally. Unfortunately since I abandoned attempting to convert this project to Kotlin, I won't be able to verify if this was the real cause :(Chaffinch
Never give up on converting a Java project to Kotlin! It will pay off later. :)Maggie
I am able to launch into MainActivityKotlin.kt if I add the line: apply plugin: "kotlin-android" to the app build.gradle file. Without this line, I get the same error. Note that the "configure Kotlin for project" action in Android Studio adds a kotlin plugin to the top level build.gradle file with the line: apply plugin: 'kotlin'. Kotlin version level as of this writing is 1.1.1.Josefjosefa
J
1

When converting an existing Android app from Java to Konlin there are many configuration changes to make. If you only convert the actual Java files to Kotlin the compile would work, but you will get those runtime loading errors. The easiest way is to add a Kotlin class to the project:

new->kotlin class/file

The Android studio will then do all the necessary setting up for the support of kotlin. After you can remove the new class

Jeddy answered 22/4, 2021 at 9:46 Comment(0)
M
1

I was missing 'apply plugin: 'kotlin-android' from my module build.gradle file

Manner answered 2/10, 2022 at 19:8 Comment(0)
H
0

I am also getting same error and I have checked so many SO question and some blogs but none of them worked. As @Haggai's answer that we need do so many configuration when we directly convert Java project to Kotlin from Android Studio. When I convert my project then all JAVA files are converted from Java to Kotlin but both Gradle files are same as previous files. So what I have done is I have added Kotlin classpath to my project level gradle file and add kotlin plugin to app level gradle file. Below is my both files and its worked for me.

Project level build.gradle file

dependencies {
        classpath 'com.android.tools.build:gradle:4.2.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20"//---Add this class path to your project
    }

This is app leve build.gradle file

plugins {//---Apply plugin like this 
    id 'com.android.application'
    id 'kotlin-android'
}
android {
    defaultConfig {
    ...
    ...
    }
    kotlinOptions {//---I have added this block of code 
        jvmTarget = '1.8'
    }
}
dependencies {
   ...
   ...
}
Hurlburt answered 23/6, 2022 at 11:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.