Gradle subproject ordering and generate jar (spring boot + angular) - spring-boot

I am a Gradle newby. I have the following project setup:
Root
core: contains spring boot 2 application
ui: angular 5 front-end application
Goal: I want to run 'gradle build' from my root folder and it should contain one jar file which includes the Angular app.
I got the 'ui' covered:
apply plugin: "com.moowork.node"
buildscript {
repositories globalRepositories
dependencies {
classpath "com.moowork.gradle:gradle-node-plugin:1.2.0"
}
}
node {
// based on current version of Angular 5
version = "8.9.1"
npmVersion = "5.6.0"
download = true
}
task buildAngular(type: NpmTask) {
args = ['run', 'build']
}
buildAngular.dependsOn(npm_install)
build.dependsOn(buildAngular)
The above gradle definition will build and generate the Angular files in the static backend core application.
The 'core' gradle build file looks like this (I excluded the dependencies), nothing special:
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'xxx.xxxxxx'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
buildscript {
repositories globalRepositories
ext {
springBootVersion = '2.0.0.M7'
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
jar {
baseName = 'spring-boot-angular'
version = '1.0.0'
}
How can I make this possible? I want the following actions to be triggered when I run 'gradle build' from my root project:
run first 'gradle build' in ui
then second run 'gradle build' in core
use the generated jar file from 'core' as the end result
I can't stand the groovy like syntax, can't wait for Gradle Kotlin DSL to mature :P
Hope somebody can help. I will open source this setup (together with Spring 5, Hibernate 5 and flyway) when I get this up and ready. Thanks in advance.

You need to include the result of the frontend (ui) buildAngular task inside the jar generated in the backend (core) build:
bootJar {
dependsOn ':ui:buildAngular'
into('BOOT-INF/classes/static') {
from "${project(':ui').projectDir}/dist"
}
}
The fact that the bootJar task now depends on the buildAngular task of the frontend will make gradle order them as needed.
You can browse this project of mine to have an example using basically the same setup (except it uses yarn instead of npm to resolve dependencies)

Answer of JB Nizet should work. You can also add the following in the root gradle file:
build.dependsOn("core:build").mustRunAfter("ui:build")
Above answer is in my opinion cleaner.

Related

unable to create a executable spring boot jar by the bootJar task

basically I need to create a spring boot jar to run system spring-server service on my server
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
ext {
spring_boot_version = '1.5.7.RELEASE'
spring_version = '4.3.11.RELEASE'
}
repositories {
mavenLocal()
jcenter()
mavenCentral()
maven { url 'https://dl.bintray.com/kotlin/exposed' }
maven { url 'https://jitpack.io' }
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases' }
}
apply plugin: 'kotlin'
apply plugin: 'java'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'
bootJar {
basName = 'corda-webserver'
version = '1.0.0'
}
How can I achieve this is there something wrong with gradle dependencies or plugins?
I tried springboot task as well
So there's not enough information here to be sure of what the issue could be; so here are a few ideas.
Start by cleaning gradle cache. ./gradlew clean
Obviously the issue here is dependencies, you need to make sure gradle is able to build your project, and download dependencies.
./gradlew deployNodes (if you're using one of the corda sample projects) will build all of the files locally and should pull in the dependencies for you.
R3 now uses software.r3.com as the 'official' link to the artifact repository, you may want to take a look there and maybe look at whether the downloads are still good.
good luck!

How can I have Teamcity Artifactory plugin invoke bootJar instead of Jar in Gradle?

We are using Gradle 4.8.1 to generate Spring Boot executable jars. This works fine locally. However, we are using Teamcity to publish our artifacts into Artifactory.
The issue is, to my understanding, that the "artifactoryPublish" task invokes the "jar" task in Gradle, which uploads artifacts from "Archives". So, irrespective of whether teamcity invokes the "assemble" task, or the "bootjar" task, or the "build" task, the artifactory plugin is taking the output of the "jar" task in the end and publishes that, whereas we'd like to have the output of the "bootjar" task (fat jar) in artifactory.
Is there any way I can force artifactoryPublish to run bootjar instead of jar ? Or for the jar task to create a fat jar as well ? Or should I consider another approach ?
Here's my build.gradle from one of the subprojects
plugins {
id "org.springframework.boot" version "2.0.4.RELEASE"
id "io.spring.dependency-management" version "1.0.6.RELEASE"
}
apply plugin: 'java'
repositories {
mavenCentral()
}
description = 'atlas-data-service'
// Dynamically insert TeamCity build number if available
if (hasProperty("teamcity")) {
version = teamcity["build.number"]
println "Release version with TeamCity build number passed into gradle is " + version
} else {
// Take the default appVersion defined in top level build.gradle when building outside of TeamCity
version = "$appVersion"
}
jar {
baseName = 'data-service'
enabled = true
}
bootJar {
mainClassName = 'c.m.f.a.dataservice.AtlasDataServiceApplication'
baseName = 'data-service'
enabled = true
classifier = 'boot'
}
dependencies {
...
}
This question is from last year, but updating in case someone else comes looking with the same issue.
I used the Maven-publish plugin to get the job done.
https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#publishing-your-application-maven-publish
apply plugin: 'maven-publish'
publishing.publications {
bootJava(MavenPublication) {
artifact bootJar
}
}

Applying Gradle Dependency-Check plugin

I am trying to use the dependency.check from the following link and have been unable to get it to run properly (at all) when following the instructions given.
https://github.com/jeremylong/DependencyCheck/tree/master/dependency-check-gradle
When trying to build with the apply plugin and additional dependency the fails on startup and it throws the following error.
Where:
Build file '/Users/aaron/work/backups/eiss/build.gradle' line: 25
What went wrong:
A problem occurred evaluating root project 'eiss'.
Failed to apply plugin [id 'dependency.check']
Plugin with id 'dependency.check' not found.
I made a little progress when making some changes but was still ultimately unsuccessful.
First, I commented out the apply plugin line.
Next, I switched:
classpath "com.thoughtworks.tools:dependency-check:0.0.7"
over to:
compile "com.thoughtworks.tools:dependency-check:0.0.7"
After these two changes it began recognizing the path and I was able to see it grabbing the items from the repository.
Even with the path correct I am still having issues with the apply plugin line with it throwing the same error whenever I place it into the script or even try to change the '.' in it into a '-' (both are used in the instructions and in different repository examples).
Any help on this issue would be appreciated! Thanks
lastly here is the build.gradle script. I didn't want to just leave this blob right in the center of the post.
defaultTasks 'assemble'
// For third party libs that are widely used, keep versions in one place
ext {
MONGO_JAVA_DRIVER = "org.mongodb:mongo-java-driver:2.12.3"
RABBITMQ_VERSION = "com.rabbitmq:amqp-client:3.4.3"
LOG4J = "log4j:log4j:1.2.16"
// For groovy there are multiple libs, just capture version number and use lib-name-$GROOVY_VERSION
GROOVY_VERSION = "2.3.6"
}
//
// Common settings for all projects
//
subprojects {
defaultTasks 'assemble'
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'codenarc'
apply plugin: 'dependency.check'
targetCompatibility = "1.6"
sourceCompatibility = "1.6"
repositories {
mavenCentral()
}
dependencies {
compile LOG4J
compile "org.codehaus.groovy:groovy:${GROOVY_VERSION}"
compile "org.codehaus.groovy:groovy-json:${GROOVY_VERSION}"
compile "org.codehaus.groovy:groovy-templates:${GROOVY_VERSION}"
compile "com.thoughtworks.tools:dependency-check:0.0.7"
testCompile group: 'junit', name: 'junit', version: '4.+'
testCompile "org.codehaus.groovy:groovy-test:${GROOVY_VERSION}"
testCompile "org.hamcrest:hamcrest-core:1.3"
}
clean.doLast {
// The archive path is configured via the jar tasks. Can't use
// delete jar.archivePath because that will configure the delete with
// the wrong (default) path of build/libs/<component.jar>
jar.archivePath.delete()
jarSources.archivePath.delete()
}
//--------------------------------------------------------------------
// Run and test
//--------------------------------------------------------------------
test {
// Uncomment to see standard output when running tests
testLogging.showStandardStreams = true
// This causes tests to run even when nothing has changed
outputs.upToDateWhen { false }
maxParallelForks = 1
}
task runClass(dependsOn: 'classes', type: JavaExec) {
if (project.hasProperty('classToRun')) {
if (project.hasProperty('arguments')) {
args(arguments.split(','))
}
classpath = sourceSets.main.runtimeClasspath
main=classToRun
}
}
//run this task to create source jars
task jarSources(type:Jar){
destinationDir = new File(projectDir.parent + "/sourcelibs")
from sourceSets.main.allSource
classifier 'sources'
}
}
You added plugin dependency in a wrong place, to the dependencies of your project, not a build script itself, which will use it. Try to add buildscript dependencies, as it's made in the example of plugin installation
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.thoughtworks.tools:dependency-check:0.0.7'
}
}
And then return your apply plugin
apply plugin: 'dependency.check'
Though this is very old post, accepted answer is using legacy plugin application, whereas below could be used while using the plugins DSL: https://plugins.gradle.org/plugin/org.owasp.dependencycheck
plugins {
id "org.owasp.dependencycheck" version "7.3.0"
}
With recent version of gradle it is below steps
add id 'com.diffplug.spotless' version '6.3.0' in plugins section like
plugins {
id 'com.diffplug.spotless' version '6.3.0'
}
And define your task to generate required format reports. Here for e.g. xml and json will be generated along with the html report
dependencyCheck{
formats=['xml','json']
check.dependsOn(dependencyCheckAnalyze)
}
And this can be integrated with Sonar by adding below properties to sonare.properties file (Provide dependency plugin is installed already on the sonar)
sonar.dependencyCheck.xmlReportPath=build/reports/dependency-check-report.xml
sonar.dependencyCheck.jsonReportPath=build/reports/dependency-check-report.json
sonar.dependencyCheck.htmlReportPath=build/reports/dependency-check-report.html

How do I run spring-boot 1.2.x executable jar

This is a continuation of another question that got partially answered. Since the question morphed, I thought I should open a question that is more inline with that.
I have a project that started out as a spring-boot 1.1.7.RELEASE and I started from a directory containing the jar and an application.properties file via:
java -jar edm-0.1.0.jar
Everything was right as rain until I upgraded to spring-boot 1.2.1.RELEASE. Now, when I try to start with java -jar the app appears to start but trying to login gives me an error that the /templates html pages aren't found.
It would appear that the preferred way to start spring-boot apps is:
gradle bootRun
This would appear to work as long as I am in the top level of my project directory. But if I move the jar file off to another directory, and try to run it, I get the error:
:temp$ gradle bootRun
FAILURE: Build failed with an exception.
* What went wrong:
Task 'bootRun' not found in root project 'temp'.
* Try:
Run gradle tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
so when I run "gradle tasks" I can see that "bootRun" is not available:
:temp$ gradle tasks
:tasks
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]
Help tasks
----------
dependencies - Displays all dependencies declared in root project 'temp'.
dependencyInsight - Displays the insight into a specific dependency in root project 'temp'.
help - Displays a help message
projects - Displays the sub-projects of root project 'temp'.
properties - Displays the properties of root project 'temp'.
tasks - Displays the tasks runnable from root project 'temp'.
I guess this is a spring-boot gradle issue, but I can't say for sure. My version:
:temp$ gradle -version
------------------------------------------------------------
Gradle 1.10
------------------------------------------------------------
Build time: 2013-12-17 09:28:15 UTC
Build number: none
Revision: 36ced393628875ff15575fa03d16c1349ffe8bb6
Groovy: 1.8.6
Ant: Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy: 2.2.0
JVM: 1.8.0_31 (Oracle Corporation 25.31-b07)
OS: Mac OS X 10.10.2 x86_64
And here is my build.gradle:
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'maven'
idea {
project {
//if you want to set specific jdk and language level
jdkName = '1.8'
languageLevel = '1.8'
}
}
jacoco {
toolVersion = "0.7.0.201403182114"
}
project.ext {
springBootVersion = '1.2.1.RELEASE'
}
configurations {
querydslapt
}
buildscript {
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url "http://repo.spring.io/libs-milestone" }
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE")
}
}
jar {
baseName = 'edm'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-milestone" }
maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url "http://repo.spring.io/snapshot" }
maven { url 'http://repo.spring.io/milestone' }
}
dependencies {
querydslapt group: 'com.mysema.querydsl', name: 'querydsl-jpa', version: '2.8.0', classifier: 'apt-one-jar', transitive: false
compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion")
compile("org.springframework.security:spring-security-web:4.0.0.M1")
compile("org.springframework.security:spring-security-config:4.0.0.M1")
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:2.1.1.RELEASE')
compile('com.android.tools.build:gradle:1.0.1')
task wrapper(type: Wrapper) {
gradleVersion = '2.0'
}
I did read the documentation, but nothing seems to address why I am having this problem. I would really appreciate any help you can send my way.

Using jettyRunWar or jettyRun in Gradle with a Spring Boot app results in just a directory listing in the browser

I'm using Gradle and Spring Boot for the first time. I decided to create a project that actually builds a WAR archive and I'm using the Gradle Jetty plugin. If I run the jettyRun or jettyRunWar tasks, in my browser all I'm seeing is a directory listing, not my actual application.
For example, the jettyRunWar task results in a directory listing like this:
META-INF/
WEB-INF/
dist/
The dist/ directory contains my static files.
Maybe I'm missing something fundamental since I'm using Gradle and Spring Boot for the first time.
I'm trying to test my app while making changes to my static files without restarting the app. Here is my build.gradle file.
buildscript {
repositories {
maven { url "http://repo.spring.io/libs-snapshot" }
mavenLocal()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:0.5.0.M6"
}
}
apply plugin: "java"
apply plugin: "idea"
apply plugin: "spring-boot"
apply plugin: "war"
war {
baseName = "mis-support-client"
version = "1.0.0-SNAPSHOT"
includes = ["dist/**"]
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/libs-snapshot" }
}
dependencies {
testCompile "junit:junit:4.11"
compile ("org.springframework.boot:spring-boot-starter-web:0.5.0.M7") {
exclude module: "spring-boot-starter-tomcat"
}
compile "org.springframework.boot:spring-boot-starter-jetty:0.5.0.M7"
compile "org.springframework.boot:spring-boot-starter-security:0.5.0.M7"
compile "org.springframework.boot:spring-boot-starter-websocket:0.5.0.M7"
compile "javax.inject:javax.inject:1"
compile "org.codehaus.jackson:jackson-mapper-asl:1.9.12"
compile "org.apache.httpcomponents:httpclient:4.3.1"
compile "commons-io:commons-io:2.4"
}
task wrapper (type: Wrapper) {
gradleVersion = "1.8"
}
Did you try ./gradlew bootRun instead? Normal Spring Boot project has server embedded for easier usage :)
This task requires gradle plugin:
apply plugin: 'spring-boot'
Features
Embed Tomcat or Jetty directly (no need to deploy WAR files)
Task
Execution tasks
---------------
bootRun - Run the executable JAR/WAR

Resources