Spring Boot's baner and log4j apears in console - spring-boot

I have Spring Boot application which internally uses libraries with log4j logging.
I added inside pom.xml (to attach log4j entries to my logback logs):
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
According http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html#howto-configure-logback-for-logging-fileonly I added custom logback-spring.xml which should disable console log output:
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
The problem is after:
java -jar my-app.jar &
baner.txt and following warning are still written to console:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.2.RELEASE)
log4j:WARN No appenders could be found for logger (package.hidden).
log4j:WARN Please initialize the log4j system properly.
Q1: How to disable console logs entirely?
Q2: How to attach log4j log to logback file output?

According to the comment, just 1 question left. If you need to disable banner, there are a number of ways. You can do it via application.properties file like:
spring.main.banner-mode=off
Or via application.yml as:
spring:
main:
banner-mode: "off"
Or even in your sources:
public static void main(String... args) {
SpringApplication application = new SpringApplication(SomeSpringConfiguration.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}

Solution to log4j WARN was to exclude transitive dependencies from my internal libraries.
Banner is written to console by default, so we have to set:
spring.main.banner-mode=log
https://github.com/spring-projects/spring-boot/issues/4001

Related

Spring native generation with multi module spring boot application

having a spring boot multi module application. Wanted to convert in spring native exe on windows. Also need to support third party lib as well. I am having 5 modules in my spring boot application:
Security (user management generates JWT and validate before each request).
Spring boot main application.
Configuration - use to do my application configuration)
UI (angular code )
Reporting (generates reports from DB)
I am able to create exe via maven AOT plugin. (did lot of configuration for initialize at run time and build time) exe is generated with following files:
target\application.exe (executable)
target\awt.dll (jdk_lib)
target\jaas.dll (jdk_lib)
target\javaaccessbridge.dll (jdk_lib)
target\jawt.dll (jdk_lib)
target\management.dll (jdk_lib)
target\sunmscapi.dll (jdk_lib)
target\w2k_lsa_auth.dll (jdk_lib)
target\java.dll (jdk_lib_shim)
target\jvm.dll (jdk_lib_shim)
target\cpos-admin-portal-application.build_artifacts.txt
target\cpos-admin-portal-application.exe
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.6)
but no hit goes to any controller. Not other logs of starting application is printed
When I start exe, application use to start following prints on console
Not getting why this much type of files has been generated.

Spring Cloud Config client - how to debug?

After upgrading Spring Cloud libraries to newest version Spring Cloud Config client behaves differently in terms of logging.
In previous version, whenever Spring Cloud Config server was unavailable, I could see log:
Connect Timeout Exception on Url - http://localhost:8888/. Will be trying the next url if available
Currently there's no logs, application simply hangs. After Config Server is available, app also starts an emits all logs at once. It looks like it's caching somehow all logs istead of outputting it immediately.
[INFO] --- spring-boot-maven-plugin:2.5.4:run (default-cli) # gateway-service ---
[INFO] Attaching agents: []
2021-10-07 18:37:02,746 main ERROR Unrecognized format specifier [entityId]
2021-10-07 18:37:02,747 main ERROR Unrecognized conversion specifier [entityId] starting at position 146 in conversion pattern.
2021-10-07 18:38:36,172 main ERROR Unrecognized format specifier [entityId]
2021-10-07 18:38:36,172 main ERROR Unrecognized conversion specifier [entityId] starting at position 147 in conversion pattern.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.4)
2021-10-07 18:38:36.340 INFO 80607 --- [ main] c.y.g.GatewayApplication [%entityId] : Starting GatewayApplication using Java 11.0.12 on ...
In the example above, I was waiting for 30s, before starting Config Server (see timestamps). What is wrong?

SpringBootTest not falling back to "default" profile with Spring Boot 2.4.3

I have a problem with a #SpringBootTest integration test that is driving me nuts, I hope there are some Spring gurus around that can shed some light on this issue:
Our integration tests need to have a fully initialized ApplicationContext so we dont run them with any special test profiles. This worked well in all environments. I've just now updated to Spring Boot 2.4.3 (from 2.3.4) and experience a really weird problem:
When I run the test locally (either from the IDE or using mvn test) it just runs as expected: As I have no profile to run specified whatsoever he's picking up the default default profile as it is also shown on the INFO log output when starting:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.3)
2021-02-25 14:24:29.920 INFO [service-api] [ main] d.r.i.i.s.a.ServiceApiApplicationTest : No active profile set, falling back to default profiles: default
2021-02-25 14:24:31.599 INFO [service-api] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
...
If the same thing is run in our CI pipeline using mvn test (well actually it is Gitlab AutoDevOps which utilizes the herokuish java buildpack but i'm pretty sure it boils down to mvn test) he does not use the default default profile which is causing problems afterwards:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.3)
2021-03-10 15:31:03.925 INFO [service-api] [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8888
2021-03-10 15:31:04.034 INFO [service-api] [ main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://localhost:8888. Will be trying the next url if available
...
(You see the problem: we're using Spring Cloud config for every environment except default but this is just a follow-up problem, the root cause is that when running in Gitlab CI it just does not use the default profile.)
So the question is: What part of the environment makes the magic Spring Boot Context initialization process not going through the standard org.springframework.boot.SpringApplication#logStartupProfileInfo code its supposed to go every time (like it is documented in the official documentation:
The annotation works by creating the ApplicationContext used in your tests through SpringApplication.
?
This problem just occurs after updating to Spring Boot 2.4.3, with v2.3.4 it worked in Gitlab CI just as fine as locally.
(Oh and i know i can würg-around this issue by specifying the profile on the test using #ActiveProfiles("default") but dont you agree that this is horrible?)

SpringBootTest context not loading?

I have an extremely basic SpringBootTest that I am trying to run (the contextLoads()) test.
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
#SpringBootTest
#ActiveProfiles("test")
public class ApplicationTest {
#Test
void contextLoads() {
}
}
I have a config file application-test.yml under src/test/resources/ with some basic configuration that I'd like to use to test my application with. However even with the simple test above the context isn't loading. I'm using IntelliJ to run my tests - and when I run the unit test with Maven the test just is in a running state but it seems like it's frozen loading the context. The only thing I see is
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
and that it says "Running tests..." and it doesn't resolve. I'm not exactly sure what's wrong here. I've noticed when I remove the #ActiveProfiles annotation that the test fails to run and throws back an exception Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class where it looks like it's trying to get load my actual configuration file and it' cant because I haven't set environment variables that I use in the config file. So How can I get SpringBootTest to pick up on the application-test.yml and proceed with the test?

What is the Grails Console of Spring Boot?

I recently started spending more time on Spring Boot and have the started to feel the absence of a shell (similar to Grails console) like application that I can play with the repositories, services etc... Does something like this exist in spring boot?
I recently launched the Spring Context from Groovy project, that gives you access to all beans object within the Remote Shell plugin using the repl groovy interactive console.
Looks like this:
$ ssh -p 2000 user#localhost
user#localhost's password:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.6.RELEASE) on myhost
> repl groovy
Using repl groovy
> ctx.App.myUserService.findUserByEmail("mrsarm#gmail.com")[0].id
100123
> ctx.App.myUserService.getById(100123).name
Mariano Ruiz
> ctx.App.contactDao.logger.effectiveLevel
INFO
> ctx.App.contactDao.logger.setLevel(ch.qos.logback.classic.Level.DEBUG)
As I mentioned in my previous post and later in a comment, you can use the Spring Context from Groovy tool for a Spring Boot 1.x project, but because changes in the Spring Boot framework, it does not work for Spring Boot 2+ projects, in that case you can use the jshell-plugin along with spring-ctx (two projects that I also created).
Quick setup following the steps here and here:
Add the following to your build.gradle:
plugins {
id "com.github.mrsarm.jshell.plugin" version "1.1.0"
}
Add the following dependency to the dependencies section:
implementation 'com.github.mrsarm:spring-ctx:1.0.0'
Add at the end of the repositories section:
maven { url 'https://jitpack.io' }
Any Spring Boot application has a class annotated with #SpringBootApplication that is the starting point of the application, with a public static void main(String[] args) method, you need to create a startup.jsh file at the root of your project calling that method, eg:
com.my.package.MyApplication.main(new String[]{})
You can also add the imports of the business classes you are going to play with, as many as you have, otherwise you can import them once the JShell started:
import com.my.package.services.MyUserService
The configuration is done. You can start the jshell session executing within a console:
$ gradle --console plain jshell
Once the session started you can play with your Spring application, accessing the bean objects from the Spring context as follow:
$ gradle --console plain jshell
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.4.RELEASE)
14:43:28.320 INFO com.my.package.MyApplication : Starting Application on kubu1910 with PID 5225 (/projects/...
14:43:28.323 DEBUG com.my.package.MyApplication : Running with Spring Boot v2.2.4.RELEASE, Spring v5.2.3.RELEASE
14:43:28.324 INFO com.my.package.MyApplication : The following profiles are active: ...
14:43:30.229 INFO boot.web.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8010 (http)
...
...
14:43:33.729 INFO tuate.endpoint.web.EndpointLinksResolver : Exposing 3 endpoint(s) beneath base path ''
14:43:33.811 INFO boot.web.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8010 (http) with context path ''
14:43:33.816 INFO com.my.package.MyApplication : Started Application in 6.995 seconds (JVM running for 10.524)
> Task :jshell
| Welcome to JShell -- Version 11.0.6
| For an introduction type: /help intro
jshell> var myUserService = ctx.App.getBean(MyUserService.class)
jshell> ctx.App.ppjson(myUserService.getByUsername("admin"))
{
"name" : "Jhon",
"lastName" : "Due",
"username" : "admin",
"age" : null
}
Final advice: in Windows / Mac you can call the command with the rlwrap to make the autocompletion to work, there is a well know issue with Gradle that cause tabs and arrow keys to not work well, so you can call the JShell as follow:
$ rlwrap gradle --console plain jshell
Also worth to note that you can use the Gradle Wrapper (./gradlew) from your project if available instead of an installed version of Gradle (gradle).

Resources