Spring Boot plugin doesn't add lib folder in jar - spring-boot

I have the following build.gradle:
group 'as'
version '1.0'
buildscript {
ext {
springVersion = '5.0.4.RELEASE'
springBootVersion = '1.5.6.RELEASE'
springJPAVersion = '2.0.5.RELEASE'
javaxVersion = '1.0.2'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'reports'
version = '0.0.1'
manifest {
attributes 'Implementation-Title': baseName,
'Implementation-Version': version
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
repositories {
jcenter()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}"
implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}"
implementation "org.springframework.data:spring-data-jpa:${springJPAVersion}"
implementation "javax.persistence:persistence-api:${javaxVersion}"
implementation "mysql:mysql-connector-java:5.1.43"
testImplementation group: 'junit', name: 'junit', version: '4.11'
}
And gradle creates jar with following structure:
BOOT-INF
classes
META-INF
org
But it seems that the structure must be the following:
BOOT-INF
classes
lib
META-INF
org
with lib folder, which contains dependencies, because now after launch I get error:
Exception ...
Caused by: java.lang.NoClassDefFoundError:
org/springframework/boot/SpringApplication at com.as.reports.Application.main(Application.java:12)

So I know this answer is probably too late to help you, but I stumbled across this question while trying to solve the exact same problem, and was reminded of this.
After half a day of trial and error, I found the solution, so hopefully I can save someone else the pain of finding this unanswered question.
The problem is with using the implementation keyword in your dependencies. The 1.x Spring Boot Gradle plugin doesn't appear recognize that keyword as notating required dependencies for repackaging a fat jar. If you change those back to the older compile keyword, you should get the necessary lib folder.

Related

Spring framework import failed

I am starting on Spring and learning its foundations. I created a project in intellij
It was giving an error stating that web cannot be imported.
so i guessed it must have been . my gradle build file which does not have web
I tried to import in manually via the build.gradle file as below but it throws me an error saying it cannot be found.
WHat am i doing wrong and how can i resolve this?
plugins {
id 'org.springframework.boot' version '2.2.2.BUILD-SNAPSHOT'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'io.codementor.gtommee'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
any help?
You are missing the spring-boot-starter-web dependency in your build.gradle file.
To get started, have a look at https://start.spring.io/

Gradle spring boot 2 spring-boot-dependencies cannot download dependencies

I am using eclipse 2018, gradle 5.2.1, buildship 3.0.1.
My config looks like:
I try to create spring boot 2 according to building-spring-boot-2-projects-with-gradle
The build.gradle is:
plugins {
id 'java'
id 'com.gradle.build-scan' version '2.1'
id 'org.springframework.boot' version '2.1.3.RELEASE'
}
repositories {
jCenter()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-dependencies:2.1.3.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
components {
withModule('org.springframework:spring-beans') {
allVariants {
withDependencyConstraints {
// Need to patch constraints because snakeyaml is an optional dependency
it.findAll { it.name == 'snakeyaml' }.each { it.version { strictly '1.23' } }
}
}
}
}
}
buildScan {
// always accept the terms of service
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
// always publish a build scan
publishAlways()
}
bootJar {
mainClassName = 'gt4.App'
}
However, after I save build.gradle, the Project and External Dependencies disappear, and the spring boot jars are not downloaded too.
What I was wrong?
If I create spring boot project with gradle by Spring Tool Suite 4, the generated build.gradle is:
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
then it works.
Do I use spring-boot-dependencies wrong?
try to deleting the local Repository and build project again to download dependancy.
Delete .m2 or .gradle folder and then Rebuild your project.
a)On a Windows machine, the .gradle or .m2 path will be:
c:\Users\username\.m2 or c:\Users\username\.m2
b)On linux machine, the .gradle or .m2 path will be:
USER_HOME/.m2/

How can I generate JPA metamodel in spring-boot with gradle?(+ lombok)

I want add JPA metamodel to my project - Spring boot + gradle
I find a lot of examles how can i do it but all with Maven. Also I find this site: https://plugins.gradle.org/search?term=metamodel
and try first three plugins. With each plugins I get errors: error: cannot find symbol in classes marked lombok #Builder annotation and some classes is not entity. It is example some plugin:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.github.iboyko.gradle.plugins:jpamodelgen-plugin:1.0.1"
}
}
dependencies {
compile ('org.hibernate:hibernate-jpamodelgen')
}
1) Which plugin or method is the most official (correct) to create JPA metamodel in Spring boot + spring-data-jpa + gradle ?
2) How can I specify only the package with entities and not scan another classes?
3) how to make friends with it with lombok?
EDIT
I add this code to gradle file:
sourceSets.configureEach { sourceSet ->
tasks.named(sourceSet.compileJavaTaskName).configure {
options.annotationProcessorGeneratedSourcesDirectory = file("$buildDir/generated/sources/java")
}
}
and it generate classes_ fine. After that I mark
generated/sources/java
folder ass root of generated classes(rigth clik to this folder and mark as)
After that I try import generated classes in my repository and IDE show this:
For each module I have 2 module - my_module and my_module_main(I don't understand why) and all classes generate in my_module but all code in my_module_main. If I add this dependency - I have this:
and in generated class I have this:
I was struggling through the same issue. Finally I got it working by adding both dependencies in both compileOnly and annotationProcessor forms. Don't ask me why, but it somehow works.
compileOnly 'org.projectlombok:lombok:1.18.10'
annotationProcessor 'org.projectlombok:lombok:1.18.10'
compileOnly 'org.hibernate:hibernate-jpamodelgen'
annotationProcessor('org.hibernate:hibernate-jpamodelgen')
Did you use Spring Initalizr to generate the project?
This is what you get from Initializr (expect the jpamodelgen that I added by myself):
buildscript {
ext {
springBootVersion = '2.1.1.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: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
runtime('com.h2database:h2')
compileOnly('org.projectlombok:lombok')
compileOnly ('org.hibernate:hibernate-jpamodelgen')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}
// Add source set to define where the generated source code should go to
sourceSets.configureEach { sourceSet ->
tasks.named(sourceSet.compileJavaTaskName).configure {
options.annotationProcessorGeneratedSourcesDirectory = file("$buildDir/generated/sources/java")
}
}
You can find a demo project on GitHub:
https://github.com/simasch/demo-gradle-jpa
In IntelliJ you can right click on generated/sources/java and choose

How to force a specific dependency version in a gradle buildscript

There's an issue for the gradle-docker-plugin and SpringBootVersion 2.0.0.M4
M4 uses a newer jersey client and using the docker-plugin ends in an Exception:
ERROR com.github.dockerjava.core.async.ResultCallbackTemplate - Error during callback
java.lang.IllegalStateException: InjectionManagerFactory not found.
at org.glassfish.jersey.internal.inject.Injections.lambda$lookupInjectionManagerFactory$0(Injections.java:98)
at java.util.Optional.orElseThrow(Optional.java:290)
at org.glassfish.jersey.internal.inject.Injections.lookupInjectionManagerFactory(Injections.java:98)
at org.glassfish.jersey.internal.inject.Injections.createInjectionManager(Injections.java:68)
at org.glassfish.jersey.client.ClientConfig$State.initRuntime(ClientConfig.java:432)
at org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:341)
at org.glassfish.jersey.client.ClientConfig.getRuntime(ClientConfig.java:826)
at org.glassfish.jersey.client.ClientRequest.getConfiguration(ClientRequest.java:285)
at org.glassfish.jersey.client.JerseyInvocation.validateHttpMethodAndEntity(JerseyInvocation.java:143)
at org.glassfish.jersey.client.JerseyInvocation.<init>(JerseyInvocation.java:112)
at org.glassfish.jersey.client.JerseyInvocation.<init>(JerseyInvocation.java:108)
at org.glassfish.jersey.client.JerseyInvocation.<init>(JerseyInvocation.java:99)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:456)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:357)
at com.github.dockerjava.jaxrs.async.POSTCallbackNotifier.response(POSTCallbackNotifier.java:29)
at com.github.dockerjava.jaxrs.async.AbstractCallbackNotifier.call(AbstractCallbackNotifier.java:50)
at com.github.dockerjava.jaxrs.async.AbstractCallbackNotifier.call(AbstractCallbackNotifier.java:24)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
My BuildScript in my main project:
buildscript {
ext {
springBootVersion = "2.0.0.M4"
}
repositories {
maven { url "https://repo.spring.io/plugins-snapshot" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
}
}
....
As you can see, we load the spring-boot-gradle-plugin version=2.0.0.M4 and all its dependencies.
My subproject build.gradle:
apply plugin: "org.springframework.boot"
apply from: "docker.gradle"
....
Most important the docker.gradle file in the same directory as the build.gradle of the subproject:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-docker-plugin:3.0.11'
}
}
apply plugin: com.bmuschko.gradle.docker.DockerRemoteApiPlugin
import com.bmuschko.gradle.docker.tasks.image.*
...
task buildImage(type: DockerBuildImage, dependsOn: copyDockerFiles) {
version.release = true
dockerFile = file("${projectDir}/build/docker/Dockerfile")
inputDir = file("${projectDir}/build/docker")
tags = ['...']
}
My Questions:
How do I know which Version of the jersey client loads SpringBoot 2.0.0.M4?
How do I force gradle in docker.gradle to use a specific version of the jersey client?
Adding to the classpath didnt work. I think gradle will just use the newest version, wich will be loaded by SpringBoot 2.0.0.M4
You have to add the following in your build.gradle dependencies as pointed in: This Link
dockerJava 'com.nirima:docker-java-shaded:0.16.2'
dockerJava 'org.slf4j:slf4j-simple:1.7.5'
dockerJava 'cglib:cglib:3.2.0'
After that you have to separate "buildImage" and "tagImage" tasks as suggested in This link
I have tested this with: spring boot 2.0.0.M6
I simply did:-
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
classpath "org.mozilla:rhino:1.7.14"
classpath ( group: 'org.apache.commons', name: 'commons-text'){
version{
strictly '1.10.0'
}
}
}

GORM not bootstrapping from JAR

Replacing a persistence layer in legacy app with a JAR file using Spring, Hibernate and GORM. Methods like person.save() work fine when running agains project with Gradle etc. in project. However, after I build the fat jar and reference it with -cp my-big-fat-gorm.jar I get:
java.lang.IllegalStateException: Method on class [blah.Person] was
used outside of a Grails application. If running in the context of a
test using the mocking API or bootstrap Grails correctly.
Using Spring boot for Spring, Hibernate4 and GORM and build.gradle file show below...
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'application'
mainClassName = "blah.App"
jar {
baseName = 'blah-gorm'
version = '1.0-SNAPSHOT'
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.8.2'
compile 'org.grails:gorm-hibernate4-spring-boot:1.1.0.RELEASE'
compile 'org.slf4j:slf4j-simple:1.7.7'
runtime 'com.h2database:h2:1.4.181'
}
Am I missing something in the JAR file creation that causes Spring boot to honor #Entity etc.?
Here is a GitHub project that illustrates this and should allow you to execute and see the same stuff I'm seeing.
https://github.com/twcrone/spring-gorm-jar
You don't have the Spring Boot Gradle plugin installed so you're not actually creating a fat JAR you need to add the following to your build.gradle file:
apply plugin: 'spring-boot'
buildscript {
ext {
springBootVersion = '1.1.0.M2'
groovyVersion = '2.3.2'
}
repositories {
mavenCentral()
maven {
url 'http://repo.spring.io/milestone'
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
With this in place doing gradle assemble and then java -jar ... results in bootstrapping GORM correctly

Resources