Spring banner is not printed within log - spring-boot

Within my Spring Boot application (loglevel=DEBUG) I do log against slf4j, jcl (commons logging), log4j and jul (java util logging). I do use following:
log4j-to-slf4j.jar
slf4j-log4j12.jar
commons-logging.jar
log4j.jar
jul-to-slf4j.jar
Running it on Tomcat (juli) it doesnt print the Spring Boot bannner.
We are using Tomcat with a Logging Bridge. This Logging Bridge contains a LoggingListener (that implments the org.apache.catalina.LifecycleListener) and does redirect every Log from System.out and System.err.
systemOut = System.out;
systemErr = System.err;
System.setOut(new PrintStream(new LoggingOutputStream(Level.DEBUG, systemOut), true));
System.setErr(new PrintStream(new LoggingOutputStream(Level.WARN, systemErr), true));
The execution of this code snipped is based on a class attribute flag (private boolean redirectSystemLogs) which is always true - I tried to steer this flag from outside (tomcat clathpath) but didnt succeed. And still I would expect that with loglevel DEBUG I should be able to see the spring banner in the logs.

You have to tell it to print to the log file and not the console. In your application.yml:
spring:
main:
banner-mode: log
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/Banner.Mode.html

Related

ActiveMQ Artemis broker and Spring Boot - prevent from starting embedded

I have a project, where I want to use ActiveMQ Artemis with Spring Boot 3.0.1, but I have an issue with embedded server.
Dependencies used:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-server</artifactId>
</dependency>
The drill should be: when needed, start embedded server, but there is no need for that, connect to existing instance.
From I understand, there are two parameters, that might be useful here:
spring.artemis.mode - I should set it whenever want to start embedded service or connect to native instance of the server and:
spring.artemis.embedded.enabled - Quote from documentation, "Whether to enable embedded mode if the Artemis server APIs are available."
All that said, setting first one to native and second one to false does not do the trick. Native server is still starting. Am I missing something? Is there a simple way to tell Spring Boot via property or any other way to not start server if not needed?
EDIT1:
Maybe I'll provide some more details.
All configuration for the Artemis goes into separate module, where dependencies that has been provided above are.
Then, this module (let's call it "message") has only following properties:
spring:
artemis:
broker-url: tcp://localhost:61616
mode: native
Then, other module has than module as a dependency (has changed names of the groupId and artifactId for simplicity):
<dependency>
<groupId>org.example.company</groupId>
<artifactId>message</artifactId>
</dependency>
Then, changing the value in the properties does nothing to starting the server, in both configurations I see in logs:
2023-01-23T11:41:18.445+01:00 INFO 35336 --- [ restartedMain] o.apache.activemq.artemis.core.server : AMQ221000: live Message Broker is starting with configuration Broker Configuration (clustered=false,journalDirectory=C:\Users\USR~1.JAR\AppData\Local\Temp\artemis-data/journal,bindingsDirectory=data/bindings,largeMessagesDirectory=data/largemessages,pagingDirectory=data/paging)
...
2023-01-23T11:41:19.058+01:00 INFO 35336 --- [ restartedMain] o.apache.activemq.artemis.core.server : AMQ221007: Server is now live
2023-01-23T11:41:19.059+01:00 INFO 35336 --- [ restartedMain] o.apache.activemq.artemis.core.server : AMQ221001: Apache ActiveMQ Artemis Message Broker version 2.26.0 [localhost, nodeID=78075d71-9b0a-11ed-8116-3cf011ac7196]
In this second module, where "message" is being imported as a dependency, I'm sending and receiving some messages, if that matters.

Spring Cloud Bootstrap Config prepending "bootstrapProperties-" to all of my BootstrapProperties

My team and I updated a spring boot application in order to work with oauth2, but with the updated we jumped from Spring Boot 1.5.2 to Spring Boot 2.5.8. The oauth2 is now implemented although the new version of the app cannot found any client encryption keys from the config server. Checking the logs of the last version I have:
INFO Nov 17 16:30:51 [main] org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration: LOCAL_HOST:, APP_ID:, OPERATION_NAME:, TRANSACTION_ID:, CALL_PATH:, REMOTE_HOST:, USER: - Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='fulfillments-event-validation-job'], MapPropertySource [name='config-internal']]]
After this log there are several com.esrx.inf.config.client.CustomEnvironmentDecryptApplicationInitializer* logs where it loads the values of config server and decrypts them
But in the new version I have this logs:
INFO Nov 18 02:25:53 [main] org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration: LOCAL_HOST:, APP_ID:, OPERATION_NAME:, TRANSACTION_ID:, CALL_PATH:, REMOTE_HOST:, USER: - Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-fulfillments-event-validation-job'}, BootstrapPropertySource {name='bootstrapProperties-config-internal'}]
After this log there are not even one log for com.esrx.inf.config.client.CustomEnvironmentDecryptApplicationInitializer*
The old app can load and decrypt the config server values, the new version doesn't even load the values of config server.
old version
new version
spring-boot-starter-test 1.5.2
2.5.8
it does not have this one
spring-cloud-starter-bootstrap 3.0.5
spring-cloud-starter-config 1.3.0
3.0.6
configService
bootstrapProperties-configClient
fulfillments-event-validation-job
bootstrapProperties-fulfillments-event-validation-job
config-internal
bootstrapProperties-config-internal
So I'm thinking the error is with the values of the new version, for some reason is prepending en every value the string "bootstrapProperties-". You know any related to this issue?
I changed the configuration of my pom and application.properties several times.
At the end I stayed with spring-cloud-starter-bootstrap in order for the app to run.

Spring Cloud Config Server spams "Adding property source" during health check [Spring Boot 2.6+]?

For a Spring Cloud Config Server project, we recently migrated from Spring Boot 2.1.8.RELEASE to 2.6.6. However, the application seemed to be flooded with below logs that eventually leads to k8s pod crashing/restarting. And the INFO log is generated each time /actuator/health from kube-probe is called.
2022-08-30 19:20:19.182 INFO [config-server,5bd83ee81e7d3ccb,e17a13026d9c85ee] 1 --- [nio-8888-exec-5] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: Config resource 'file [{spring.cloud.config.server.git.basedir}/application.yml]' via location 'file:{spring.cloud.config.server.git.basedir}'
2022-08-30 19:20:19.543 INFO [config-server,7557d9d04d71f6c7,a3d5954fe6ebbab1] 1 --- [nio-8888-exec-8] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: Config resource 'file [{spring.cloud.config.server.git.basedir}/application.yml]' via location 'file:{spring.cloud.config.server.git.basedir}'
...
Note that I have replaced the actual file path to config repo in the container with spring.cloud.config.server.git.basedir.
Is there something that we missed on how Spring Cloud Config Server behaves differently since the update? Or how to disable health check endpoint to add a property source? As EnvironmentController.java seems to be the culprit.

Spring Boot: Log to multiple files. All DEBUGs to debug.log, all INFOs to info.log

I'm using logging provided by Spring Boot in an application.yml like this:
logging:
file: log/info.log
level.com.mycompany.app: INFO
What I actually want is:
1) Log every DEBUG message from our application (com.mycompany.app) to debug.log,
(optional: every INFO message from the whole app / ROOT to debug.log, too)
2) log every INFO message from the whole app / ROOT to info.log
So in pseudo code, it should look like this:
logging:
level: DEBUG
file: debug.log
com.mycompany.app: DEBUG
level:
ROOT: INFO
file: debug.log
level:
ROOT: INFO
file: info.log
How can I achieve this? Please note, we're using SLF4j, not logback (I've read in other threads about logback for writing to multiple files).
Regards,
Bernhard

Why wsdl2java generated code use CXF dependencies at will?

I use Apache CXF 3.0.4 wsdl2java to generate code from this wsdl with following command:
./wsdl2java -client -exsh true -d weather -p weather -verbose url
As far as I know wsdl2java generates pure java code using only JAX-WS. Generated code works fine without any additional library/dependency. I've grepped it to find any CXF classes, but it seems to be free from CXF. The problem flows out when I add specific CXF dependency to my pom.xml. This dependency is:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.0</version>
</dependency>
After adding this, application seems to use different implementation of JAX-WS( is it even possible?).
Generated code contains among other things WeatherSoap interface. One of it's methods is getWeatherInformation()
#WebService(targetNamespace = "http://ws.cdyne.com/WeatherWS/", name = "WeatherSoap")
#XmlSeeAlso({ObjectFactory.class})
public interface WeatherSoap {
/**
* Gets Information for each WeatherID
*/
#WebResult(name = "GetWeatherInformationResult", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
#RequestWrapper(localName = "GetWeatherInformation", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "weather.GetWeatherInformation")
#WebMethod(operationName = "GetWeatherInformation", action = "http://ws.cdyne.com/WeatherWS/GetWeatherInformation")
#ResponseWrapper(localName = "GetWeatherInformationResponse", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "weather.GetWeatherInformationResponse")
public weather.ArrayOfWeatherDescription getWeatherInformation();
...
}
Without cxf-rt-frontend-jaxws dependency
Step into getWeatherInformation() while debugging leads to GetWeatherInformation( another generated class.
Step into GetWeatherInformation leads to com.oracle.webservices.internal.api.message.BasePropertySet
...
Result from SOAP webservice received.
With cxf-rt-frontend-jaxws dependency
Step into getWeatherInformation while debugging leads to org.apache.cxf.jaxws.JaxWsClientProxy (why?)
...
Exception is thrown:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Could not find conduit initiator for address: http://wsf.cdyne.com/WeatherWS/Weather.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
at com.sun.proxy.$Proxy33.getWeatherInformation(Unknown Source)
at weather.WeatherSoap_WeatherSoap_Client.main(WeatherSoap_WeatherSoap_Client.java:49)
Caused by: java.lang.RuntimeException: Could not find conduit initiator for address: http://wsf.cdyne.com/WeatherWS/Weather.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:224)
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:229)
at org.apache.cxf.endpoint.AbstractConduitSelector.createConduit(AbstractConduitSelector.java:145)
at org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:107)
at org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:63)
at org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:853)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:511)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
... 2 more
I know that there is workaround for this exception which is mentioned here and it works. But not for my work application. It throws NPE after all:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: java.lang.NullPointerException
...
Caused by: org.apache.cxf.binding.soap.SoapFault: java.lang.NullPointerException
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:802)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1642)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1533)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1336)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:652)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
... 7 more
Question time
Why Apache-CXF is used even when application works fine without it?
Is it possible to force application to stop using Apache-CXF in this case?
I don't need this dependencies for client( since it works fine without them). I just want to produce SOAP as well. And thats why I need this dependencies. The only solution which I see is to split application into separate consumer and producer.
application seems to use different implementation of JAX-WS( is it even possible?).
Yes. CXF have it's own jax-ws provider and it's jar contains a service file declaring it. (when the JVM needs a jax-ws provider: it looks on the classpath to see if there is a non-default provider declared... and if any use it).
Why ?
That's the Java specs : http://docs.oracle.com/javaee/5/api/javax/xml/ws/spi/Provider.html#provider()
Is it possible to force application to stop using Apache-CXF in this case?
Yes. Create the appropriate resource file on your classpath to redirect to the default implementation.
In details : the file must be here : META-INF/services/javax.xml.ws.spi.Provider (if you use maven: put it simply here : /src/main/resources/META-INF/services/javax.xml.ws.spi.Provider)
And it must contains one single line :
javax.xml.ws.spi.Provider

Resources