2

I've written a utility library for a project I am working on in Kotlin. The project has a number of dependencies (such as AWS libraries). I want to package the library as a 'fat' .jar so that I can use the library in other projects without issue.

Currently, I am using the gradle shadow plugin. I am able to successfully use the .jar classes in Java code/projects without issue. However, when using the .jar classes in Kotlin projects/code (or attempting to) I am facing visibility issues (code does not compile b/c of unresolved references). I have no idea what I am doing wrong and am not sure if this is a common issue.

I've already tried:

  • Gradle Shadow plugin here
  • Modifying the gradle jar task to include all dependencies myself

The fat jar is successfully created in both cases, and usable in Java code, but Kotlin is not able to resolve the references. However, when I create a non fat jar, the classes are visible, but obviously broken (bc of missing dependencies). So, essentially, only when I create a fat .jar, only my Kotlin code cannot use the library.

Does anyone have any insight?

2
  • Does the resulting JAR with Kotlin files also include the META-INF/*.kotlin_module files? These are required for the Kotlin compiler to correctly read the declarations. Without them, you might face visibility issues with top-level declarations. Commented Apr 4, 2019 at 18:48
  • @hotkey yup, the kotlin_module files are present both in the FAT jar and the original jar Commented Apr 4, 2019 at 19:18

2 Answers 2

2

Most likely, your re-packaged JAR is missing the META-INF/*.kotlin_module files from the original JARs. These are the Kotlin package metadata files which the Kotlin compiler needs to be able to read top-level declarations from the classes.

If these files are lost, you will face visibility issues with top-level declarations and extensions.

You need to configure your fat JAR tools to also copy these files into the resulting JAR.

Sign up to request clarification or add additional context in comments.

3 Comments

The FAT jar contains the META-INF/*.kotlin_module files. So does the non FAT jar (which is able to be imported and used)
@plesh Do you relocate any packages for the fat JAR? The *.kotlin_module files will point the compiler to the original packages, so if the classes are relocated, it will fail to find them.
I do not. I was previously, but even without relocating packages I run into the same issue.
0

You would also need to add both the compile time and run time dependencies when you compile your library jar file.

One way to add them would be for example:

tasks {
    jar{
        from({
            configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
            configurations.compileClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
        })

        exclude ("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.