kotlingradleshadowjarkvision

In Gradle, how can I configure a task that is added by a plugin added as a transitive dependency of a different plugin?


I'm developing a full-stack app using KVision with KTor. KVision uses Gradle as a build system, and generates the JAR file using the ShadowJar plugin.

I need to configure the ShadowJar plugin to work around an issue with Flyway. Unfortunately, since I am not importing the ShadowJar plugin directly, I have no access to the ShadowJar task type.

Adding ShadowJar as a plugin dependency manually, naturally, doesn't work, since the plugin is already added as a dependency by KVision.

What's the best approach to configure ShadowJar in a situation like this?


Solution

  • The short answer

    You do not need to work with the Shadow Jar plugin at all. As you are using Ktor, the shadowJar task is of type Jar and you can configure it by writing:

    tasks.named<Jar>("shadowJar") {
        // configuration code
    }
    

    Why that is the case

    Looking at the source code and the build file for the KVision plugin, it looks to be the case that:

    1. The Shadow Jar plugin is not applied to the build by the KVision plugin, and is not on the runtime classpath of the project build1;
    2. Rather confusingly, the KVision plugin adds a task named shadowJar to the build2; however:
    3. The shadowJar task is only of type ShadowJar (being the type from the Shadow Jar plugin) for users of Micronaut and Vert.x servers. In this case, the plugin appears to expect users to apply the Shadow Jar plugin to the build; plus
    4. For users of Ktor, Jooby and Javalin servers, the shadowJar task is of the usual Jar type included with Gradle.

    Gradle build classpaths and plugins

    For completeness, I note that your original premise was not correct, namely that you would not have access to a plugin that was applied from another plugin (or, similarly, the KVision plugin could not have used the Shadow Jar plugin unless it was on the classpath). There is no such separation in Gradle.

    Had the Shadow Jar plugin been applied by the KVision plugin, you would have full access to its extensions and classes, just as if you had applied it yourself in your own build.gradle.kts. You see this in many other cases, such as how the Kotlin JVM plugin applies the Java plugin which in turn applies the Java base plugin, and you can configure all of those plugins in a Kotlin JVM build.


    1Note it is only a compileOnly dependency in the plugin's build.gradle.kts file

    2See plugin code starting from line 282