简体   繁体   中英

Cannot Access Class Using Java Language But Can Using Kotlin

I am experiencing an issue regarding access of an abstract class.

For background, I have an abstract class in a common module. The abstract class is just setters/getters for some values.

abstract class BaseConfiguration {

    abstract var key: String?
    abstract var token: String?
}

The common module is used by another module that is a SDK. So, in gradle this common module is implemented.

Gradle

implementation project(":common")

Inside of the SDK module, there are public interfaces to allow the setting/getting of the values in the BaseConfiguration file.

The conflict I am running into is that for Kotlin everything works fine. I am able to create a project, then add the SDK as a dependency and then set values for the BaseConfiguration through the provided interfaces in the SDK.

However, when I try to use the Java language, I am receiving a "cannot access BaseConfiguration" error. The only thing that seems to resolve this issue is to update my SDK gradle to api.

Gradle Changes

api project(":common")

I have concerns with this change, because the common module is supposed to be internal and only used by the SDK. The app level should not have access to it. The app should only access the provided interfaces by the SDK.

Does anyone know why this is working perfectly with Kotlin, but not with Java? What am I doing wrong?

Further Notes: When decompiling the Kotlin to Java for the BaseConfiguration class it shows that everything is public.

public abstract class BaseConfiguration {
   @Nullable
   public abstract String getKey();

   public abstract void setKey(@Nullable String var1);

   @Nullable
   public abstract String getToken();

   public abstract void setToken(@Nullable String var1);
}

By default, java's class visibility is package private. That means any file in the same package can access your abstract BaseConfiguration.

In kotlin, the default is public.

I suppose it is this visibility that is causing the issue. You should not use api for common module if the app module is not using it. Common's visibility should only be exposed to the SDK module as its direct neighbour. You are right to not expose the common module as a transitive dependency of app module.

Trying being explicit about the class dependency:

public abstract class BaseConfiguration {
    abstract var key: String?
    abstract var token: String?
}

I would take a look at the compiled java class by the kotlin compiler and see how it generates it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM