I don’t do many crimes. I don’t even do crimes that I could do without getting caught! Every single time my dog poops on the sidewalk, I pick it up. Even if nobody’s watching! I have honor.
With that disclaimer out of the way, here’s instructions on how to do an excellent crime...
First, find a Kotlin API that you want to use, but can’t because it’s marked internal
and you’re in a different module.
Next, add this to the top of your file:
@file:Suppress(
"CANNOT_OVERRIDE_INVISIBLE_MEMBER",
"INVISIBLE_MEMBER",
"INVISIBLE_REFERENCE",
)
Finally, use the internal API! You’ve bribed the compiler.
Pragmatic Hacks
Using non-public APIs is dangerous and fragile. It’s occasionally also a good trade-off! I’ve done hacks like these a few times with mixed results:
- Moshi’s
ClassFactory
uses sun.misc.Unsafe to construct types without invoking their constructors. I’ve grown to dislike this behavior. - OkHttp’s
Platform
reflectively accesses the privateTrustManager
from aSSLSocketFactory
to fix a vulnerability in certificate pinning. This hack is carefully constrainted to JDK8, and the OkHttp function that relies on it has been deprecated since 2016. - Redwood’s prepareEnvironment() uses the above internal trick to configure a global uncaught exception handler. There’s no public API for that so I asked for one.
I don’t like needing to hack around access controls, but at least two of these crimes are righteous.
Sharing with Friends
I’m asking for trouble when I use somebody else’s non-public API. Upgrading dependencies is riskier. Using different versions in tests vs. runtime is riskier. The reward needs to be substantial to justify these hazards!
But sometimes I just wanna access my stuff from a different module that I also own. In one of Zipline’s tests, I’m using the zipline-cryptography
module’s internals from the zipline
module’s tests.
Allowing my test code to hack around internal
lets me reduce the visibility of my production code. I don’t need to publish public APIs to the world!
Honor
Don’t use the hack above. But if you must, do it honorably.