I created an Java Spring library to audit and log execution times during the execution of my application. I deployed it on SonaType and load it as a dependency in a demo project.
The properties of my library could not be resolved, even if I add an auto-config file and a properties file for each feature to the library.
Here is the pom.xml of my library:
<?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>3.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.github.speedkillsx</groupId>
<artifactId>checkcommonlib</artifactId>
<version>0.0.5</version>
<name>Check Common Library</name>
<description>Demo project for Spring Boot</description>
<packaging>jar</packaging>
<url/>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:git:git://github.com/speedKillsx/checkcommonlib.git</connection>
<developerConnection>scm:git:ssh://git@github.com/speedKillsx/checkcommonlib.git</developerConnection>
<url>https://github.com/speedKillsx/checkcommonlib</url>
<tag>HEAD</tag>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.7.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>ossrh</publishingServerId>
<autoPublish>true</autoPublish>
<waitUntil>published</waitUntil>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- GPG Signing Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
My auto-configuration file in the library:
package io.github.speedkillsx.checkcommonlib.config;
import io.github.speedkillsx.checkcommonlib.properties.AuditProperties;
import io.github.speedkillsx.checkcommonlib.properties.LogExecutionTimeProperties;
import io.github.speedkillsx.checkcommonlib.properties.RetryOnFailurePropreties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* CheckCommonAutoConfiguration is a Spring configuration class that
* auto-configures beans related to common functionalities such as
* auditing, logging execution time, and retry mechanisms. These functionalities
* are managed through properties prefixed with "check-common" and loaded from
* the application's configuration file.
*
* It integrates configuration support for the following types of properties:
* - {@link AuditProperties} for enabling or disabling auditing features.
* - {@link LogExecutionTimeProperties} for enabling or disabling method execution time logging.
* - {@link RetryOnFailurePropreties} for configuring retry mechanisms in case of failures.
*
* The class enables AspectJ auto-proxy support and ensures that the
* necessary configuration beans are available for components relying on
* these common features.
*/
@Configuration
@EnableConfigurationProperties({
AuditProperties.class,
LogExecutionTimeProperties.class,
RetryOnFailurePropreties.class
})
@EnableAspectJAutoProxy
public class CheckCommonAutoConfiguration {
}
Properties files:
@Getter
@Setter
@ConfigurationProperties(prefix = "check-common")
public class AuditProperties {
private boolean auditEnable;
}
@Getter
@Setter
@ConfigurationProperties(prefix = "check-common.retry")
public class RetryOnFailurePropreties {
private boolean enabled;
private int defaultMaxAttempts;
private long defaultDelayMs;
}
@Getter
@Setter
@ConfigurationProperties(prefix = "check-common")
public class LogExecutionTimeProperties {
private boolean logExecutionTime;
}
I have empty application.yaml and application-local.yaml in the library.
For my demo application, I added the library as a dependency:
<?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>3.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.testcommonlib</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<repositories>
<repository>
<id>sonatype-releases</id>
<url>https://oss.sonatype.org/content/repositories/releases/</url>
</repository>
<repository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<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>
<dependency>
<groupId>io.github.speedkillsx</groupId>
<artifactId>checkcommonlib</artifactId>
<version>0.0.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
And my application.yaml (in demo application):
server:
port: 8087
spring:
application:
name: demo
check-common:
audit-enable: true
check-common
and its propreties cannot be resolved, I don't understand why.
Fortunately, the source code of your library is available on Maven Central, so I could compare version 0.0.5 (which you had problems with) to 0.0.8 (which works nicely): In the older version of class CheckCommonAutoConfiguration
, you forgot to declare your aspects to be @Bean
s or to alternatively activate component scan correctly.
So, this minimal reproducer works:
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>3.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.testcommonlib</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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>
<dependency>
<groupId>io.github.speedkillsx</groupId>
<artifactId>checkcommonlib</artifactId>
<version>0.0.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
src/main/resources/application.yaml
server:
port: 8087
spring:
application:
name: demo
check-common:
audit-enable: true
log-execution-time: true
src/main/java/com/testcommonlib/app/q79605952/MyController.java
package com.testcommonlib.app.q79605952;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
public void doSomething() {
System.out.println("Doing something...");
}
}
src/main/java/com/testcommonlib/app/q79605952/DemoApplication.java
package com.testcommonlib.app.q79605952;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
try (ConfigurableApplicationContext appContext = SpringApplication.run(DemoApplication.class, args)) {
doStuff(appContext);
}
}
private static void doStuff(ConfigurableApplicationContext appContext) {
appContext.getBean(MyController.class).doSomething();
}
}
Console log (without timestamps, log channels, thread names etc.)
c.t.app.q79605952.DemoApplication : Started DemoApplication in 4.938 seconds (process running for 6.049)
i.g.s.checkcommonlib.aspect.AuditAspect : [AUDIT] Starting the Audit...
i.g.s.c.aspect.LogExecutionTimeAspect : [LogExecutionTime] Starting execution time recording for method doSomething...
i.g.s.c.aspect.LogExecutionTimeAspect : [LogExecutionTime] Starting execution time record : 1.74641853044E9 SECONDS
Doing something...
i.g.s.c.aspect.LogExecutionTimeAspect : [LogExecutionTime] Result generated : null
i.g.s.c.aspect.LogExecutionTimeAspect : [LogExecutionTime] Ending execution time record : 1.746418530442E9 SECONDS
i.g.s.c.aspect.LogExecutionTimeAspect : [LogExecutionTime] Time elapsed during execution equals : 0.002 SECONDS
i.g.s.checkcommonlib.aspect.AuditAspect : [AUDIT] Method signature: void com.testcommonlib.app.q79605952.MyController.doSomething()
i.g.s.checkcommonlib.aspect.AuditAspect : [AUDIT] Method name: doSomething ; Returned result null
o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete
The problem was not that your configuration was not picked up but that your aspects were completely inactive.