Spring boot - disable Liquibase at startup - java

I want to have Liquibase configured with my Spring Boot application, so I added dependencies to pom.xml and set the path to master.xml in application.properties. This works fine and Spring Boot runs Liquibase at startup. The problem is that now I want to run Liquibase manually, not at startup of application. Should I completely disable auto-configuration for Liquibase or can I use it and only disable running evaluations at startup?

The relevant property name has changed between Spring versions:
For Spring 4.x.x: the liquibase.enabled=false application property disables Liquibase.
For Spring 5.x.x: the spring.liquibase.enabled=false application property disables Liquibase.
P.S. And for Flyway:
Spring 4.x.x: flyway.enabled=false
Spring 5.x.x: spring.flyway.enabled=false

Add liquibase.enabled=false in your application.properties file
Reference
But if you don't want to use liquibase from application anymore, remove liquibase starter altogether from pom.

If you see on the LiquibaseProperties, there is a prefix like
prefix = "spring.liquibase"
So, My suggestion is to use
spring.liquibase.enabled=false
It solved my problem with spring boot 2.0.0.RC1

I faced an issue where I wasn't able to disable Liquibase from properties for some reason, so this is how I disabled Liquibase with #Bean annotation:
#Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setShouldRun(false);
return liquibase;
}

There is one more programmatic approach.
#EnableAutoConfiguration(exclude = LiquibaseAutoConfiguration.class)
on Application main class

If you want to run Liquibase manually, you could use the liquibase maven plugin. Just add something like this to your pom.xml:
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>${liquibase.version}</version>
<configuration>
<changeLogFile>src/main/liquibase/master.xml</changeLogFile>
<propertyFile>src/main/liquibase/liquibase.properties</propertyFile>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
</configuration>
</plugin>
You can take a look at the plugin documentation for the configuration details.
And don't use the liquibase support from Spring Boot, as it is only meant to be used in runtime. Just remove the liquibase starter and/or any related dependencies as you'll only need the maven plugin.

You can use the spring.liquibase.enabled=true/false

Whilst the documented Spring Boot solution is spring.liquibase.enabled=false, it didn't work for me. To disable liquibase you can also use the following property:
liquibase.shouldRun=false
I passed this as a command line parameter when launching the Spring Boot jar
-Dliquibase.shouldRun=false
see https://docs.liquibase.com/parameters/should-run.html

Related

spring.datasource.platform is not working

I made a project from scratch just with the schema.sql and the data.sql just to try the schema.sql and the data.sql:
https://github.com/rmmcosta/TestSchema
Everything works fine. The table inside schema.sql is created in a MySql database (previously created and the grants were given to the user defined in application.properties) and the data.sql populates the data as it's supposed to do.
But, when I change schema.sql and data.sql to schema-mysql.sql and data-mysql.sql and I put in the application.properties the property spring.datasource.platform=mysql the schema-mysql.sql and the data-mysql.sql are not being executed.
No errors are being thrown, simple nothing happens on the database.
I tried with spring boot 2.2.4 and it works fine, but with spring boot 2.7.5 it isn't working.
Do you know if the spring.datasource.platform was deprecated? And if so, do you know how can I set the application.properties in order to run schema-mysql.sql?
Thank you in advance,
Ricardo
Note:
I tried without using spring.datasource.platform=mysql and with schema.sql and data.sql and everything works fine.
I tried with an old project, spring boot 2.2.4 and java 1.8, and works fine.
Do you know if the spring.datasource.platform was deprecated? And if so, do you know how can I set the application.properties in order to run schema-mysql.sql?
The property name changed to spring.sql.init.platform
https://github.com/spring-projects/spring-boot/blob/d870474fcd4899fac94d51311c4163832d6b109d/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json#L1148
Which occurred in Spring Boot 2.5: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5.0-RC1-Configuration-Changelog
You need to use spring.sql.init.platform instead of spring.datasource.platform property in application.properties.
Please see the comment from latest documentation -
In addition, Spring Boot processes the schema-${platform}.sql and
data-${platform}.sql files (if present), where platform is the value
of spring.sql.init.platform

Override application properties spring boot

I have application.properties like
spring.mail.host=${MAIL_HOST:smtp.gmail.com}
spring.mail.port=${MAIL_PORT:587}
In test I want to change these properties, i run tests with profile like
mvn clean install -Ptests
Then I tried to override
mvn clean install -Ptests -DMAIL_HOST=host -DMAIL_PORT=123
but its not working for me. It is possible to do like this?
You add custom properties to application.yml / properties or application-{env}.yml / properties . Spring recognise it and you can access it via
#Value
Spring environment
Using Spring ConfigurationProperties

What is the purpose of org.springframework.boot.spring-boot POM?

What is the purpose of this POM in Sprint Boot org.springframework.boot.spring-boot
It includes
org.springframework.spring-core
org.springframework.spring-context
So in something like org.springframework.boot.spring-boot-starter-web you have
org.springframework.spring-webmvc
org.springframework.boot.spring-boot-starter
org.springframework.boot.spring-boot-starter-json
org.springframework.boot.spring-boot-starter-tomcat
Why not just make org.springframework.boot.spring-boot-starter-web
org.springframework.spring-webmvc
org.springframework.spring-core
org.springframework.spring-context
org.springframework.boot.spring-boot-starter-json
org.springframework.boot.spring-boot-starter-tomcat
spring-boot-starter has following dependencies:
jakarta.annotation-api
spring-core
spring-boot
spring-boot-autoconfigure
spring-boot-starter-logging
if you replace spring-boot-starter with spring-core and spring-context, then you miss out all the classes and annotations that are defined in spring-boot and spring-boot-autoconfigure(spring-boot depends on spring-core and spring-context, but it has implemented some important classes itself, see below).
take spring-boot-starter-web as an example, usually we need to set server.port in our application.yml, this property is defined in ServerProperties class in spring-boot-autoconfigure project(that's why we need spring-boot-starter in org.springframework.boot.spring-boot-starter-web), there are other commonly used properties such as server.address, server.servlet.context-path, and server.ssl.* ....etc.They are all defined here in spring-boot-autoconfigure project.
in order to auto configure the properties defined in ServerProperties, class ServletWebServerFactoryAutoConfiguration is created to take ServerProperties as a parameter and apply it's values to set up software like tomcat
now see that ServerProperties is neither annotated with #Configuration nor #Component, so it wouldn't be instantiated when component-scan is happening, so this annotation EnableConfigurationProperties is created to make sure ServerProperties's instance will be injected. this annotation is defined in spring boot project, that's why we need spring-boot dependency. And it's used
here.
for what is a spring boot starter and how it works, here is a helpful article: Quick Guide to Building a Spring Boot Starter

How to disable autocommit Spring Boot?

I'm trying to disable autocommit, but I'm not lucky. I'm using the Spring Boot version 2.1.3.RELEASE
application.properties
spring.jpa.database=oracle
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
spring.jpa.generate-ddl=false
spring.jpa.open-in-view=true
spring.jpa.show-sql=false
spring.datasource.hikari.auto-commit=false
Use
spring.datasource.auto-commit=false
This property (and some more too) were not documented.
Please refer below github issue for more undocumented properties.
https://github.com/spring-projects/spring-boot/issues/1829

Using Spring boot/cloud with Amazon AWS lambda does not inject values

I have an AWS lambda RequestHandler class which is invoked directly by AWS. Eventually I need to get it working with Spring Boot because I need it to be able to retrieve data from Spring Cloud configuration server.
The problem is that the code works if I run it locally from my own dev environment but fails to inject config values when deployed on AWS.
#Configuration
#EnableAutoConfiguration
#ComponentScan("my.package")
public class MyClass implements com.amazonaws.services.lambda.runtime.RequestHandler<I, O> {
public O handleRequest(I input, Context context) {
ApplicationContext applicationContext = new SpringApplicationBuilder()
.main(getClass())
.showBanner(false)
.web(false)
.sources(getClass())
.addCommandLineProperties(false)
.build()
.run();
log.info(applicationContext.getBean(SomeConfigClass.class).foo);
// prints cloud-injected value when running from local dev env
//
// prints "${path.to.value}" literal when running from AWS
// even though Spring Boot starts successfully without errors
}
}
#Configuration
public class SomeConfigClass {
#Value("${path.to.value}")
public String foo;
}
src/main/resources/bootstrap.yml:
spring:
application:
name: my_service
cloud:
config:
uri: http://my.server
failFast: true
profile: localdev
What have I tried:
using regular Spring MVC, but this doesn't have integration with #Value injection/Spring cloud.
using #PropertySource - but found out it doesn't support .yml files
verified to ensure the config server is serving requests to any IP address (there's no IP address filtering)
running curl to ensure the value is brought back
verified to ensure that .jar actually contains bootstrap.yml at jar root
verified to ensure that .jar actually contains Spring Boot classes. FWIW I'm using Maven shade plugin which packages the project into a fat .jar with all dependencies.
Note: AWS Lambda does not support environment variables and therefore I can not set anything like spring.application.name (neither as environment variable nor as -D parameter). Nor I can control the underlying classes which actually launch MyClass - this is completely transparent to the end user. I just package the jar and provide the entry point (class name), rest is taken care of.
Is there anything I could have missed? Any way I could debug this better?
After a bit of debugging I have determined that the issue is with using the Maven Shade plugin. Spring Boot looks in its autoconfigure jar for a META-INF/spring.factories jar see here for some information on this. In order to package a Spring Boot jar correctly you need to use the Spring Boot Maven Plugin and set it up to run during the maven repackage phase. The reason it works in your local IDE is because you are not running the Shade packaged jar. They do some special magic in their plugin to get things in the right spot that the Shade plugin is unaware of.
I was able to create some sample code that initially was not injecting values but works now that I used the correct plugin. See this GitHub repo to check out what I have done.
I did not connect it with Spring Cloud but now that the rest of the Spring Boot injection is working I think it should be straightforward.
As I mentioned in the comments you may want to consider just a simple REST call to get the cloud configuration and inject it yourself to save on the overhead of loading a Spring application with every request.
UPDATE: For Spring Boot 1.4.x you must provide this configuration in the Spring Boot plugin:
<configuration>
<layout>MODULE</layout>
</configuration>
If you do not then by default the new behavior of the plugin is to put all of your jars under BOOT-INF as the intent is for the jar to be executable and have the bootstrap process load it. I found this out while addressing adding a warning for the situation that was encountered here. See https://github.com/spring-projects/spring-boot/issues/5465 for reference.

Categories