Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradle configuration fails because of implicit dependency on ShadowJar #13

Closed
gregorbg opened this issue Nov 4, 2019 · 15 comments · Fixed by #15
Closed

Gradle configuration fails because of implicit dependency on ShadowJar #13

gregorbg opened this issue Nov 4, 2019 · 15 comments · Fixed by #15
Assignees
Labels
bug Something isn't working

Comments

@gregorbg
Copy link
Contributor

gregorbg commented Nov 4, 2019

No template, so I will just freestyle the issue report to the best of my abilities!

OS: Manjaro Linux 18.1.4 / Kernel 5.4.2 amd64
Java: 1.8.0_232
Gradle: 6.0.1 (wrapper via gradlew)

Expected behaviour

When following the steps on the Quickstart guide in the README.md file, I can incorporate the Gradle plugin id("io.kotless") into my existing build without breaking the project.

Actual behaviour

Upon following the instructions on how to include Kotless in my own Gradle project, Gradle fails during configuration stage with the following error message:

FAILURE: Build failed with an exception.

* Where:
Build file '/home/suushie_maniac/jvdocs/tnoodle/webscrambles/build.gradle.kts' line: 27

* What went wrong:
An exception occurred applying plugin request [id: 'io.kotless', version: '0.1.2']
> Failed to apply plugin [id 'io.kotless']
   > Task with name 'shadowJar' not found in project ':webscrambles'.

The failure occurs even for simple commands such as ./gradlew tasks.

In particular, my buildscript file uses the Kotlin DSL. I have installed Kotless as id("io.kotless").version("0.1.2") as determined by the Quickstart guide. The plugins {} block also includes johnrengelman's shadow plugin indenpendently of Kotless, because it is needed as part of my project.

Steps to reproduce

The entire codebase of the project where this fail occurs is open-source at https://github.com/suushiemaniac/tnoodle/tree/feature/kotless.

To reproduce, simply clone and check out the feature/kotless branch that is linked above and execute ./gradlew tasks in the project directory.

The relevant build file is in the cloudscrambles folder, found at cloudscrambles/build.gradle.kts

@TanVD TanVD added the bug Something isn't working label Nov 6, 2019
@TanVD TanVD self-assigned this Nov 6, 2019
@gregorbg
Copy link
Contributor Author

Heads-up: The error persists in Gradle 6.0.1

@TanVD
Copy link
Member

TanVD commented Nov 21, 2019

Yep, the problem is in a shadow-jar integration. I'll fix it in next release

@freiit
Copy link

freiit commented Dec 10, 2019

Is there a workaround? I followed README.md and no matter what I try out, I always end up with that error message.

@TanVD
Copy link
Member

TanVD commented Dec 10, 2019

@freiit You also use ShadowJar in your project for some other purpose?

@freiit
Copy link

freiit commented Dec 11, 2019

@TanVD I just started to play around. I copy/pasted the build.gradle.kts from the README.md. Started it in a new empty folder. Here the dump.

Just asking for a (tmp) workaround, would still like to try out kotless.

/tmp/xxx$ cat build.gradle.kts 
plugins {
    id("io.kotless") version "0.1.2" apply true
    
    //Version of Kotlin should 1.3.50+
    kotlin("jvm") version "1.3.50" apply true
}

repositories {
    jcenter()
}

dependencies {
    implementation("io.kotless", "lang", "0.1.2")
    //or for Ktor
    //implementation("io.kotless", "ktor-lang", "0.1.2")
}

kotless {
    config {
        bucket = "kotless.s3.example.com"
        
        dsl {
            type = DSLType.Kotless
            //or for Ktor
            //type = DSLType.Ktor
        }

        terraform {
            profile = "example"
            region = "us-east-1"
        }
    }

    webapp {
        route53 = Route53("kotless", "example.com")

        //configuration of lambda created
        lambda {            
            //needed only for Kotless DSL
            kotless {
                //Define packages in which scan for routes should be performed
                packages = setOf("io.kotless.examples")
            }
        }
    }
}

/tmp/xxx$ gradle
FAILURE: Build failed with an exception.

* Where:
Build file '/tmp/xxx/build.gradle.kts' line: 1

* What went wrong:
An exception occurred applying plugin request [id: 'io.kotless', version: '0.1.2']
> Failed to apply plugin [id 'io.kotless']
   > Task with name 'shadowJar' not found in root project 'xxx'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 4s

/tmp/xxx$ gradle --version

------------------------------------------------------------
Gradle 6.0.1
------------------------------------------------------------

Build time:   2019-11-18 20:25:01 UTC
Revision:     fad121066a68c4701acd362daf4287a7c309a0f5

Kotlin:       1.3.50
Groovy:       2.5.8
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          1.8.0_192 (Azul Systems, Inc. 25.192-b01)
OS:           Linux 4.15.0-72-generic amd64

@TanVD
Copy link
Member

TanVD commented Dec 11, 2019

@freiit Could you try it instead of current plugins block:

import io.kotless.DSLType
import io.kotless.plugin.gradle.dsl.Webapp.Route53
import io.kotless.plugin.gradle.dsl.kotless

plugins {
    //Version of Kotlin should 1.3.50+
    kotlin("jvm") version "1.3.50" apply true

    id("io.kotless") version "0.1.2" apply true
}

@TanVD
Copy link
Member

TanVD commented Dec 11, 2019

As for initial issue @suushiemaniac I am investigating issue right now, but now I am not sure what actually leads to problem with Gradle configuration. Am I right, that kotless now is applied at cloudscrambles?

@gregorbg
Copy link
Contributor Author

@TanVD Yes indeed, this has changed because I continued to work on the project after reporting the initial issue. Kotless is now applied at cloudscrambles, just like you indicated.

@gregorbg
Copy link
Contributor Author

Original post has been edited to reflect the changed versions and project structure. Underlying problem still persists, though.

@freiit
Copy link

freiit commented Dec 12, 2019

@freiit Could you try it instead of current plugins block:

import io.kotless.DSLType
import io.kotless.plugin.gradle.dsl.Webapp.Route53
import io.kotless.plugin.gradle.dsl.kotless

plugins {
    //Version of Kotlin should 1.3.50+
    kotlin("jvm") version "1.3.50" apply true

    id("io.kotless") version "0.1.2" apply true
}

Thanks, that works now 👍

/tmp/xxx$ gradle
Starting a Gradle Daemon (subsequent builds will be faster)

> Task :help

Welcome to Gradle 6.0.1.

To run a build, run gradle <task> ...

To see a list of available tasks, run gradle tasks

To see a list of command-line options, run gradle --help

To see more detail about a task, run gradle help --task <task>

For troubleshooting, visit https://help.gradle.org

BUILD SUCCESSFUL in 8s
1 actionable task: 1 executed

@TanVD
Copy link
Member

TanVD commented Dec 12, 2019

@freiit I've updated README.md, now kotlin plugin is above kotless :)
@suushiemaniac It does not fix your case, right?

@gregorbg
Copy link
Contributor Author

gregorbg commented Dec 12, 2019

Indeed it does not solve my issue, I'm afraid.

Even if it did, mitigating the problem by relying on an exact plugin order does not sound like a healthy solution to be honest.

Did you gain any more insight on why this happens so far? I'm happy to chat (for example via the Kotlin Slack) if you need any help, TNoodle is rather complex 😅

@gregorbg
Copy link
Contributor Author

I toyed around with the source code a little, and here's a potential solution that I came up with:

diff --git a/plugins/gradle/src/main/kotlin/io/kotless/plugin/gradle/utils/Utils.kt b/plugins/gradle/src/main/kotlin/io/kotless/plugin/gradle/utils/Utils.kt
index 8b73fad..f46e668 100644
--- a/plugins/gradle/src/main/kotlin/io/kotless/plugin/gradle/utils/Utils.kt
+++ b/plugins/gradle/src/main/kotlin/io/kotless/plugin/gradle/utils/Utils.kt
@@ -5,7 +5,5 @@ import org.gradle.kotlin.dsl.apply
 
 /** Apply a plugin if it is not already applied. */
 internal fun Project.applyPluginSafely(id: String) {
-    if (!plugins.hasPlugin(id)) {
-        apply(plugin = id)
-    }
+    pluginManager.apply(id)
 }

I am uncertain as to why this solves the problem, my gut instinct says that it's something with the structure of multi-project builds. Perhaps your version applies the plugin at the root level instead of the current sub-project? As I said, I'm pretty much just guessing.

A few remarks as to how I found out about this fix:

  • https://stackoverflow.com/a/45652773
  • As the StackOverflow answer indicates, Gradle's own war plugin uses this approach, so it seems to be somewhat best practice
  • From the Gradle documentation of PluginManager:

Applies the plugin with the given ID.
Does nothing if the plugin has already been applied.

@gregorbg gregorbg reopened this Dec 12, 2019
@gregorbg
Copy link
Contributor Author

Wrong button, I'm sorry! I will submit a PR, we can discuss the solution there.

@gregorbg
Copy link
Contributor Author

Sorry for being so overly talkative, but I just saw that you're using the same applyPluginSafely approach for your tanvd.kosogor plugin. You may want to contemplate on what difference my suggested fix in #15 makes and whether it would be reasonable to update that plugin as well ;)

@TanVD TanVD closed this as completed in #15 Dec 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants