# What is the proper way to repackage/shade Kotlin dependencies

**URL:** <https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869>\
**Category:** Support\
**Created:** [December 22, 2018, 12:17pm UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869 "2018-12-22T12:17:13Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Vladimir.Sitnikov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vladimir.sitnikov/32/5894_2.png) [@Vladimir.Sitnikov](https://discuss.kotlinlang.org/u/Vladimir.Sitnikov)\
**Post date:** [December 22, 2018, 12:17pm UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/1 "2018-12-22T12:17:13Z")

</div>

I wonder if Kotlin can be used to create “zero-dependency” library for Java consumers (e.g. JDBC driver).

Of course I can just use maven-shade-plugin (or alternative) to repackage kotlin.\* classes, however I wonder if [Metadata - Kotlin Programming Language](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-metadata/index.html) requires some special treatment.

---

<div class="post-metadata">

**Author:** ![cretz](https://avatars.discourse-cdn.com/v4/letter/c/d2c977/32.png) [@cretz](https://discuss.kotlinlang.org/u/cretz)\
**Post date:** [December 22, 2018, 8:12pm UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/2 "2018-12-22T20:12:27Z")

</div>

> [@Vladimir.Sitnikov](#):
>
> (e.g. JDBC driver)

The question is a good one, and I am curious too, but this is a bad example as the practice of shading the Kotlin runtime for a library like this leads to unnecessary duplication since it’s a runtime that may often be shared by end user code anyways. If there were backwards compat problems w/ Kotlin runtime or you had to have a single-JAR-but-scared-of-classpath situation it might be different, but in general I would avoid it.

> [@Vladimir.Sitnikov](#):
>
> however I wonder if [https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-metadata/index.html](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-metadata/index.html) requires some special treatment.

I wonder this too. From my naive reading of the link you have, the [metadata lib mutation readme](https://github.com/JetBrains/kotlin/blob/master/libraries/kotlinx-metadata/jvm/ReadMe.md), and [the metadata protobuf they embed](https://github.com/JetBrains/kotlin/blob/master/core/metadata/src/metadata.proto) I would guess there is some non-trivial work to refactor and change the compiled package name. Things get even more complicated w/ `JvmPackageName` attributes and what not.

I’d say if you don’t end up getting a satisfactory answer, do some tests and make sure some of those test cases exercise Kotlin-only reflection too (e.g. `KClass.qualifiedName`). I would guess that, unless you use Kotlin reflection specifically (i.e. no reflection or Java-only reflection is fine), you could probably use maven-shade, shadow, or whatever. Worst case scenario, you may end up doing source-level refactorings which sounds like a nightmare.

---

<div class="post-metadata">

**Author:** ![Vladimir.Sitnikov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vladimir.sitnikov/32/5894_2.png) [@Vladimir.Sitnikov](https://discuss.kotlinlang.org/u/Vladimir.Sitnikov)\
**Post date:** [December 24, 2018, 10:42am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/3 "2018-12-24T10:42:19Z")

</div>

> [@cretz](#):
>
> but this is a bad example as the practice of shading the Kotlin runtime for a library like this leads to unnecessary duplication since it’s a runtime that may often be shared by end user code anyways

1. JDBC drivers are often used in `public static void main` environment, especially when developers use no dependency management
2. You can’t predict the environment, so end-user might use various runtime versions. This will cause conflicts

---

<div class="post-metadata">

**Author:** ![tj.rothwell](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tj.rothwell/32/8659_2.png) [@tj.rothwell](https://discuss.kotlinlang.org/u/tj.rothwell)\
**Post date:** [June 22, 2021, 7:40pm UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/4 "2021-06-22T19:40:11Z")

</div>

Is Kotlin team saying it can’t be done? Whether is should or shouldn’t is up to the author.

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [June 23, 2021, 6:11am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/5 "2021-06-23T06:11:07Z")

</div>

@tj.rothwell Your question is unclear. The fatjar could be created via [gradle shadow plugin](https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow). It works perfectly fine with kotlin. Also, you should probably know that [jpackage](https://github.com/beryx/badass-runtime-plugin) also works perfectly well with kotlin.

---

<div class="post-metadata">

**Author:** ![Vladimir.Sitnikov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vladimir.sitnikov/32/5894_2.png) [@Vladimir.Sitnikov](https://discuss.kotlinlang.org/u/Vladimir.Sitnikov)\
**Post date:** [June 23, 2021, 6:46am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/6 "2021-06-23T06:46:25Z")

</div>

@darksnake , does shadow plugin update kotlin metadata annotation to account the repackage?

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [June 23, 2021, 6:51am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/7 "2021-06-23T06:51:37Z")

</div>

The class path does not change during repackaging so I do not see why it should affect anything. I usually prefer application instead of shadow, but I used shadow multiple times in kotlin and I have not seen any problems. From the java side metadata looks like an annotation with string content, so it is just moved together with class.

The shadow plugin is usually used for an application, so the metadata is not even used anymore (save for very specific reflection cases).

---

<div class="post-metadata">

**Author:** ![Vladimir.Sitnikov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vladimir.sitnikov/32/5894_2.png) [@Vladimir.Sitnikov](https://discuss.kotlinlang.org/u/Vladimir.Sitnikov)\
**Post date:** [June 23, 2021, 7:26am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/8 "2021-06-23T07:26:25Z")

</div>

My use case is for shading stdlib for a **libarary** rather than application.

The better questions probably: “is the metadata relocatable?” In other words, does it need to be changed when class name/method name changes?

> From the java side metadata looks like an annotation with string content

For instance, if the contents includes references to other classes, then the annotation must be adjusted if classes are repackaged.

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [June 23, 2021, 7:28am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/9 "2021-06-23T07:28:39Z")

</div>

I do not see why it should be changed. The metadata points to java class files and their paths are not changed during repackaging (otherwise standard java programs would stop working). It is possible that there are some corner cases for that, but I have not seen them. If you do encounter something like this, please file an issue.

---

<div class="post-metadata">

**Author:** ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)\
**Post date:** [June 23, 2021, 10:30am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/10 "2021-06-23T10:30:50Z")

</div>

Also probably you should not shade a library…

---

<div class="post-metadata">

**Author:** ![Vladimir.Sitnikov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vladimir.sitnikov/32/5894_2.png) [@Vladimir.Sitnikov](https://discuss.kotlinlang.org/u/Vladimir.Sitnikov)\
**Post date:** [June 23, 2021, 10:49am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/11 "2021-06-23T10:49:31Z")

</div>

I see your suggestions, yet they do not help to clarify if “kotlin metadata annotations” or “META-INF/\*.kotlin\_module” contains non-relocatable data.

For instance, I just checked `META-INF/stage-vote-release-plugin.kotlin_module` from one of my projects, and the file does contain fully qualified class references, so I assume `.kotlin_module` breaks if I relocate the classes.

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [June 23, 2021, 11:03am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/12 "2021-06-23T11:03:46Z")

</div>

The question is: do you really plan to relocate your code (so rename a package name) or do you only need to shade/create a fatjar, which does not really relocate classes? You are right that you didn’t get an answer to your question. People are just concerned, because you asked specifically about shading, but it shouldn’t introduce the problem that you try to avoid.

---

<div class="post-metadata">

**Author:** ![Vladimir.Sitnikov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/vladimir.sitnikov/32/5894_2.png) [@Vladimir.Sitnikov](https://discuss.kotlinlang.org/u/Vladimir.Sitnikov)\
**Post date:** [June 23, 2021, 11:21am UTC](https://discuss.kotlinlang.org/t/what-is-the-proper-way-to-repackage-shade-kotlin-dependencies/10869/14 "2021-06-23T11:21:10Z")

</div>

> [@broot](#):
>
> People are just concerned, because you asked specifically about shading

It is in the question title, and I want **both** : **relocate** and **shade**

In other words, I want to write a zero-dependency JVM library in Kotlin and use libraries like `kotlin-stdlib`. I want to make sure it won’t conflict with other `kotlin-stdlib` on the users’ classpath, and I have no way to control the classpath of the users. They might have their Kotlin versions.

Is it possible?
