quarkus - switching from "default" to "PersistenceUnit" causes "Unsatisfied dependency" - quarkus

Quarkus 2.7.4
I had my app working with default datasource config. When I tried to switch to using persistence units it stopped working. I've got to the point where I get this error...
[ERROR] [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type javax.persistence.EntityManager and qualifiers [#PersistenceUnit(value = "ds")]
[ERROR] - java member: uk.co.me.filter.CheckFilter#entityManager
[ERROR] - declared on CLASS bean [types=[uk.co.me.filter.CheckFilter, javax.ws.rs.container.ContainerRequestFilter, java.lang.Object], qualifiers=[#Default, #Any], target=uk.co.me.filter.CheckFilter]
[ERROR] The following beans match by type, but none have matching qualifiers:
[ERROR] - Bean [class=org.hibernate.Session, qualifiers=[#javax.enterprise.inject.Default, #Any]]
What am I missing?.
I had my default config working...
quarkus:
datasource:
db-kind: mssql
username: user
password: pwd
jdbc:
url: jdbc:sqlserver://localhost:1433
Then I tried to convert it to a persistent unit...
quarkus:
datasource:
ds:
db-kind: mssql
username: user
password: pwd
jdbc:
url: jdbc:sqlserver://localhost:1433
hibernate-orm:
datasource: ds
packages: uk.co.me.filter
And I added the annotation to my class
#Inject #PersistenceUnit("ds") EntityManager entityManager;
First it complained about couldn't find default models so I added the original config back in. That resolved the error (I realise not the best, but hey, just trying to get things moving). Now I get the above error when trying to build the quarkus-run.jar

On the configuration snippet you add, you only configure a ds named datasource but not a ds named persistence unit so only the default one exist.
You need to configure Hibernate ORM or multiple persistence unit as explained here: https://quarkus.io/guides/hibernate-orm#multiple-persistence-units
In your case something like this:
quarkus:
datasource:
ds:
db-kind: mssql
username: user
password: pwd
jdbc:
url: jdbc:sqlserver://localhost:1433
hibernate-orm:
ds:
datasource: ds
packages: uk.co.me.filter

Related

Disabling Spring Security leads to Failed to load application context

I am disabling Spring Security for the test profile as below:
spring:
config:
activate:
on-profile: test
autoconfigure:
exclude[0]: org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
exclude[1]: org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
Error:
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/reactive/ReactiveOAuth2ClientConfigurations$ReactiveOAuth2ClientConfiguration$SecurityWebFilterChainConfiguration.class]: Unsatisfied dependency expressed through method 'springSecurityFilterChain' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.web.server.ServerHttpSecurity' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
A small clarification that you are not disabling Spring Security, you are disabling the Spring Boot auto-configuration of Spring Security. You can read more about that in the Spring Boot reference documentation.
In your configuration you are disabling the ReactiveSecurityAutoConfiguration, but the ReactiveOAuth2ClientAutoConfiguration is still enabled, presumably because you have a dependency such as spring-boot-starter-oauth2-client.
As described in the error message, the ReactiveOAuth2ClientAutoConfiguration is attempting to create a SecurityWebFilterChain bean, but cannot inject the required ServerHttpSecurity bean, because the ReactiveSecurityAutoConfiguration is disabled.
To fix the error message, you can disable the OAuth 2.0 client auto-configuration as well.
spring:
autoconfigure:
exclude[0]: org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration
exclude[1]: org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration
exclude[2]: org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration
I am using the okta-spring-boot-starter and this worked for me:
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration
- org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration
- org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration

Flyway quarkus extension get "java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus" when executing test

When execute mvnw test in my project using Flyway quarkus extension with version 1.13.2_Final, it produces the following error:
java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
Caused by: java.lang.RuntimeException: Failed to start quarkus
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException:
Unable to obtain connection from database: Error General : "java.lang.NullPointerException"
General error: "java.lang.NullPointerException" [50000-197]
-------------------------------------------------------------------------------------------------------------------------------------------------------
SQL State : HY000
Error Code : 50000
Message : Error General : "java.lang.NullPointerException"
General error: "java.lang.NullPointerException" [50000-197]
Caused by: org.h2.jdbc.JdbcSQLException:
Error General : "java.lang.NullPointerException"
General error: "java.lang.NullPointerException" [50000-197]
Caused by: java.lang.NullPointerException
I have the following configuration for datasource and flyware en test profile.
"%test":
quarkus:
datasource:
db-kind: h2
jdbc:
credentials-provider: my-bbdd-credentials-provider
driver: org.h2.Driver
url: jdbc:h2:tcp://localhost/mem:test;MODE=Oracle
max-size: 13
flyway:
locations: db/migration-test
schemas: PUBLIC
baseline-on-migrate: true
migrate-at-start: true
I think Quarkus flyway extension isn't using the class that implements credential-provider. This class decrypts the user's password from other property. This class works well when using credential-provider with agroal and hibernate-orm-panache extensions.
Can someone help me with this problem?
Thanks

Spring-Boot Test loading application.propertites wrong - 2.4.2

I was using Spring-Boot 2.2.4.RELEASE version and I decided to upgrade to 2.4.2 version since is not a released version. My problem started because I have two configuration file, one that I use configserver and another that I have a in memory database configured to class test.
src/main/resources/application.properties:
...
spring.profiles.active=#activatedProperties#
spring.config.import=optional:configserver:#url#
src/test/resources/application.yml:
spring:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
show-sql: true
properties:
hibernate.format_sql: true
....
datasource:
driver-class-name: org.h2.Driver
platform: h2
name: CUP_ORCHESTRATOR
url: jdbc:h2:mem:CUP_ORCHESTRATOR;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS CUP_ORCHESTRATOR
initializaion-mode: embedded
username: sa
password:
Before the update when I ran the Spring-Boot test class, it always took the correct configuration file, but now it is getting src/main/resources/application.properties for test:
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.closeupinternational.cpoprocesscontrol.test.WorkflowServiceTest
18:39:28.943 [main] ERROR o.s.boot.SpringApplication - Application run failed
java.lang.IllegalStateException: Unable to load config data from 'optional:configserver:http://localhost:8888'
WorkflowServiceTest:
#SpringBootTest(properties = "spring.cloud.config.enabled=false")
#TestPropertySource("classpath:application.yml")
#Slf4j
public class WorkflowServiceTest {
#MockBean
private SenderConfig senderConfig;
What changed from one version to another that broke my project?
Change application.yml to application.properties as the TestPropertySource annotation only works for .properties files.

SpringBoot Load profile properties from classpath

My Question:
It is possible to load an configuration application-persist.yml from the classpath during startup?
The application-persist.yml is part of my external lib and contains the spring.datasource configuration
myexternallib.jar
- config
- application-persist-dev.yml
spring:
datasource:
jdbc-url: url-to-dev-database
username: xxx
password: xxx
driver-class-name: org.postgresql.Driver
- application-persist-prod.yml
spring:
datasource:
jdbc-url: url-to-prod-database
username: xxx
password: xxx
driver-class-name: org.postgresql.Driver
In my spring boot project the myexternallib.jar is included as a dependency
and I want to load the configuration from classpath:
The application.yml of my project:
spring:
profiles:
include: persist
active: dev, persist-dev
The Problem is: When i start my application, the Startup failed with an exception:
Caused by: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
because the application-persist-dev.yml is not read correctly during startup.
How can i fix it?
Spring Boot's reference documentation is very clear at this point:
java -jar myproject.jar --spring.config.location=classpath:/application-persist.yml

configure dataSource for liquibase in spring boot

I have a spring boot application and I want to add liquibase configuration change log for it.
I have created a LiquibaseConfig class for configuring liquibase:
#Configuration
public class LiquibaseConfiguration {
#Value("${com.foo.bar.liquibase.changelog}")
private String changelog;
#Autowired
MysqlDataSource dataSource;
#Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(dataSource);
liquibase.setChangeLog(changelog);
return liquibase;
}
}
and I have configured the datasource information in properties file:
spring.datasource.url=jdbc:mysql://localhost:3306/dms
spring.datasource.username=root
spring.datasource.password=test
spring.datasource.testWhileIdle = true
spring.jpa.show-sql = true
#liquibase
com.foo.bar.liquibase.changelog=classpath:/db/changelog/db.changelog.xml
when I run my application I receive this error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'liquibaseConfiguration': Unsatisfied dependency expressed through field 'dataSource': No qualifying bean of type [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] found for dependency [com.mysql.jdbc.jdbc2.optional.MysqlDataSource]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] found for dependency [com.mysql.jdbc.jdbc2.optional.MysqlDataSource]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Now I understood that this means the application cannot autowire the MysqlDataSource dataSource; but I need to pass the data source to liquibase bean. How can I do that?
Here's a simple step to integrate liquibase in spring boot
STEP 1
Add liquibase dependency
Gradle
runtime "org.liquibase:liquibase-core"
Maven
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<scope>runtime</scope>
</dependency>
STEP 2
Add liquibase changelog file path in application.yml
liquibase:
enabled: true #this is optional as enabled by default
change-log: classpath:/liquibase/db-changelog.xml
Notice property liquibase.change-log. I'm referring path as /liquibase/db-changelog.xml. so you should have a file name db-changelog.xml inside src/main/resources/liquibase/
STEP 3
Add your changesets on the file and when Spring-Boot application is started (spring-boot:run) your changeset will be loaded.
This will use default dataSource that your app uses.
More Info: http://docs.spring.io/spring-boot/docs/1.4.3.RELEASE/reference/htmlsingle/#howto-execute-liquibase-database-migrations-on-startup
Update
For Spring Boot 2.0 as #veben pointed out in comment use
spring:
liquibase:
change-log: #path
Rather than autowire the datasource, create a method in your Liquibase Configuration Object to create the datasource.
private DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUsername("user");
dataSource.setPassword("pswd");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/db");
dataSource.setSchema("dbName");
return dataSource;
}
then in your bean generation method
liquibase.setDataSource(dataSource());
This gives you a chance to specify the database parameters on the fly, I still had the changelog location in the applications.properties file along with the enablement of liquibase. I've tried it, and it works for me.
I had a similar construct for my application, have you tried injecting a more generic javax.sql.DataSource instead?
My guess is that Spring uses the non-specific type for this bean, on top of that you shouldn't even use a database-specific type if your application could be configured to use a totally different source, i.e. by just changing the datasource URL in the configuration file.

Resources