`internal` is `public` in Java, so our libs leak i...
# announcements
d
internal
is
public
in Java, so our libs leak internal API is there a way to post-process Kotlin-generated bytecode to translate the internal to package-private?
d
That would potentially break your code, since
internal
can be accessed across packages in Kotlin.
d
yikes, good catch
d
If you really do want to hide them from Java, you can use the
@JvmSynthetic
annotation
šŸ‘ 1
d
I cannot apply it on constructors though šŸ˜• so I can make the constructors
private
and then add factory method and make it synthetic it leaks a
Companion
class to Java, but it’s pretty benign šŸ¤”
d
Seems like an oversight that it can't be put on constructors... but yes, you can work around it like that if you absolutely must hide it from Java.
d
well, we have to hide them otherwise, our Java callers are not informed to avoid this specific constructor and we want to be able to change it in the future without breaking our callers
d
Huh, I was not aware of that.
Not much you can do here then, I think. At least IntelliJ will warn people trying to use those internal members.
d
That’s unfortunate. The main appeal of Kotlin was that it’s a better Java. Which for me meant that it has the advantages of Java, while fixing many of its flaws. Now it seems that my control of JVM API is limited and my API consumers would have to switch to IntelliJ rather than being happy with a Java IDE of their choice. I don’t want to go back to vanilla Java 😢
r
Everybody but the language designers want
package
in Kotlin
t
If you want to control access to the constructors, why not make them all private and use a
JvmStatic
creator method in a companion object?
h
d
@tddmonkey, then the creator method is public. I wanted to keep all creation within the lib and not in the API.
t
ok - that was in response to you saying you wanted to control access to certain constructors so you could change them
d
My current ā€œsolutionā€ is to stop wanting to hide the constructors (or builders/factory methods). I still want the ability to incompatibly change their signatures. To do that, I’ll move their public members to an interface and expose its implementation in the API too. When I’ll want to provide a different signature for internal reasons, I’ll add a new implementation, leaving the old one intact.
Also, package-private wouldn’t work too well either, because it’d mean that internal API consumers would all have to reside in the same package - making it huge.
d
So you want something on the JVM that the JVM has no support for. Go talk to the JVM people šŸ˜› Sorry for the snark, but how do you expect this to work?
šŸ‘ 1
d
you are right, what I wanted is
internal
, that works in Java, but Java doesn’t have it and package-private is not it either
my bad
h
Is that what Javas module system should provide?
d
Java modules don’t allow a single class to have both public (exported) and internal members unless you use package-private, but it still causes the uber-package problem
l
If you want to expose an API without exposing constructors or coupling the API with the implementation, using an interface is almost always the best solution.
šŸ‘ 1