Springboot - validate "native" properties at startup - spring

Context: after a recent springboot/spring migration, I've been scratching my head on why my HAL URLs were now returned as HTTP and not HTTPS anymore.
After investigation, this was related to some deprecated (and removed) property replaced by another one (ok, Intellij was doing a proper job and highlighted this)
server.use-forward-headers=true
#replaced by
server.forward-headers-strategy=native
Whereas I know you can validate your own properties set via your #ConfigurationProperties, its parameters or even your own JSR annotations, is there a way to validate "native" properties (server., spring., ...) at application startup and/or build?
UC1: I want to be sure I'm not using any unknown property (e.g. the property has been totally removed or is misspelt)
UC2: I want to be sure I'm not using any deprecated property
Approaches tried:
Searching for an existing property that would do the job
Overriding ServerProperties (sounds like a bad idea)
Using an existing FailureAnalyzer or defining a custom one
Thanks for your help!

You can rely on your IDE but it can only show you the configuration files that you are managing. Those properties are potentially set as environment variables in an specific environment or using a remote config server you don't have access to.
That's one of the reasons we're providing spring-boot-properties-migrator. It is referenced in the release notes.
Here is a sample demo app that yield the following:
2020-07-18 19:19:54.168 INFO 69898 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication on taurus.lan with PID 69898 (/Users/snicoll/Downloads/demo-properties-migrator/target/classes started by snicoll in /Users/snicoll/Downloads/demo-properties-migrator)
2020-07-18 19:19:54.170 INFO 69898 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2020-07-18 19:19:54.545 INFO 69898 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.571 seconds (JVM running for 0.924)
2020-07-18 19:19:54.551 ERROR 69898 --- [ main] o.s.b.c.p.m.PropertiesMigrationListener :
The use of configuration keys that are no longer supported was found in the environment:
Property source 'systemProperties':
Key: server.connection-timeout
Reason: Each server behaves differently.
Property source 'applicationConfig: [classpath:/application.properties]':
Key: server.use-forward-headers
Line: 1
Reason: Replaced to support additional strategies.
Please refer to the release notes or reference guide for potential alternatives.
This will work for known properties (your use case) but it won't work for properties that are set and we don't know about (i.e. that don't have metadata). An obvious candidate in that set is typos of course but that's no longer an upgrade problem. Relying on your IDE to make sure that the property you introduce is legit sounds reasonable to me.
We'd like also to offer some validation for users that are adding properties without assistance, see this issue for more details.

Related

how thymeleaf can find the template location?

i'm getting a warn when i start my spring boot app, is the following:
2023-02-16T13:26:47.508-05:00 WARN 23919
--- [ restartedMain] DefaultTemplateResolverConfiguration
Cannot find template location: classpath:/templates/ (please add some templates, check your Thymeleaf configuration, or set spring.thymeleaf.check-template-location=false)
but my application.properties is the following:
spring.thymeleaf.prefix=classpath:/templates/
everything seems to be normal, but I keep getting that error
my resources directory is the following:
enter image description here
does anyone know what's going on? the answers I've looked for don't fit my weird situation.
First of all src/main/resources/templates is the default directory for Thymeleaf templates, so I guess you need to remove property spring.thymeleaf.prefix=classpath:/templates/ letting Spring to use the default one.

Cannot find template location :( please add some templates, check your Thymeleaf configuration, or set spring.thymeleaf.check-template-location=false)

I created a spring boot application and while running it I am getting this warning.
2022-10-27 00:35:12.520 WARN 11512 --- [ restartedMain] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates, check your Thymeleaf configuration, or set spring.thymeleaf.check-template-location=false)
Here, you can see my application.properties file
spring.datasource.url=jdbc:mysql://localhost:3306/springbootblogapp?
createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.show-sql=true
spring.jpa.open-in-view=false
Even though there were some related questions here, the provided answers for them are not working for me, because the warnings mentioned there were a little bit deviated from the warning which I got.
Please help me.
My initial comment, transferred to an answer:
Here is the text of the warning message shown in your question:
2022-10-27 00:35:12.520 WARN 11512 --- [ restartedMain] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates, check your Thymeleaf configuration, or set spring.thymeleaf.check-template-location=false)
Did you try what the warning message suggests - for example, by adding:
spring.thymeleaf.check-template-location=false
to your application's config? Or by creating the directory templates mentioned in the warning message (and adding a template there)? By default this directory is expected to be created in the resources location, so that it is on the classpath of the application at runtime.
Update based on your follow-up comment:
Why do you get this warning?
When you create a Spring Boot application, you can choose various additional dependencies (for example by using Spring Initializr).
One such additional dependency is Thymeleaf.
For Maven (assuming you are using Maven), that is the following artifact in your POM:
<artifactId>spring-boot-starter-thymeleaf</artifactId>
There is no point in choosing this option if you don't set up the basic location where you are going to store your Thymeleaf templates.
If you choose to configure the option:
spring.thymeleaf.check-template-location=false
then you are telling Spring not to bother checking if there is a valid configured location for your Thymeleaf templates.
So, even if there is not a valid configured location, you won't see that warning.
If you decide you do want to use Thymeleaf after all, you will need to fix this, by providing that default folder templates on the runtime classpath - or by specifying a custom location via your properties file.
You may see similar warnings (or even errors) with other Spring Boot dependencies you have chosen. For example, if you choose to include the JDBC API, but do not configure a valid data source, then I believe that causes an error (if I recall).

spring boot logs strange square brackets

I've been seeing weird square brackets and can't find and info on what there might be,
logs looking like that:
--2022-08-23 08:47:44.882 INFO [,,,] 30446 --- [)-192.168.0.165] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
--2022-08-23 08:47:44.882 INFO [,,,] 30446 --- [)-192.168.0.165] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
--2022-08-23 08:47:44.922 INFO [,,,] 30446 --- [)-192.168.0.165] o.s.web.servlet.DispatcherServlet : Completed initialization in 40 ms
as you can see there are brackets with commas after log level, at some point info in the brackets change like this:
DEBUG [,080578da-b973-450b-9cae-2c5900ab56fe,080578da-b973-450b-9cae-2c5900ab56fe,]
can't really find what that could be, i'am using default spring boot logging pattern,
could it be wrongfully used MDC without redeclaring the logging pattern?
if it is MDC problem then why any value in the brackets look like this: 080578da-b973-450b-9cae-2c5900ab56fe
The logger I'm using is Slf4j
This could happen if you use Spring Cloud Sleuth. Spring Cloud Sleuth is a framework that adds the following to your logs:
The application name (from the spring.application.name property)
A trace ID (a unique ID for each user-initiated request)
A span ID (a unique ID for a unit of work)
These IDs can be used to correlate log messages in a distributed system (eg. microservices), because these IDs will be passed from microservice to microservice. In the documentation you can find an example of what this looks like.
In your case, you're not using these properties, which is why they're empty. The trace ID is automatically generated upon each request, which is why you sometimes see [,,] and [,XXX,].
If you're not interested in these trace/span IDs, you can remove the spring-cloud-sleuth or spring-cloud-starter-sleuth library.

Embedded Keycloak springboot application, upgrading keycloak from 12 to 14

Hello I have an SpringBoot application with embedded Keyclock created using the below example
https://www.baeldung.com/keycloak-embedded-in-spring-boot-app
I am trying to upgrade Keycloak from 12 to 14 and also upgraded resteasy to 3.15.1.Final, infinispan to 11.0.9.Final. The application fails to start and there is not much in the logs except for a NullPointerException. I am trying to see if any one tried the same and has any suggestions as there are not much in logs. Thanks
2021-07-07 10:02:05 [main] INFO org.keycloak.services - KC-SERVICES0050: Initializing master realm
2021-07-07 10:02:07 [main] DEBUG org.keycloak.keys.GeneratedRsaKeyProviderFactory - Generated keys for master
2021-07-07 10:02:07 [main] DEBUG org.keycloak.keys.GeneratedHmacKeyProviderFactory - Generated secret for master
2021-07-07 10:02:07 [main] DEBUG org.keycloak.keys.GeneratedAesKeyProviderFactory - Generated secret for master
2021-07-07 10:02:07 [main] DEBUG org.keycloak.connections.jpa.updater.liquibase.lock.LiquibaseDBLockProvider - Going to release database lock namespace=KEYCLOAK_BOOT
2021-07-07 10:02:07 [main] DEBUG org.keycloak.connections.jpa.updater.liquibase.lock.CustomLockService - Going to release database lock
2021-07-07 10:02:07 [main] DEBUG org.keycloak.models.cache.infinispan.InfinispanUserCacheProviderFactory - Registered cluster listeners
2021-07-07 10:02:07 [main] DEBUG org.keycloak.executors.DefaultExecutorsProviderFactory - We are in managed environment. Executor 'java:jboss/ee/concurrency/executor/default' was available.
2021-07-07 10:02:07 [main] DEBUG org.keycloak.executors.DefaultExecutorsProviderFactory - Found executor for 'storage-provider-threads' under JNDI name 'java:jboss/ee/concurrency/executor/storage-provider-threads'
2021-07-07 10:02:07 [main] FATAL org.keycloak.services - java.lang.NullPointerException
2021-07-07 10:02:07 [main] DEBUG org.keycloak.executors.DefaultExecutorsProviderFactory - Found executor for 'storage-provider-threads' under JNDI name 'java:jboss/ee/concurrency/executor/storage-provider-threads'
$$$$$$$$$$$$$$$$Stachtrace$$$$$$$$$$$$$ : java.lang.NullPointerException
at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
at org.keycloak.executors.DefaultExecutorsProviderFactory.getExecutor(DefaultExecutorsProviderFactory.java:113)
at org.keycloak.executors.DefaultExecutorsProviderFactory$1.getExecutor(DefaultExecutorsProviderFactory.java:68)
at org.keycloak.utils.ServicesUtils.timeBoundOne(ServicesUtils.java:71)
at org.keycloak.storage.AbstractStorageManager.mapEnabledStorageProvidersWithTimeout(AbstractStorageManager.java:135)
at org.keycloak.storage.UserStorageManager.getUsersCount(UserStorageManager.java:374)
at org.keycloak.models.cache.infinispan.UserCacheSession.getUsersCount(UserCacheSession.java:545)
at org.keycloak.storage.user.UserQueryProvider.getUsersCount(UserQueryProvider.java:52)
at org.keycloak.services.managers.ApplianceBootstrap.createMasterRealmUser(ApplianceBootstrap.java:99)
We had similar vague error messages when upgrading our embedded keycloak to 15 in our Spring Boot/Servlet-style application. But we eventually fixed them by crawling through the code/history of the project that this baeldung.com tutorial was based; thomasdarimont's Embedded Keycloak Server running in a Spring Boot App. This repo is a few upgrades past the initial tutorial; up to Keycloak 13. We compared the history to our code and applying/testing fixes incrementally for each version from keycloak 11 to 13. After that, the updates from 13 to 15 were a bit easier to understand, and the errors were not as cryptic.
Our application is not exactly like the example code given in the Baeldung tutorial, but below is a list of changes we needed to upgrade to Keycloak 15.0.1. These changes may not be 1:1 with your project, but hopefully these help someone save some time.
In KeycloakApplication moved the realm-setup functions from constructor method to bootstrap() method. (An example fix found here)
public class EmbeddedKeycloakApplication extends KeycloakApplication {
...
//public EmbeddedKeycloakApplication() {
// createMasterRealmAdminUser();
// createBaeldungRealm();
//}
#Override
protected ExportImportManager bootstrap() {
final ExportImportManager exportImportManager = super.bootstrap();
createMasterRealmAdminUser();
createBaeldungRealm();
return exportImportManager;
}
In the EmbeddedKeycloakConfig we added a couple new bean references/factories (Both found here)
public class EmbeddedKeycloakConfig {
...
#Bean("fixedThreadPool")
public ExecutorService fixedThreadPool() {
return Executors.newFixedThreadPool(5);
}
#Bean
#ConditionalOnMissingBean(name = "springBootPlatform")
protected SimplePlatformProvider springBootPlatform() {
return (SimplePlatformProvider) Platform.getPlatform();
}
In our keycloak-server.json, we removed the default 'concurrenthashmap' name from the mapStorage provider, but still provided the concurrenthashmap properties. This matches other Keycloak 15 examples. As Paul mentioned, the map_storage needs to be enabled, and the simplest solution is to use the system properties -Dkeycloak.profile.feature.map_storage=enabled -Dkeycloak.mapStorage.provider=concurrenthashmap. Similar examples can be found in the Keycloak test suites here and here . HOWEVER: We ran into errors when using these system properties, and decided it is not needed for our code. Luckilly, the 'mapStorage' is no specifically called out in the tutorial; it is only found in the Referenced Tutorial Code. So we simply matched other Keycloak 13+ examples and removed the reference in the keycloak-server.json (shown below) to get rid of the null pointer exception.
//Change this:
"mapStorage": {
"provider": "${keycloak.mapStorage.provider:concurrenthashmap}",
"concurrenthashmap": {
"dir": "${project.build.directory:target}"
}
},
//To This
"mapStorage": {
"provider": "${keycloak.mapStorage.provider:}",
"concurrenthashmap": {
"dir": "${project.build.directory:target}"
}
},
Upgraded the proper infinispan and rest versions with keycloak version. (Tutorial code reference)
< properties>
< keycloak.version>15.0.1</keycloak.version>
< !-- these should be updated together with Keycloak -->
< !-- check keycloak-dependencies-server-all effective pom -->
< infinispan.version>11.0.9.Final</infinispan.version>
< resteasy.version>3.15.1.Final/resteasy.version>
< /properties>
We also added the temp directory location in the SimplePlatformProvider, since this field was required. NOTE: The system temp folder, used in the example, is not recommended for production.
#Override
public File getTmpDirectory() {
return System.getProperty("java.io.tmpdir");
}
I hope someone finds this info useful, Good luck!
I’ve tried the same thing with keycloak 15 and I got the same result. It seems that keycloak’s ConcurrentHashMapStorageProvider isn’t taken in account.
EDIT: after looking into keycloak's code, I've found that MAP_STORAGE functionality is disabled by default (because the feature is tagged as EXPERIMENTAL). To resolve this issue you must launch your springboot app with the following Java option :
-Dkeycloak.profile.feature.map_storage=enabled
Unfortunately, I'm now facing another nullPointerException...
I have applied the changes suggested by #mrieman to the initial baeldung.com tutorial. It works fine with 17.0.1 version of Keycloak as of now. Hope it will help someone. My repository on Github is here

Spring Boot not listening to external logging.level.* properties

I'm currently dealing with external logging properties for the application I'm building. I have a custom properties file called myapp.properties. It contains some custom properties and some environment-specific Spring properties like SSL and server port(including logging).
The custom properties file works just fine for all properties, except for the logging.level.* properties, which are just plainly ignored.
For example, when I use this property in my custom myapp.properties:
server.port=12345.
It works just fine: s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 12345 (http)
However, when I try the same thing for the logging properties:
logging.level.root=ERROR
It still logs other messages: 2017-05-10 12:32:54.984 INFO 9188 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http).
Anyone knows what could possibly be a solution for this problem?
Spring Boot initialises the logging system very early. So early, in fact, that a properties file that's configured via PropertySourcesPlaceholderConfigurer isn't available in time.
You have a few options including:
Configuring the logging level in the standard application.properties or application.yml files
Configuring spring.config.name so that Boot will look for myapp.properties either in addition to or in place of application.properties
I asked, essentially, that question as issue on github. So here's solution.
https://github.com/spring-projects/spring-boot/issues/9243

Resources