Difference between gradle bootrun and bootjar/build in a springboot application - spring

I'm working in a quite complex app that for some reason, gradle bootRun works as expected but when gradle bootjar or gradle build is used to then execute the packaged jar with java -jar pathtojar, it fails to load some jruby scripts present in a dependency.
What are the differences between those two in terms of packaging and how can bootRun be more reliable?

Related

Difference between gradle build and gradle bootJar?

What is the difference between "gradle build" and "gradle bootJar"? Why would I use bootJar if I can still create the artifact using build?
build is a lifecycle task contributed by the Base Plugin. It is
Intended to build everything, including running all tests, producing the production artifacts and generating documentation. You will probably rarely attach concrete tasks directly to build as assemble and check are typically more appropriate.
bootJar on the other hand is a specific task added by Spring Boot Gradle plugin that, when the java plugin is present, attaches itself to the assemble lifecycle task.
The assemble task is automatically configured to depend upon the bootJar task so running assemble (or build) will also run the bootJar task.
(Packaging Executable Jars)
You want to use bootJar if you're only interested in building the executable jar and not interested in executing tests, code coverage, static code analysis or whatever is attached to the check lifecycle task.

Micronaut - Kotlin code compilation with Maven

I have started to work on a Micronaut REST microservice, with Kotlin and Maven, and I have a hard time at trying to get the better build process possible with this stack in Intellij.
I was expecting Kotlin to be easily compatible with Micronaut, but at each code modification we have to do a compilation of the project (mvn compile) due to use of KAPT plugin to process the Micronaut annotations with Kotlin, which seems to be time consuming.
This post helped me to get a good solution to compile Kotlin with Micronaut and Gradle by making it automatized in Intellij:
IntelliJ - Gradle - Kotlin - Micronaut - Changing files does not re-generate classes on "run"
(the equivalent can be done for Maven with the same corresponding option)
Thanks to the Micronaut CLI, I have generated three hello-world projects to compare the build durations. Here are the commands to create them:
mn create-app micronaut-maven-kotlin --build maven --lang kotlin
mn create-app micronaut-maven-java --build maven --lang java
mn create-app micronaut-gradle-kotlin --build gradle --lang kotlin
I measured approximatively the duration of build process before Intellij run the project code, here are the results:
Java + Maven = no waiting
Kotlin + Gradle = 2.5 seconds
Kotlin + Maven = 8 seconds
The apps takes 1 second to start. With Java, Micronaut is blazing fast to work with, but this argument no longer exists when I'm introducing Kotlin in the pipe, and I'm afraid of doing it with a bigger project...
Did anybody succeed to have a convenient process with Micronaut, Kotlin and Maven?

gradle and dependency on spring-boot subproject

I've created a project with several gradle subprojects, including: "app" and "tests".
Tests have "app" in their dependencies. Tests use classes from "app"
When I run:
./gradlew clean test build
Everything works, tests run and pass.
But when I run:
./gradlew clean build
then the tests compilation fails with an error saying that a class is missing - in this case it's a spring-boot configuration class. I run this with --debug and it turns out that in the failing case app:bootRepackage task is executed before tests:test, the jar generated by app compilation is altered and that's why the classes cannot be found.
How can I make "./gradlew clean build" work properly?
Using: spring-boot 1.5, gradle 4.0 (and 4.1 too), io.spring.dependency-management plugin 1.0.0.RELEASE
Ideally, you shouldn't use a Spring Boot application (something that's been repackaged) as a dependency. From the documentation:
Like a war file, a Spring Boot application is not intended to be used as a dependency. If your application contains classes that you want to share with other projects, the recommended approach is to move that code into a separate module. The separate module can then be depended upon by your application and other projects.
If the proposed solution isn't possible in your situation, the documentation goes on to describe an alternative:
If you cannot rearrange your code as recommended above, Spring Boot’s Maven and Gradle plugins must be configured to produce a separate artifact that is suitable for use as a dependency. The executable archive cannot be used as a dependency as the executable jar format packages application classes in BOOT-INF/classes. This means that they cannot be found when the executable jar is used as a dependency.
To produce the two artifacts, one that can be used as a dependency and one that is executable, a classifier must be specified. This classifier is applied to the name of the executable archive, leaving the default archive for use as dependency.
To configure a classifier of exec … when using Gradle, the following configuration can be used:
bootRepackage {
classifier = 'exec'
}

Different classpath between IntelliJ and mvn

I am trying to run a Junit test from Intellij, which is failing. The same test is succeeding if I use my terminal and mvn.
I noticed that the classpath used when Intellij runs the test is different from the classpath that mvn test uses. I believe this is causing some conflicts during the execution in Intellij and causing it to fail.
Versions:
Maven: 3.1.0 Same maven is used by Intellij and Terminal
Java: 1.6.0_65 both by Intellij Module and maven
Anyone has any pointers on how to resolve this?

Gradle Spring boot application not executeable after install/uploadArchives

I want to upload an executable jar/war to a nexus repoistory
When running a gradle build I get a 66 MB jar file containing all required libraries.
However, after running install or uploadArchives, the created jar file now only contains my code and is no long executable.
When creating a war file the only thing missing is Spring's loader package.
The above happens when running gradle tasks separately,
e.g. gradle build
or gradle install
However, if the gradle tasks are run together,
e.g. gradle build install
or gradle build uploadArchives
the executable part is not removed.

Resources