I have a Spring Boot project that is built using Gradle. It has compile dependencies on other projects. All the projects are mentioned via "includeFlat" in a settings.gradle file in a master project.
My problem: the boot ("fat") jar that is generated by the build omits the project dependencies.
Here's the project structure:
master
(no source)
build.gradle - applies 'Eclipse' plugin (but not Java)
settings.gradle -- has 'includeFlat' for projectA, projectB
projectA
src/main/java/...
build.gradle
projectB
src/main/java/...
build.gradle -- see below
The build.gradle for projectB looks roughly like this:
buildscript
{
repositories
{
mavenCentral()
}
dependencies
{
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.1.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
jar
{
baseName = 'xxx'
version = '0.1.0'
}
repositories
{
mavenCentral()
}
jar {
enabled = true
}
dependencies
{
compile project(":projectA")
}
"gradle build" on projectB generates both a regular and a boot jar. I expect the boot jar to include the classes from ":projectA" -- but they are missing.
Other than that, both projects build and run properly, whether built individually or via the master project.
Related
I have a multi-module composite build project.
The project structure is this:
Panda. // Root project
-PandaService. // Service module
-PandaDataAccessLayer // DAL module whose code are generated with JOOQ
I want to exclude PandaDataAccessLayer module for checkstyle, because its code are generated automatically with JOOQ.
My checkstyle.xml is located at Panda/config/checkstyle/checkstyle.xml, and here is the build.gradle in my root project Panda:
repositories {
mavenCentral() // Use Maven Central for resolving dependencies.
}
subprojects {
apply plugin: 'java'
apply plugin: 'checkstyle'
checkstyle {
toolVersion = '10.7.0'
configFile = rootProject.file('config/checkstyle/checkstyle.xml')
checkstyleMain.exclude '**/PandaDataAccessLayer/**'
}
sourceCompatibility = '11'
targetCompatibility = '11'
}
I can see that checkstyle is running with ./gradlew build. However, the generated report still shows that it checks code in PandaDataAccessLayer module.
Checkstyle rule violations were found. See the report at:file:///****/panda/PandaDataAccessLayer/build/reports/checkstyle/main.html
How can I exclude the PandaDataAccessLayer completely from checkstyle?
This is follow up of my previous question
Convert gradle multi project to springboot fat jar application
I had a http servlet application which was a multi project gradle build, where my project was a contain gradle HttpServlet project and it depends on the other two gradle java projects. I deployed all the 3 jars in the tomcat webapps/Web-INF/lib directory and run it.
Now there is a requirement that I have to convert my application as a spring boot application and instead of 3 separate jars I have to create a fat jar which I should run it.
I arranged my code as follows
Rootrepository
- settings.gradle
- build.gradle
- Springboot project
- build.gradle
-src….
- OtherGardleProject1
- Src…
- OtherGardleProject2
- Src…
Please see `root project’s build.gradle`
version = '1.0.0'
group = ‘myproj’
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'groovy'
apply plugin: 'eclipse'
subprojects {
repositories {
mavenCentral()
}
}
apply plugin: 'java'
sourceCompatibility = 1.8
compileJava
jar {
from sourceSets.main.allSource
}
}
subprojects.each { subproject ->
evaluationDependsOn(subproject.path)
}
task mmJar(type: Jar, dependsOn: subprojects.jar) {
manifest {
attributes 'Main-Class': 'org.springframework.boot.loader.JarLauncher'
attributes 'Start-Class': ‘mypackage.springboot.Application'
}
subprojects.each { subproject ->
from subproject.configurations.archives.artifacts.files.collect {
zipTree(it)
}
}
}
dependencies {
compile 'junit:junit:4.12'
compile 'org.slf4j:slf4j-api:1.7.7'
}
Please see springboot projects’ build.gradle
buildscript {
ext {
spring_plugin_version = '2.1.1.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:$spring_plugin_version")
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
}
}
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
dependencies {
implementation('org.springframework.boot:spring-boot-starter-quartz')
implementation('org.springframework.boot:spring-boot-starter-web')
compile project(‘:otherproject1’)
compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1'
compile group: 'commons-io', name: 'commons-io', version: '2.4'
compile('org.springframework:spring-webmvc')
runtimeOnly('org.springframework.boot:spring-boot-devtools')
compileOnly('org.projectlombok:lombok:1.18.8')
annotationProcessor('org.projectlombok:lombok:1.18.8')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Then I ran gradle clean assemble mmJar and it created a fat jar as expected.
But when I try to run java -jar build/libs/myproj-1.0.0.jar
Exception in thread "main" java.lang.IllegalStateException: Failed to get nested archive for entry BOOT-INF/lib/JavaEWAH-1.1.6.jar
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:108)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:86)
at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:70)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:49)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.io.IOException: Unable to open nested jar file 'BOOT-INF/lib/JavaEWAH-1.1.6.jar'
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:256)
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:241)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:103)
... 4 more
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/JavaEWAH-1.1.6.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:284)
at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:264)
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:252)
... 6 more
Can someone please suggest what am I doing wrong?
As suggested by #M.Deinum and me in the linked post, just let spring boot gradle plugin do the the job. In your root folder keep the settings.gradle file and remove the build.gradle. Run
gradle clean build
in the Rootrepository folder. Gradle will build the projects included in settings.gradle and create the fat jar in the Springboot project/build/libs folder
I am trying out a simple gradle spring boot application as per the below URL
https://spring.io/guides/gs/spring-boot/
This is my build.gradle file
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'my-jar'
version = '1.0.0'
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
testCompile "junit:junit"
}
I am using a local artifactory and my init.gradle has the buildscript configuration which is below
buildscript {
repositories {
maven {
url 'http://mylocalartifactory:8081/'
}
}
dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:1.5.2.RELEASE" }
}
I get the below error when i try to run gradlew build
What went wrong:
Could not resolve all dependencies for configuration ':compileClasspath'.
> Could not find org.springframework.boot:spring-boot-starter-web:.
Looks like the version is not getting applied for the dependency.
What I understand is that the version will be defaulted by the spring-boot plugin .
Am I missing something ?
It works fine if I mention the version number in the dependency
dependencies {
compile "org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE"
testCompile "junit:junit"
}
Though I can make it work , it beats the purpose of using spring boot if I need to manually specify the spring version jar dependency .
Kindly revert back if you see any issue in my build.gradle or init.gradle
I have a project corehibernate and a project coregeneral. corehibernate is dependent on coregeneral. I need the jar file of coregeneral to be bundled along with the corehibernate jar. I tried various versions of the build.gradle thing, nothing worked.
I tried compile files("../coregeneral/build/libs/coregeneral.jar")
This version of fatJar too does not work.
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
compile (':coregeneral')
testCompile 'junit:junit:4.12'
}
jar {
baseName='corehibernate'
from ('bin')
}
task fatJar(type: Jar, dependsOn: jar) {
baseName = project.name + '-fat'
}
There are two basic ways how to bundle projects together. The first would be to use application plugin which creates a zip with scripts that will also execute your application and bundle all jars by default. Second way is to use distribution plugin and define the final archive yourself (zip or tar).
Here is a sample project using the application plugin:
settings.gradle
rootProject.name = 'root'
include 'partone', 'parttwo'
build.gradle
subprojects {
apply plugin: 'java'
}
partone/build.gradle - this one is empty
parttwo/build.gradle
apply plugin: 'application'
mainClassName = 'Hello'
dependencies {
compile project (':partone')
}
Give that both projects actually have some content (classes), when you run gradle :projecttwo:build it will generate a zip file with executable scripts and both jars bundled inside.
If you prefer to use distribution plugin, change the parttwo/build.gradle to:
apply plugin: 'distribution'
distributions {
main {
contents {
from jar
from (project.configurations.runtime)
}
}
}
dependencies {
compile project (':partone')
}
And again run gradle :parttwo:build. It will create a zip file that contains both jars.
I am having a problem building some interdependent modules in a gradle based project. What I want to be able to do is have a project (similar to some maven projects I have worked with), where the dependencies are on each others versions, so when deployed to a maven repository, are available, but building a module builds the dependencies.
To illustrate, I have a gradle project with a few submodules.
ProjectA
|- module-a
\- module-b (depends on module-a)
In module b, I specify the dependency using compile "{groupId:module-b:{versionName}, and in the project root build.gradle, I have
project(':module-b') {
dependencies {
compile project(':module-a')
}
}
Another project with a dependency on the other project.
ProjectB
\- module-c (depends on module-b)
When building ProjectB, there are errors about not being able to find ProjectA:module-a:unspecified. The pom generated for module-b does include that dependency.
If I remove the dependency specification in ProjectA's root build.gradle, when I try and build, module-b cannot find module-a (during the dependency resolution phase). module-a would not be deployed anywhere yet, so this makes sense to me.
I would like module-b to depend on it's sibling, but have it's pom show a maven-style version dependency, so that module-c can depend on module-b and transitively get module-a.
(There is no requirement that ProjectB be a gradle project. Either maven or gradle should work.)
Gradle configuration files
settings.gradle
include 'module-a', 'module-b'
build.gradle
project(':module-b') {
apply plugin: 'java'
dependencies {
compile project(':module-a')
}
}
module-a/build.gradle
group 'com.example.coatedmoose'
version '1.0.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
mavenLocal()
}
}
}
module-b/build.gradle
group 'com.example.coatedmoose'
version '1.0.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'maven'
dependencies {
compile 'com.example.coatedmoose:module-a:1.0.0-SNAPSHOT'
}
uploadArchives {
repositories {
mavenDeployer {
mavenLocal()
}
}
}