spring-bootgradlespring-boot-gradle-plugin

Spring Boot Issue between jar and task that build jar: Gradle


Right now I am having this issue where I need to have my SpringBoot application be turned into an executable jar, but it needs to be done in a task as opposed to just a configuration in the gradle.build.

So the below snippet in my build.gradle will produce an executable jar:

jar {
    manifest {
        attributes 'Main-Class': 'com.path.name.to.main.App'
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

Everything works, but when I make the jar creation a task the jar no long becomes executable and throws this error Error: Could not find or load main class com.path.name.to.main.App :

task makeJar(type: Jar) {
    archiveName = 'app.jar'
    manifest {
        attributes 'Main-Class': 'com.path.name.to.main.App'
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

The way my company does deployments it is advisable to have the jar creation in a task in the build.gradle as opposed to the configuration mentioned above.

However, I'm not really sure why moving it from jar config to a task would affect the outcome of the actual jar that was created and what do I need to do to fix this?


Solution

  • First of all, the jar configuration you are talking about is actually a task of type Jar, it just gets created by Gradle (most probably by its Java plugin). Checkout the documentation on tasks created by plugins that are applied to your build script.

    As an example you may access your task makeJar in the same way as the task jar once it has been created:

    task makeJar(type: Jar)
    
    makeJar {
       // configuration things
    }
    

    The way my company does deployments it is advisable to have the jar creation in a task in the build.gradle as opposed to the configuration mentioned above.

    Knowing that jar is also a task shows that this deployment policy of your company does not make sense at all. You can configure and use the task jar in the same way as a task that was created manually.

    However, sometimes it makes sense to both produce a JAR file with just the project classes and an executable JAR. Since the jar task already produces the first one, we need another task to produce the second one. Executable JARs are also called fat oder uber JARs and there is actually a really good plugin to create them.

    The root of your actual problem is that the task jar, since it is created by the Java plugin, has some configuration applied to it automatically that your task makeJar is missing. With the line from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } all your project dependencies inside the compile configuration are added to the JAR, but the code in your own project is missing. The following code adds the contents of the regular jar task:

    task makeJar(type: Jar) {
        archiveName = 'app.jar'
        manifest {
            attributes 'Main-Class': 'com.path.name.to.main.App'
        }
        with jar
        from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    }