Self Contained Jar Distrobution

I have a little java project that I distribute as a self contained jar file. I converted all the code to Kotlin and made a project out of tweaking the Kotlin to make it work/work better. It uses the Jackson Object Mapper to serialize/deserialize to/from JSON files. I resolved the issues and warnings and got the Gradle file working fairly well. The build works and had a ton of fun during the conversion.

However, the jar file went from 4.1MB to 8.2MB, so adding no functionality, just a language swap doubled the jar size. Looking at the jar file it appears the biggest piece is in the kotlin-reflect library. Is there any way to use the native java reflection to make this library a little smaller? Is a ~4MB overhead expected for a self contained Kotlin jar?

Are you actually using anything from kotlin-reflect or did you add it without needing it?

Its required for the Jackson ObjectMapper

You probably mean that it is used by jackson-module-kotlin. Is this correct?

Yes, exactly - I should include more details…

A snippit from “gradle dependencies”

runtimeClasspath - Runtime classpath of source set 'main'. +--- com.fasterxml.jackson.core:jackson-core:2.8.7 +--- com.fasterxml.jackson.core:jackson-databind:2.8.7 | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 | \--- com.fasterxml.jackson.core:jackson-core:2.8.7 +--- com.fasterxml.jackson.module:jackson-module-kotlin:2.8.7 | +--- com.fasterxml.jackson.core:jackson-databind:2.8.7 (*) | +--- com.fasterxml.jackson.core:jackson-annotations:2.8.0 | \--- org.jetbrains.kotlin:kotlin-reflect:1.0.6 -> 1.1.1 | \--- org.jetbrains.kotlin:kotlin-stdlib:1.1.1 | \--- org.jetbrains:annotations:13.0 +--- com.dorkbox:SystemTray:3.1 | +--- org.javassist:javassist:3.21.0-GA | +--- net.java.dev.jna:jna:4.3.0 | +--- org.slf4j:slf4j-api:1.7.9 -> 1.7.18 | \--- ch.qos.logback:logback-classic:1.1.6 | +--- ch.qos.logback:logback-core:1.1.6 | \--- org.slf4j:slf4j-api:1.7.18 +--- org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.1 | \--- org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.1 | \--- org.jetbrains.kotlin:kotlin-stdlib:1.1.1 (*) \--- org.jetbrains.kotlin:kotlin-reflect:1.1.1 (*)

My Gradle file:

group 'nv.jdw'
version '6.0'

apply plugin: 'kotlin'

sourceCompatibility = 1.8
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
repositories {
    mavenCentral()
}

dependencies {
    //used for JSON serialization/deserialization
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.7'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.7'
    compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-kotlin', version: '2.8.7'
    // a better tray icon...
    compile group: 'com.dorkbox', name: 'SystemTray', version: '3.1'
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}


jar {
    manifest {
        attributes("Implementation-Title": "jnvdw",
                "Implementation-Version": version,
                "Main-Class" : "nv.Jnvdw")
    }
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

buildscript {
    ext.kotlin_version = '1.1.1'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

Do you really need jackson-module-kotlin. Doesn’t it work without it for you?

Well I commented out the jackson-module-kotlin and the kotlin-reflect lines and it still works. So I guess the answer is no, I don’t actually need them. The Jar size dropped to 5.2M, which is a much nicer margin. Thanks!

Update:

I just tried to convert another new project. This line:

var node = om.readValue(resp, ObjectNode::class.java )

was giving an error on the .java part in the IDE and it wouldn’t compile either. So I added this:

compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

to the gradle file and the error goes away. But then I think: hey, I didn’t need that in my other project, so I remove the kotlin-reflect line from the grade file save it… no error in the IDE and it compiles just fine. (using gradle clean build)

So I don’t know if its really needed except on first compile?

That’s some kind of a bug. You don’t need kotlin-reflect for ::class.java. It would be great if you can file a defect report to http://kotl.in/issue with some description of how it can be reproduced.