0
votes

I was working on the Android library which I'm developing in Kotlin. I kept access modifier of some classes as internal. Internal classes are only visible in that library module in Kotlin. If I implement that library in the app then it's not visible at all.

But the problem comes when accessing that library from Java code. If I create .java file and type name of that internal class of library then IDE is suggesting name and it's resolved and compiled without any error.

For e.g.

Library Module:

internal class LibClass {
    // Fields and Methods
}

After implementing above library in DemoApp module:

App Module

Kotlin:
fun stuff() {
    val lib = LibClass() // Error.. Not resolving
}
Java:
public void stuff() {
    LibClass lib = new LibClass() // Successfully resolving and compiling
}

So that's the problem. How can I achieve securing that class from Java?

Thank you!

2
This should not be the case, in my IDE I cant compile it. Are you sure you are accessing LibClass in app module?Minki
Yes I can access it from app module. It's just showing red error underline below class name but compiling successfullyShreyas Patil
Not sure whether it would work, but maybe try annotating your class with @JvmName and give it an invalid Java name like containing a space, hyphen or something.Saurabh Thorat
Okay. I'll try this and will let you know about itShreyas Patil
@SaurabhThorat I tried using @JvmName but it's not working. It only works when top-level functions are created inside .kt file. It's not working for the class.Shreyas Patil

2 Answers

2
votes

I see you have got class with internal modifier that cannot be instantiated in kotlin class but can be instantiated in Java file. If it’s a standalone class, you can make its constructor private and allow the instantiation using a static method (Companion object).

0
votes

Not perfect solution but I found two hacky solutions

Annotate every public method of that internal class by @JvmName with blank spaces or special symbols by which it'll generate syntax error in Java.

For e.g.

internal class LibClass {

    @JvmName(" ") // Blank Space will generate error in Java
    fun foo() {}

    @JvmName(" $#") // These characters will cause error in Java
    fun bar() {}
}

Since this above solution isn't appropriate for managing huge project or not seems good practice, this below solution might help.

Annotate every public method of that internal class by @JvmSynthetic by which public methods aren't accessible by Java.

For e.g.

internal class LibClass {

    @JvmSynthetic
    fun foo() {}

    @JvmSynthetic
    fun bar() {}
}

Note:

This is explained in detail in this article.