Add JSON provider for CXF JAX-RS in Spring Boot properties or YAML file - spring-boot

How to move endpoint.setProvider(new JacksonJsonProvider()); into an application properties file?
#Bean
public Server rsServer() {
JAXRSServerFactoryBean endpoint = new JAXRSServerFactoryBean();
endpoint.setBus(bus);
endpoint.setProvider(new JacksonJsonProvider());
endpoint.setServiceBeans(asList(new CustomerServiceDefault()));
endpoint.setAddress("/");
endpoint.setFeatures(asList(new Swagger2Feature()));
return endpoint.create();
}

First if you haven't done so already, you have to add the dependency with the provider:
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.0</version>
</dependency>
Then you need to add the package with Jackson entity providers for JAX-RS scanning (org.codehaus.jackson.jaxrs in this case), together with other packages you created. I'm using yaml configuration and class scanning as opposed to component scanning, and here is how it looks:
cxf:
path: /services
servlet.init:
service-list-path: /info
jaxrs:
classes-scan: true
classes-scan-packages: com.yourcompany.package.with.your.handlers,org.codehaus.jackson.jaxrs

Related

Refresh not working when using spring cloud starter and fabric8

I think that there is an issue when using these two dependencies in the same projet. I'm talking about spring-cloud-starter and spring-cloud-starter-kubernetes-fabric8-config.
I'm using
Spring Boot : 2.7.7
Spring Cloud : 2021.0.5
What i'm trying to build is a spring boot application on kubernetes. Each time a configmap or a sercret get changed, the app context should be updated with the new values. To achieve this, i'm using the spring cloud watcher.
https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/#spring-cloud-kubernetes-configuration-watcher
For the configmap part, everything works fine but when i tried to use a secret i noticed a strange behavior. The spring watcher calls my pods on the /actuator/refresh endpoint but nothing get updated. Actually, even on my local machine, the /refresh endpoint returns 200_OK but nothing is updated.
Here's the code snippet :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
#Configuration
#ConfigurationProperties(prefix = "metadata")
#PropertySource(value = "classpath:acl-default.yaml", factory = YamlPropertySourceFactory.class)
#PropertySource(value = "file:${user.home}/acls/acl.yaml", factory = YamlPropertySourceFactory.class, ignoreResourceNotFound = true)
#Slf4j
#Getter
#Setter
public class ACLConfig implements InitializingBean {
private List<User> users;
The ACLConfig class will load our users credentials let's say based on a file from the files system under ${user.home}/acls/acl.yaml otherwise it will get loaded from the classpath.
The content of ${user.home}/acls/acl.yaml is :
metadata:
users:
- name: Richard
password: kjqsd78jkdq-local
- name: Richard
password: jqsd98ds78-local
- name: Richard
password: kSkjqf887qsd-local
bootstrap.properties
server.port=8080
spring.application.name=demo
spring.cloud.kubernetes.config.sources[0].name=${spring.application.name}
spring.cloud.kubernetes.config.sources[0].namespace=spring-cloud-watcher
application.properties
logging.level.root=INFO
logging.level.com.example.demo=DEBUG
management.endpoints.web.exposure.include=info,health,refresh
spring.config.import=optional:file:${user.home}/acls/acl.yaml
So as i said, this example does not work (the acl file update will not trigger the spring context refresh).
To make it work, you have to :
delete the spring-cloud-starter-kubernetes-fabric8-config dependency from pom.xml,
change the content of ${user.home}/acls/acl.yaml,
call the /actuator/refresh,
check the logs : you'll see that ACLConfig -> users List will be updated
You can find the example on my repo : https://github.com/mamdouni/spring-watcher-example
Delete the fabric8 dependency is not an option for me because i need to run this on kubernetes but i don't understand why it blocks the context refresh !!!
Any help will be appreciated.

Spring boot application with Spring-boot-starter-data-jpa and spring-boot-starter-test makes spring does not find application properties

I have created a small application with spring boot that access to a database (mySql) using spring data:
spring-boot-starter-parent: 2.4.2
spring-boot-starter-web: 2.4.2
spring-boot-starter-data-jpa: 2.4.2
mysql-connector-java: 8.0.22
spring-boot-starter-test: 2.4.2
org.junit.jupiter: 5.7.0
junit-jupiter-engine: 5.7.0
I have configured my application.properties, inside src/main/resources, and I have configured the properties for url, username, password, driver, ..., like this:
spring.datasource.url=jdbc:mysql://localhost:3306/BBDD
spring.datasource.username=XXX
spring.datasource.password=XXXX
spring.datasource.driver=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect:org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
I have an interface for my repository for access to my database:
#Repository
public interface ArticleRepository extends PagingAndSortingRepository<ArticuloEntity, Integer> {
}
also, I have defined my entity.
The issue consists on when I start my webapp, I get an error because it does not read the parameters for configuring the datasource from the application.properties:
Description:
Failed to configure a DataSource: 'url' attribute is not specified and
no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following: If you want an embedded database (H2, HSQL or
Derby), please put it on the classpath. If you have database settings
to be loaded from a particular profile you may need to activate it (no
profiles are currently active).
If I remove the dependencies for spring-boot-starter-test and junit, the application loads fine, and it access to database. But if I add the dependency for adding my junits, it does not read my application.properties file and I get the previous error.
How can I have my application configured with junits and reading the configuration for my application with the application.properties file?
Thank you in advance!
Your test/application.properties needs to be configured as well. Try adding this to your test application properties file
spring.datasource.url=jdbc:h2:mem:BBDD;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
and this to your pom if you don't already support h2.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
check your application.properties
changing
spring.datasource.driver=com.mysql.jdbc.Driver
to
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Azure AppConfiguration with Spring Boot 2.5.x

Question
How to integrate an Azure AppConfiguration with SpringBoot 2.5.x or higher?
Info
Im trying to use an Azure AppConfiguration resource with a Spring Boot 2.5.4 project. Unfortunately I cant get it to read a setting from the AppConfiguration or even connect to it as far as I can tell.
The project is newly created with the Spring Initializr where I only added
Spring Boot Starter Web
Spring Boot Starter Security
Spring Boot Starter WebSocket
Afterwards I tried following the Microsoft Quickstart documentation with no success. The documentation mentions that its using Spring 2.4.x so I assume some changes broke it.
I also tried to identify the issue by looking through some Azure Spring Boot Code Samples.
All the examples so far use the bootstrap.properties file which I learned during my search so far is deprecated. Moving the settings to the application.yml or enabling use-legacy-processing: true did not work either. Any ideas?
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</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-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-cloud-appconfiguration-config</artifactId>
<version>2.0.0</version>
</dependency>
...
application.yml
spring:
config:
use-legacy-processing: true
profiles:
active: "develop"
application:
name: "MySampleService"
cloud:
azure:
appconfiguration:
stores:
- connection-string: "SomeAzureAppConfigurationResourceConnectionString"
label: ${spring.profiles.active}
#mysampleservice:
# message: "this is a message from file"
AppConfiguration Resource
Im not entirely sure about the format for the setting name. I tried to build the format based on this documentation.
The configuration classes should be fine since commenting in the mysampleservice causes the value of message beeing used.
Any hints are appreciated!
Some more info to elaborate on the accepted answer
The documentation linked in the answer refers to two different packages. The one linked right at the start in the maven repository is spring-cloud-azure-appconfiguration-config while the one used further down is azure-spring-cloud-appconfiguration-config. The second one works with the bootstrap.properties file.
Working pom.xml and bootstrap.properties:
...
<dependencies>
<!-- Dependency to load configuration from azure app configuration resource. Note that additional settings are required in bootstrap.properties
Documentation of settings: https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/appconfiguration/azure-spring-cloud-starter-appconfiguration-config
-->
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-cloud-appconfiguration-config-web</artifactId>
<version>2.1.0</version>
</dependency>
...
# Use this to enable or disable the cloud config, disabling it results in application.yaml beeing used.
spring.cloud.azure.appconfiguration.enabled=true
# Connection string to azure app configuration resource
spring.cloud.azure.appconfiguration.stores[0].connection-string= Endpoint=https://myofficeconfiguration.azconfig.io;Id=zUcT-l9-s0:PFYfW7WM0/Pz7WZOnH3v;Secret=JTB9myJqGekDAJ5m8Z1vjmkJZrPd88JbOEE3EqoqJYs=
# Configured filters for settings in the previous defined app configuration resource
spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filter = /mysampleservice/
spring.cloud.azure.appconfiguration.stores[0].selects[0].label-filter = Sample
spring.cloud.azure.appconfiguration.stores[0].selects[1].key-filter = /notificationservice/
spring.cloud.azure.appconfiguration.stores[0].selects[1].label-filter = Sample2
bootstrap.yml/bootstrap.properties can still be used, they are no longer part of the base Spring packages.
Also, you want to use this doc for 2.0.0 and newer https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/appconfiguration/azure-spring-cloud-starter-appconfiguration-config.

Eureka Client running with name "UNKNOWN" in eureka server UI

I created a Eureka server spring boot application. It is properly loaded. After that I am trying to create a Eureka client.But it is not getting listed in eureka server UI. I am adding my client application details.
My main controller class file is as below,
#SpringBootApplication
#EnableDiscoveryClient
public class ZEurekaClientServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ZEurekaClientServiceApplication.class, args);
}
}
And my pom.xml contains the ,
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
And
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
And my application.properties file containing,
eureka.client.serviceUrl.defaultZone=http://localhost:8071/eureka
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
When It client is running , the eureka server UI not showing it's name. ONly showing UNKNOWN as application. I am adding its screenshot below.
What I need to display the application name instead of "UNKNOWN" in the eureka server UI? Is there is any additional settings to add application name?
You can specify the application name by setting it either in your application.yml or in your application.properties.
For application.yml:
spring:
application:
name: {YOUR_APPLICATION_NAME}
For application.properties:
spring.application.name={YOUR_APPLICATION_NAME}
In my case, the property (yml) file could not be copied to the target folder due to a build problem.
If this happens, none of the yml properties will load and the spring boot program will run with the default configuration.
For example, Tomcat started with 8080, not any port you specified in the yml file

logging.config configuration for spring boot

I wanted to configure location of log4j.xml file in my spring boot application.
For that I have added logging.config property to my application.properties configuration, indicating log4j.xml file path.
But seems this property is ignored.
But it should work accorindg to spring boot docs:
logging.config= # location of config file (default classpath:logback.xml for logback)
Have I did something wrong?
Spring Boot includes some starters that can be used if you want to exclude or swap specific technical facets. It's using logback by default, if you're gonna use log4j add spring-boot-starter-log4j in your classpath. For example, with maven it would be something like this:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
and for log4j 1.x:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
Then add logging.config to your application.properties:
logging.config = classpath:path/to/log4j.xml
I find out that in some cases external logging config(logback.xml)is not ignored: when application is started from application folder, it works properly.
Some clarification on this point: application is run through script, which can be called from any place.
I have not yet gone deep and found out why it works in that way, but if I provide config file path as an argument during the start up, it will work. So we just add this argument to running script:
--spring.config.location=/configPath/application.properties
Probably this problem is caused by Spring loading stages.
If you have any idea what is the root cause of this problem , please share:)
According to spring boot docs :
If you are using the starter poms for assembling dependencies that means you have to exclude Logback and then include your chosen version of Log4j instead.
like this :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>
I spend few days to understand whether this should even work and I have doubts regarding this. Despite it is clearly mentioned in the documentation how to use Custom Log Configuration, some treat it differently. There many issues regarding this property is not working here and there on spring github issue tracker, like this and this. And another valid point is that logging configuration must be done as earlier as possible to correctly log application initialization. Thus system property looks like most savvy option here. And you can keep it within your application code. The only requirements would be to set it before spring context initialization.
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
// to start from command line
System.setProperty("logging.config", "classpath:portal-log4j2.yaml");
SpringApplication.run(Application.class, args);
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
// to start within container
System.setProperty("logging.config", "classpath:portal-log4j2.yaml");
// this has SpringApplication::run() inside
super.onStartup(servletContext);
}
}
Because all apps in Tomcat web container is loaded within the same JVM, there is no sense to deal with custom logging.config but use single config for the whole container with default file name.

Resources