0

I have a Gradle project that as a simple example looks similar to this:

root
|
|build.gradle.kts
|settings.gradle.kts
|config.yaml
|web/
    |build.gradle.kts
    |src/
        |main/
             |java....(etc)

The web project is a barebones Dropwizard app that does nothing other than declare a configuration and an application that uses it so that the server can start up.

In my root path, I have defined my subproject (:web in this case) in the settings.gradle.kts file. In my root build.gradle.kts, I have a implementation(project(":web")) dependency declared.

I have a run task and a fatJar task to run/build this app.


val run by tasks.getting(JavaExec::class) {
    args("server", "config.yaml")
}

val fatJar = task("fatJar", type = Jar::class) {
    manifest {
        attributes["Implementation-Title"] = "Some API"
        attributes["Main-Class"] = "my.package.web.HelloWorldApplication"
    }
    from(configurations.runtimeClasspath.get().map({ if (it.isDirectory) it else zipTree(it) }))
    with(tasks.jar.get() as CopySpec)
}

tasks {
    "build" {
        dependsOn(fatJar)
    }
}

I can build the fatJar and it contains what appears to be all the classes I expect (dependencies at root, dependencies of web, their transitive dependencies, etc).

However, when I run ./gradlew run I get an error starting the Dropwizard app due to multiple logging bindings found on the class path. Error is below:

./gradlew run
Starting a Gradle Daemon, 1 busy and 1 incompatible and 3 stopped Daemons could not be reused, use --status for details

> Task :run
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/me/.gradle/caches/5.4.1/generated-gradle-jars/gradle-api-5.4.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/me/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.3/7c4f3c474fb2c041d8028740440937705ebb473a/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.gradle.internal.logging.slf4j.OutputEventListenerBackedLoggerContext]
Exception in thread "main" java.lang.IllegalStateException: Unable to acquire the logger context
        at io.dropwizard.logging.LoggingUtil.getLoggerContext(LoggingUtil.java:46)
        at io.dropwizard.logging.BootstrapLogging.bootstrap(BootstrapLogging.java:52)
        at io.dropwizard.logging.BootstrapLogging.bootstrap(BootstrapLogging.java:41)
        at io.dropwizard.Application.bootstrapLogging(Application.java:38)
        at io.dropwizard.Application.<init>(Application.java:26)
        at my.package.web.HelloWorldApplication.<init>(HelloWorldApplication.java:15)
        at my.package.web.HelloWorldApplication.main(HelloWorldApplication.java:17)

> Task :run FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':run'.
> Process 'command '/Library/Java/JavaVirtualMachines/jdk-12.0.1.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1

* 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 25s
13 actionable tasks: 1 executed, 12 up-to-date

I know I can remove logback from Dropwizard but I'd really rather figure out why gradle-api-5.4.1.jar is being bundled into my application. I can't for the life of me figure it out and don't understand why it would be pulled in.

Any direction would be appreciated.

Thanks

Mustafa Shabib
  • 798
  • 12
  • 35
  • Try to run it as a simple `jar` file without the `gradle` magic. Here [from the gradle spring-boot example](https://guides.gradle.org/building-spring-boot-2-projects-with-gradle/#building_and_running_the_spring_boot_application) use the `java -jar xxxxxx` syntax. If it runs without a problem you will know that the problem is in the way `Gradle wrapper` is interacting with the `fat jar/uber jar` of your application. – zloster Jun 07 '19 at 07:19
  • Can you post the build.gradle file ? – Sambit Jun 07 '19 at 07:47
  • @zloster Interestingly, `./gradlew run` fails with the error described, but `java -jar my-fat.jar` starts up correctly. I also tested using the `shadowJar` plugin and `./graldew runShadow` works appropriately as well. – Mustafa Shabib Jun 07 '19 at 13:38
  • Now you know that the `fat.jar` is bundled OK. You should investigate how and what `gradle wrapper` is doing differently. I can't help further because I have very little experience with `gradle`. – zloster Jun 07 '19 at 15:56

2 Answers2

1

So my mistake in both asking this question and in what I was doing was that I failed to mention or realize that I was applying the kotlin-dsl plugin in my root script on accident. Once I removed this, everything worked as I expected.

Tom
  • 16,842
  • 17
  • 45
  • 54
Mustafa Shabib
  • 798
  • 12
  • 35
0

You have to add the following in the dependency section of your build.gradle file.

dependencies {
  compile('io.dropwizard:dropwizard-core:1.2.2') {
     exclude group: 'org.slf4j', module: 'slf4j-api' 
  }

}
Sambit
  • 7,625
  • 7
  • 34
  • 65
  • The question explicitly mentioned that he is aware of this "solution". If we exclude this library will the application start with the command `java -jar /path/to/fatjar`? – zloster Jun 07 '19 at 11:07