11

I've written a Java library in Kotlin, and I'd like to compile it to a jar that is usable by Java and Kotlin applications.

The idea is that the jar should be able to work on Java projects, and Kotlin projects. Doing a simple ./gradlew clean assemble generates a jar, and when I inspect the jar I can see several imports that aren't included in the jar that normal Java applications won't have access too:

import jet.runtime.typeinfo.JetValueParameter;
import kotlin.jvm.internal.Intrinsics;
import kotlin.jvm.internal.KotlinClass;
import kotlin.jvm.internal.KotlinClass.Kind;
import kotlin.jvm.internal.KotlinSyntheticClass;
import kotlin.jvm.internal.KotlinSyntheticClass.Kind;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

How could I include the above dependencies in the jar? Right now the jar is only 30kb. I'd prefer to not have to include the entire Kotlin runtime either, but only compile in the used components.

spierce7
  • 14,797
  • 13
  • 65
  • 106
  • Take a look [here](http://stackoverflow.com/a/30565407/1212960) - although this talks about including the _whole_ Kotlin runtime. – Greg Kopff Aug 03 '15 at 06:20
  • After including the runtime you could try running ProGuard to reduce its size. You will probably need to tune the config file, though. – Kirill Rakhman Aug 03 '15 at 09:43

1 Answers1

5

Kotlin binaries do use some classes from the runtime, but the exact set of those classes is unspecified and may change even between minor versions, so you shouldn't rely on the list you've provided. Your best option is to include the full Kotlin runtime with the -include-runtime option and then run ProGuard (as noted in the comments) to exclude unused classes.

You can use this minimal ProGuard config file:

-injars input.jar
-outjars output.jar
-libraryjars <java.home>/lib/rt.jar

-keep class org.jetbrains.annotations.** {
    public protected *;
}

-keep class kotlin.jvm.internal.** {
    public protected *;
}

-keepattributes Signature,InnerClasses,EnclosingMethod

-dontoptimize
-dontobfuscate

If you use reflection (kotlin-reflect.jar), you should also keep everything under kotlin.reflect.**

Alexander Udalov
  • 31,429
  • 6
  • 80
  • 66
  • 1
    I'll mark this as the correct answer once I confirm that it works. I'm having a difficult time passing the `-include-runtime` argument to the kotlin compiler via gradle. I've created a separate question on how to pass the kotlin compiler arguments through gradle. http://stackoverflow.com/questions/31847292/how-to-pass-compiler-arguments-to-kotlin-compiler-with-gradle – spierce7 Aug 06 '15 at 05:14