8

I've got very strange error, because it only happens after installing app from generated .apk. When I try to run the app through IDE, it works fine.

java.lang.IllegalAccessError: Method 'int <package>.BaseActivity$Companion.getANIMATION_SLIDE_FROM_RIGHT()' is inaccessible to class '<package>.MyActivity' (declaration of '<package>.MyActivity' appears in /data/app/<package>-mg7eYmJ8hX5WvkNWNZWMVg==/base.apk!classes3.dex)

As you can see there is class called BaseActivity which looks like this:

open class BaseActivity : AppCompatActivity() {

    companion object {
        @JvmStatic
        protected val ANIMATION_DEFAULT = 0
        @JvmStatic
        protected val ANIMATION_SLIDE_FROM_RIGHT = 1
        @JvmStatic
        protected val ANIMATION_SLIDE_FROM_BOTTOM = 2
    }

    protected open var animationKind = ANIMATION_DEFAULT

    // Some other stuff
}

Now every activity extends this class and often overrides the animationKind like this:

class MyActivity: BaseActivity() {

    override var animationKind = ANIMATION_SLIDE_FROM_RIGHT

    // Some other stuff
}

The problem is that ANIMATION_SLIDE_FROM_RIGHT is inaccessible for MyActivity. I will repeat that it only happens on manually generated .apk. The funny thing is that I'm not using multidex, but error seems to show that BaseActivity is in classes3.dex. Here is my gradle file:

apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt'

android {

    compileSdkVersion 28

    defaultConfig {
        applicationId <package>
        versionCode <versionCode>
        versionName <versionName>
        minSdkVersion 21
        targetSdkVersion 28
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    androidExtensions {
        experimental = true
    }
}

dependencies {

    // Dependencies
}

I tried to play with multidexEnabled false/true, but the only change is that in false state the classes3.dex suffix disappears.

UPDATE

Of course when I change MyActivity's animationKind property to 1, then everything works fine.

UPDATE 2

After removing @JvmStatic and protected visibility it works fine.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
Nominalista
  • 4,632
  • 11
  • 43
  • 102

4 Answers4

11

From the official Kotlin documentation:

Java allows accessing protected members from other classes in the same package and Kotlin doesn't, so Java classes will have broader access to the code

So, please make sure that your BaseActivity and MyActivity are under the same package.

If both activities are not under the same package then it will run perfectly by direct run from Studio, but it will crash (IllegalAccessError) while you generate .apk and try to run on the device by installing that apk.

Adinia
  • 3,722
  • 5
  • 40
  • 58
Vinay Rathod
  • 1,262
  • 1
  • 10
  • 19
  • It doesn't tell what's the actual problem. Furthermore `companion object` and `protected` definition have nothing in common. What if I don't want to share these fields outside extending classes? – Nominalista Jul 20 '18 at 06:10
  • Can you prove somehow that protected is only working when classes are in the same package? – Nominalista Jul 20 '18 at 07:14
  • What I mean is that I couldn't find information that in Kotlin you can access protected fields only in the same package. – Nominalista Jul 20 '18 at 07:49
  • that not officially written but by analysis I am saying that. – Vinay Rathod Jul 20 '18 at 08:29
  • In my case it happened during java->kotlin conversion. Files were in same package. Finally I tried removing build, app/build and .idea and doing "invalidate caches and restart" and things started working. AndroidStudio 4.0.1, Kotlin version 1.4.10. When a problem makes no sense at all, that often seems to work. – steven smith Oct 06 '20 at 03:13
1

While I'm not sure why this results in IllegalAccessError, you should be defining those constants like this:

companion object {
    const val ANIMATION_DEFAULT = 0
    const val ANIMATION_SLIDE_FROM_RIGHT = 1
    const val ANIMATION_SLIDE_FROM_BOTTOM = 2
}

And that should solve your problem, otherwise using @JvmField instead of @JvmStatic would have been a better choice.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
1

Make sure you've declared the method that is failing inside the same module as the calling code.

In my case I was experiencing following error:

java.lang.IllegalAccessError: Method 'boolean[] my.package.common.kotlin.AndroidExtensionsKt.$jacocoInit()' is inaccessible to class 'my.package.ui.first.FirstActivity$viewModel$2' (declaration of 'my.package.ui.first.FirstActivity$viewModel$2' appears in /data/app/my.package.dev-fdHNodmdXHv-b_heK4MXeA==/base.apk!classes8.dex)
    at my.package.ui.first.FirstActivity$viewModel$2.invoke(FirstActivity.kt:18)
    at my.package.ui.first.FirstActivity$viewModel$2.invoke(FirstActivity.kt:14)
    at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
    at my.package.ui.first.FirstActivity.getViewModel(Unknown Source:11)
    at my.package.ui.first.FirstActivity.onCreate(FirstActivity.kt:23)

Where getViewModel() was declared in common module and FirstActivity was declared in app module:

inline fun <reified T : ViewModel> FragmentActivity.getViewModel(
    factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(this, factory).get(T::class.java)

After moving getViewModel() from common module to app module no issues were seen.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
  • 2
    Removing the keyword `inline` will resolve the error too. But I wonder why I am not able to call inline function which is in a different modules. – BakaWaii Sep 28 '19 at 16:00
  • this is occurred to us in AGP 4.2.0-beta06, running the gradle task manually always giving us `IllegalAccessError`, looks like it needs to be reported – mochadwi Mar 29 '21 at 13:05
  • opened an issue in jacoco: https://github.com/jacoco/jacoco/issues/1171 also the google commented here: https://issuetracker.google.com/issues/171802602#comment5 – mochadwi Mar 29 '21 at 13:18
  • 1
    Commenting on old issues in the google issue tracker probably won't get any results. I have file a new issue for this. If @mochadwi and everyone else would like to "star" it to help get Google's eyes on it, that'd be great. https://issuetracker.google.com/issues/192636549 – Bradleycorn Jul 02 '21 at 20:41
0
open class BaseActivity : AppCompatActivity() {
    @JvmField
    protected val ANIMATION_DEFAULT = 0
    @JvmField
    protected val ANIMATION_SLIDE_FROM_RIGHT = 1
    @JvmField
    protected val ANIMATION_SLIDE_FROM_BOTTOM = 2

protected open var animationKind = ANIMATION_DEFAULT

// Some other stuff
}

How About this?

In my opinion, Kotlin does not yet fully support companion - jvm static member.

NeoMind
  • 105
  • 1
  • 3
  • 7