Provide Spring Boot git and build information via /actuator/info endpoint when using maven as a build tool - spring-boot

I am using this Spring Boot guide Building a RESTful Web Service with Spring Boot Actuator. When accessing endpoint /actuator/info I am getting empty json response {}.
The actuator api documentation mentions response structures which contain build information like artifact, group, name, version and git information like branch, commit etc.
How can I enable the documented response structures. I want to use maven as build tool (not gradle). This is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>actuator-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>actuator-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

After further research I found the answer in the documentation:
Git Information
Add this to plugins section of pom.xml. maven will generate this file during build ./target/classes/git.properties. Spring will read contents of this file and include it in the response of /actuator/info
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>
See Git Commit Information and Generate Git Information
Build Information
Add an execution goal to spring-boot-maven plugin. This will generate the file ./target/classes/META-INF/build-info.properties. Spring will read contents of this file and include it in the response of /actuator/info
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
Source: Build Information and Generate Build Information

Below is the working solution on Gradle.
Gralde Version 7.3.2
SpringBoot Version: 2.6.1
To include actuators for the project. below dependency should be added to the build.gradle file.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
By default only health is available over web. So to enable the info actuator add below entry in your application.yml
management:
endpoints:
web:
exposure:
include: "health,info"
Now when we run the application and attempt to access the /actuator/info end point it prints empty json in response. This is the default behavior of info actuator end point.
To generate the buildInfo from build.gradle, add below in your gradle file
springBoot {
buildInfo()
}
Now if you run the application and hit /actuator/info endpoint, output will be your project's build info
{"build":{"artifact":"actuator-service","name":"","time":"2022-01-12T18:16:28.468Z","version":"0.0.1-SNAPSHOT","group":"com.example"}}
Additional we can configure to generate the git commit information. To do this, you have to apply below plugin
id "com.gorylenko.gradle-git-properties" version "1.5.1"
Once done, on the project build, it will generate a file called git.properties in your build/resources folder.
And now the /actuator/info endpoint will also generated the git information from the git.properties. By default it won't generate all configs from git.properties.
If you want to see full git configuration in /info endpoint, do the below config in application.yml
info:
git:
enabled: true
mode: full
References:
https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/html/howto-build.html#howto-build-info
https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/html/howto-build.html#howto-git-info

I had the same problem, /actuator/info always returns {}
First, add plugins (lombok is not necessary):
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
</plugin>
Second, go Maven -> compile. Now, in target/classes should be generated git.properties and META-INF folder with build-info.properties.
Finally, run your app and that's it!

You can do that for example by adding the following to your application.properties
info.app.name=#project.name#
info.app.version=#project.version#
info.app.encoding=#project.build.sourceEncoding#
info.app.java.version=#java.version#
Source: https://dzone.com/articles/magic-with-spring-boot-actuator

Related

Sprint-boot-project - I have a requirement to get the version of the spring boot application and port on which it is running

Today i got a requirement, where i have to create a common module to expose the version of the application without changing anything in parent application
Common module
groupId : com.mhn.version, artifactId: version-endpoint packaging: jar
VersionController.java - where i will expose a REST Service "/version" as GET method which returns the details
In any spring boot application if i add this jar (module) as a dependency, then without changing anything in parent application it should fetch the application artifactId and version. Here in this case
1.0.1-SNAPSHOT
For example if i add this as dependency in spring-boot-sample-1.0.1-SNAPSHOT.war application as mentioned in pom.xml below
<groupdId>com.parent.app</groupId>
<artifactId>spring-boot-sample</artifactId>
<version>1.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.mhn.version</groupId>
<artifactId>version-endpoint</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Then spring-boot-sample-1.0.1-SNAPSHOT has to expose a service "/version". and by hitting that endpoint it should return maven project.artifactId and project.version details
In this example
{
"artifactId" : "spring-boot-sample"
"version" : "1.0.1-SNAPSHOT"
}
Guide me, if we have any third party jars, if not guide me on how to do this.
Make this as a note, we are not going to do any changes in parent application
Spring Boot actuators will do this for you with some project configuration as shown in the documentation. Modifying the build configuration to look something like this:
<groupdId>com.parent.app</groupId>
<artifactId>spring-boot-sample</artifactId>
<version>1.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.5.RELEASE</version>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
...
</plugin>
</plugins>
</build>
Will enable a response from the /actuator/info endpoint that might look like this:
{
"build": {
"artifact": "spring-boot-sample",
"group": "com.parent.app",
"name": "spring-boot-sample",
"time": "2020-03-06T16:29:01.200Z",
"version": "1.0.1-SNAPSHOT"
}
}
If, for some reason, you can't use Boot actuators, you could read the content written by spring-boot-maven-plugin's build-info goal in your own library code by accessing the file as a resource with classpath:META-INF/build-info.properties.

Spring boot with maven multi module project

I have a maven multi module project designed like the first answer in following SO post:
Multi-module maven with Spring Boot
Now I want a common maven module that can contain some models to be used by multiple microservices. If I make this common project as a child of the first level parent pom (so that all dependencies injected by boot like jpa, jackson etc are available to common), then STS/Spring is detecting it as a boot application and complains about no Main class on maven build.
Can someone suggest how I can achieve this?
Current Code:
parent pom.xml: (Only relevant parts included)
<project>
<name>...</name>
<groupId>...</groupId>
<artifactId>...</artifactId>
<packaging>pom</packaging>
<version>...</version>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M3</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
child (common module) pom.xml (only relevant parts), not to be boot app:
<project>
<artifactId>...</artifactId>
<version>...</version>
<name>...</name>
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
</parent>
</project>
I don't have all the details regarding your project but my best guess is that the spring-boot-maven-plugin is defined on the parent (or you are using the spring-boot-starter-parent in your root pom). This effectively ask the build to package your module as a Spring Boot app (which is not what you want).
STS probably looks for that hint to figure out if a module contains a Spring Boot application or not. Maybe it would be nicer if it looks for a main class annotated with #EnableAutoConfiguration (or SpringBootApplication).
You can fix the problem easily (from the build side) by specifying the skip property of the repackage goal
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
If STS still picks up the module as a Spring Boot app, I'd create an issue in their tracker
Normally, Spring Boot won't start a web container if it's not present in the module.
I would suggest you to analyse your dendencies using the command
mvn dependency:tree
One more brute-force way of ensuring is use this configuration in your application.properties
spring.main.web-environment=false
Here are two ways to fix this:
You can add the skip property like #Stephane Nicoll mentioned. However, this will completely ignore the test cases inside that module. https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/it-skip.html
Another option is to add a classifier property to make a separate executable jar out of this module. https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/repackage-classifier.html
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
This fix will make sure the dependent module get its required jar and the source module will still be an executable one.

Spring-boot application can only be launched with spring-boot:run when forking - java -jar fails

I have a Spring Boot web application that I cannot start when using the executable jar directly.
I am using Spring Boot 1.2.0.RELEASE, Maven 3.0.5, Java 1.7.0_72.
I have a requirement to use the hp-roman8 character set - in order to handle incoming requests from some remote legacy systems. To provide the hp-roman8 charset I use net.freeutils.jcharset in version 1.5.
The jcharset artifact is installed in my local repository
However when launching my application using java -jar the application fails to start and I get "java.nio.charset.UnsupportedCharsetException: hp-roman8" as cause.
The same error occurs if I do mvn spring-boot:run unless I configure spring-boot-maven-plugin to always fork.
With <fork>true</fork> spring-boot:run starts the application successfully and the hp-roman8 charset is available on the classpath.
However <fork>true</fork> has no effect on the created jar, so I am still unable to launch my application using java -jar - and continue to get the "java.nio.charset.UnsupportedCharsetException: hp-roman8".
The jcharset-1.5.jar is included correctly in the created executable jar file next to the rest of the dependencies in the path "lib/jcharset-1.5.jar" so I don't quite understand why it is not available on the classpath when launching the jar.
Have any of you seen similar behavior, or have any ideas as to what I could try out in order to troubleshoot or even resolve this problem?
update:
I have also tried changing the main-class to use the PropertiesLauncher instead (using the <layout>ZIP</layout> tag in the plugin configuration) - see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging.
Afterwards I added loader.path to my application.properties. Even if I specify the absolute path to jcharset-1.5.jar I still get the UnsupportedCharsetException.
I also tried using an exploded archive but still no go.
You could use Maven's shade plugin rather than Spring Boot's Maven plugin. The main difference is that the shade plugin takes all of your project's dependencies and packages them directly in the jar file, i.e. it doesn't use nested jars. While this has some disadvantages, it does mean that a single class loader is used to load all of your application's classes and, therefore, JCharset is available to the application class loader.
When you're using the Shade plugin, you shouldn't use Spring Boot's starter parent. You may want to import Boot's dependency management instead.
Your pom would look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-sample-jcharset</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-sample-jcharset</name>
<description>Spring Boot sample showing the use of JCharset in an executable jar</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Any additional dependencies, including JCharset -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>sample.jcharset.SampleJCharsetApplication</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

how to externalise the checkstyle config for maven-checkstyle-plugin

I'm trying to make the maven-checkstyle-plugin use the same config file for all our projects.
I've tried a couple of ways, but non of them was effective.
The only thing that seems to work is when i place the config file at the root of my maven-project and then use the name as configLocation configuration parameter in the pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.10</version>
<configuration>
<configLocation>my-checkstyle-checker.xml</configLocation>
</configuration>
</plugin>
I've tried specifying an absolute disk-path, but that doesn't seem to work.
(Considering the endgoal is to have jenkins do the checkstyle this seemed a valid option if the file would be on the jenkins server at the specified location)
I've also tried making a seperate jar-file only containing the xml-file and then using this as a dependency. (This would also centralise the config in 1 location and prevent project specific deviations.) Unfortunately this also doesn't work.
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:2.10:checkstyle (default-cli) on project jenkins-sandbox-project: An error has occurred in Checkstyle report generation. Failed during checkstyle execution: Unable to find configuration file at location my-checkstyle-checker.xml: Could not find resource 'my-checkstyle-checker.xml'. -> [Help 1]
Is there anyone that can tell me what i'm doing wrong here?
It seems it only knows about the files in the same location as where the maven command was started.
maven-checkstyle-plugin version : 2.10
maven command : mvn checkstyle:checkstyle
Create a separate Maven project, that contains just the Checkstyle configuration. In my case I called this project checkstyle-config and it contains the following:
checkstyle-config/src/main/resources/checkstyle.config.xml
checkstyle-config/src/main/resources/checkstyle.suppressions.xml
checkstyle-config/pom.xml
The POM file for this project is trivial:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.totaalsoftware.incidentmanager</groupId>
<artifactId>checkstyle-config</artifactId>
<version>2.0.0-SNAPSHOT</version>
</project>
Build it, so that it gets installed. Then use it as a dependency for your Checkstyle execution, e.g.:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.totaalsoftware.incidentmanager</groupId>
<artifactId>checkstyle-config</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<configuration>
<configLocation>checkstyle.config.xml</configLocation>
<suppressionsLocation>checkstyle.suppressions.xml</suppressionsLocation>
... other configuration ...
</configuration>
</plugin>
I had a similar problem. I solved it with the following configuration.
${project.basedir}/src/main/resources/checkstyle.xml
Note: my checkstyle file is located in "src/main/resources"
I also had some issues defining the location in my plugin configuration, but was able to get this working by overriding a Maven property that the plugin uses, checkstyle.config.location. See example below which works with a multi-module maven project and requires very little overhead.
<checkstyle.config.location>${project.parent.basedir}/my_checks.xml</checkstyle.config.location>
On my case the order of dependencies is the key , this is my pom
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-wkt</artifactId>
<version>${geotools.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geometry</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-swing</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>${geotools.version}</version>
</dependency>

How to download spring framework zip file [duplicate]

This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
SpringSource.org changed their site to http://spring.io
Does someone know how to get the latest build without Maven/github? from http://spring.io/projects
Please edit to keep this list of mirrors current
I found this maven repo where you could download from directly a zip file containing all the jars you need.
https://maven.springframework.org/release/org/springframework/spring/
https://repo.spring.io/release/org/springframework/spring/
Alternate solution: Maven
The solution I prefer is using Maven, it is easy and you don't have to download each jar alone. You can do it with the following steps:
Create an empty folder anywhere with any name you prefer, for example spring-source
Create a new file named pom.xml
Copy the xml below into this file
Open the spring-source folder in your console
Run mvn install
After download finished, you'll find spring jars in /spring-source/target/dependencies
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-source-download</groupId>
<artifactId>SpringDependencies</artifactId>
<version>1.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>download-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependencies</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Also, if you need to download any other spring project, just copy the dependency configuration from its corresponding web page.
For example, if you want to download Spring Web Flow jars, go to its web page, and add its dependency configuration to the pom.xml dependencies, then run mvn install again.
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow</artifactId>
<version>2.3.2.RELEASE</version>
</dependency>

Resources