How to merge client and server builds into one jar with gradle? - java

I have a project with the following structure:
web-client/ # Angular Client
build/
build.gradle
server/ # Spring Boot Application
build/
build.gradle
build.gradle # The "parent" project. Works on web-client and server
The parent is supposed to copy the compiled web-application into server/build/classes/static such that it will be copied to /BOOT-INF/classes/ of the final jar where it will be served by the Spring Boot server.
Everything is working so far except the last part. Those files are nor copied into the final jar and I think it's because it got already build at the time where the copying task is executed.
This is the script which I am currently using:
task buildWebApp {
outputs.dir('mobile-client/build')
dependsOn ':mobile-client:buildWebApp'
}
task copyWebApp {
doFirst {
copy {
from 'mobile-client/build'
into 'server/build/classes/static'
}
}
dependsOn tasks.buildWebApp
}
# assemble.dependsOn copyWebApp
build.dependsOn copyWebApp
How can I make sure that those files from mobile-client/build end up in the final jar of server?

Cannot guarantee its current functionality, but this I used in one of my projects a few years ago. I did use separate gradle submodule for building Frontend and then separate module for Backend where I included Frontend as a JAR:
root gradle project -> frontend
-> backend
Frontend build.gradle (builds frontend JAR with /static/**)
apply plugin: "com.moowork.node"
apply plugin: 'java'
node {
version = '8.9.3'
download = true
}
def webResources = "$buildDir/web-resources/main"
sourceSets {
main {
output.dir(webResources, builtBy: 'buildWeb')
}
}
task webInstall(type: NpmTask) {
args = ['install']
}
task buildWeb(type: NpmTask) {
dependsOn webInstall
args = ['run', 'build']
}
build.dependsOn buildWeb
Backend build.gradle
apply plugin: 'spring-boot-gradle-plugin'
apply plugin: 'idea'
dependencies {
compile project(':frontend')
}

Related

Spring boot where is my jar file

Spring boot makes it really easy to setup a simple app.
But it takes me longer to actually get a jar file which I can upload to a remote server.
I am using IntelliJ, no command line, and I use gradle. The application is running somehow out of Intellij. But where are the created files? Where is my jar from Bootjar?
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'gs-spring-boot'
version = '0.1.0'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")
testCompile("org.springframework.boot:spring-boot-starter-test")
// add spring data repos
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.postgresql:postgresql:42.2.4")
// REST interface
compile("org.springframework.boot:spring-boot-starter-data-rest")
// Security
compile("org.springframework.boot:spring-boot-starter-security")
}
Update: Added a picture of the project structure:
Update 2: Folder structure:
There will not be a jar created if you are just running this in your IDE. In order to do that, you need to run the gradle build (in your case) either from your IDE or the command line to get it to build it into a jar.
From the command line, go to your project directory and type this:
./gradlew build
This executes the gradle wrapper, which should download everything you need to run the build, and then executes the build.
You will then find your jar in build/lib
build/libs (if you've ran build to build the jar file)

Gradle is not place WebJar contents into the correct place in my Jar file

I've got a basic Java application in which I would like to use WebJars. I use Gradle as my build system. I would like to use the WebJars for Bootstrap and JQuery so I can easily reference and update them in my Spring-Boot/ThymeLeaf application. The application is basically the one from the form tutorial located here
As I understand it Gradle should place all the files from the WebJars into the META-INF folder in my Jar file. If I understand everything correctly the Spring-Boot resource handler will then load resource from META-INF/ when I reference something in my html page that starts with /webjars/
Unfortunately this doesn't work (yet). Since I see in Tomcat's log output that the resource handler is correctly installed. I decided to check if the files are actually in my Jar file.
When I extract my Jar file the META-INF folder only has a file called MANIFEST.MF with some information about Spring Boot. There is a BootStrap-3.3.7.Jar and a JQuery-3.2-1.Jar file in BOOT-INF/lib but I don't think that is where they are supposed to end up. (Or am I wrong and is there error somewhere in the resource handler?).
How do I tell gradle to do the right thing with these files when I run gradle build?
My gradle.build file looks like this:
buildscript {
ext {
springBootVersion = '1.5.8.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: "jacoco"
jar {
baseName = 'gs-serving-web-content'
version = '0.0.1'
}
bootRun {
addResources = true
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.webjars:jquery:3.2.1")
compile("org.webjars:bootstrap:3.3.7")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
Gradle is doing the right thing as the jars should be packaged in BOOT-INF/lib. The root of each jar in BOOT-INF/lib is then added to the classpath from where each its webjar related content in META-INF content should be found.
I'd recommend asking another question that focuses on what your application's doing at runtime. As far as I can tell, everything's working as it should at build time.

Include react generated HTML/JS files from composite gradle build

I have 2 Gradle projects that I want to link together. The first project has a standard Spring Boot app, and I want to link it with a ReactJS project that I've added a "build.gradle" file to.
I want to include the files generated into the "build/" directory of the ReactJS project into the "META-INF/resources" directory of the Spring Boot project.
These are my gradle.build files:
Spring Boot Gradle project:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE'
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
group = "com.myproject"
version = "1.0"
bootRun {
systemProperties = System.properties
}
repositories {
jcenter()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("com.myproject:myproject-ui:1.0")
}
ReactJS Gradle project:
plugins {
id "com.moowork.node" version "1.1.1"
}
node {
download = true
}
apply plugin: 'java'
group = "com.myproject"
version = "1.0"
buildDir = 'dist'
task webjar(type: Jar, dependsOn: 'jar') {
from(fileTree('build')) {
into 'META-INF/resources'
}
}
build.dependsOn(webjar)
build.dependsOn(npm_run_build)
clean {
delete 'dist'
delete 'build'
}
Assume I've setup the "settings.gradle" files correctly such that it is a composite build, because that doesn't seem to cause issues.
When I run the "build" task for the ReactJS project, the "build/" directory is successfully generated, but I doesn't seem to be included by the Spring Boot project anywhere. How can I include the generated HTML/JS files such that they show up when I run the "bootRun" task of the Spring Boot project.
Typically you'd use a Configuration for this
reactjs/build.gradle
configurations {
wj
}
task webjar(type: Jar) { ... }
dependencies {
wj files(webjar)
}
springboot/build.gradle
configurations {
wj
}
dependencies {
wj project(path: ':reactjs', configuration: 'wj')
}
war {
with copySpec {
from zipTree(configurations.wj.singleFile)
into 'META-INF/resources'
}
}

How to export a Spring Boot project to an executable standalone file?

I have created a project in Spring Tool Suite with Spring Boot and Gradle, and I really don't know how to export to make it work.
I don't know much about gradle, just the basics to add dependencies from the maven repository. So in some articles says to apply the application plugin to do the task, but I don't know how to set up the configuration file and how to create the executable.
If anyone could write or link a step by step detailed explanation on how to do it, it would be very much appreciated.
This is my build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
springBoot {
mainClass = "com.rodamientosbulnes.objetivosventa.Application"
executable = true
}
jar {
baseName = 'objetivosventa'
version = '0.1.0'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework:spring-jdbc')
compile('net.sourceforge.jtds:jtds:1.3.1')
compile('org.apache.poi:poi-ooxml:3.13')
compile('com.miglayout:miglayout-swing:4.2')
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
Build file looks fine, you only need to run gradle build (or Run As -> Gradle -> Gradle build in the STS) to create the runnable jar.
More details about configuration of the gradle plugin are available on spring boot documentation site.
Gradle's application plugin doesn't make a single execitable for you, but it can create a distribution, which includes all the dependencies, jar-artifact for your project and 2 scripts to run it (one batch-file and linex executable).
The main thing you need to know, is that spring-boot plugin already provide all the task from application plugin you may need. All the task you can find here. You need distZip or installDist to package your project to the distribution. This task will create a ready project distribution under your project-folder/build folder. One more task you may find usefull is buildRun which will run you spring-boot application without package it into distribution.

Using Gradle serve a front end (JS) and a backend API (Java)

Im trying to create a web application using Gradle. The front end UI will be built with Angular.js and the backend should be Java. When I say backend, I mean a Java / Spring based API that will be queried using Ajax from Angular.js.
So basically what Im trying to do is to get any URL's that start with mysite.com/api/... should be routed to the src/com/veight/client files, or in other words to the Java backend. And then any other URLs such as mysite.com/login should be handled by the JavaScript / Angular.js front end.
I have the JavaScript / Angular.js routing working for the front end using the following build.gradle file. How should I go about sending routes that match mysite.com/api/... to the Java / Spring back end?
Thank you for the help!
Note: I know that Java Spring naturally does this routing where it sends certain routes mysite.com/home to one folder and other routes mysite.com/api/... are handled buy a xml file. But I think its possible to handle this in the build.gradle file. So I was hoping to prove / disprove that theory.
File Structure
.gradle
.settings
build
gradle
src
com
veight
client
WebContent
Heres my build.gradle:
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:1.2.4' // Gradle Tomcat Plugin
classpath 'com.eriwen:gradle-css-plugin:1.11.1'
classpath 'com.eriwen:gradle-js-plugin:1.12.0'
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'tomcat'
apply plugin: 'eclipse-wtp'
apply plugin: 'js'
apply plugin: 'css'
sourceCompatibility = 1.7
version = '1.0'
task wrapper(type: Wrapper) {
gradleVersion = '2.0'
}
repositories {
mavenCentral() // Allow access to the Maven Centeral Repo
}
dependencies {
def tomcatVersion = '7.0.54'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}"
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
}
}
sourceSets {
main {
java {
srcDirs 'src'
}
}
}
// End: Java Plugin Configuration
// Start: Tomcat Plugin Configuration
tomcatRun {
httpPort = 8080
stopPort = 8081
URIEncoding = 'utf-8'
webAppSourceDirectory = file('WebContent')
}
eclipse {
wtp {
component {
contextPath = '/'
deployName = 'client'
}
}
}

Categories

Resources