ORA-01882: timezone region not found in Liquibase Gradle plugin - oracle

In our project we are using Liquibase gradle plugin. Recently, we updated ojdbc8 plugin to version 18.3.0.0. Unfortunately, it caused our Liquibase task to fail with ORA-01882: timezone region not found. I found some solutions for this error (e.g. there: ORA-01882: timezone region not found), but I have no idea how I could add this -Duser.timezone or -Doracle.jdbc.timezoneAsRegion property to gradle task. I tried different approaches, but with no success.
This is how some crucial parts of our build.gradle look like:
liquibase {
activities {
oracle {
changeLogFile "$liquibasePath/db.changelog-master.xml"
driver liquibaseProps['oracle.driver']
url "jdbc:oracle:thin:#${liquibaseProps['oracle.ip.port']}:${liquibaseProps['oracle.schema']}"
username liquibaseProps['oracle.username']
password liquibaseProps['oracle.password']
outputDefaultSchema false
outputDefaultCatalog false
}
}
}
def generate(taskName, taskDescription, generateCommand) {
project.task(taskName, type: LiquibaseTask) {
group = 'Liquibase'
description = taskDescription
inputs.property('databases', getRunList())
inputs.dir liquibasePath
outputs.dir sqlScriptsPath
doLast {
new LiquibaseSqlCleanupTask(sqlScriptsPath).execute()
}
}
}

You need to set that as a system property when running gradle. The docs for that are at https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_system_properties, but here is a copy/paste of the most relevant info:
Using the -D command-line option, you can pass a system property to
the JVM which runs Gradle. The -D option of the gradle command has the
same effect as the -D option of the java command.
You can also set system properties in gradle.properties files with the
prefix systemProp.
So you could create a gradle.properties file in the root directory of your project with contents like this:
systemProp.oracle.jdbc.timezoneAsRegion=false

Related

Gradle Version Catalog (Published): How to dynamically set up repository

I'm not that experienced with Gradle and are currently running into problems when trying to use the new version catalog feature.
Goal:
Using a Gradle 7.4.2 version catalog, managed in a standalone GIT repository and published to private JFrog artifactory, in a second project.
Every project member's artifactory credentials are already available in $HOME/.gradle/gradle.properties (auto-generated by JFrog) and are supposed to be re-used.
Issue:
according to the current Gradle documentation, a published version catalog is supposed to be defined in settings.gradle(.kts) within any project that wants to use the catalog;
inserting that piece of code results in an error because Gradle has no repository definition available for artifact look-up
therefore, adding a repository definition:
// my settings.gradle.kts
rootProject.name = "catalog-consumer"
dependencyResolutionManagement {
val catalogVersion = "0.1.0"
val artifactoryUri = "..."
val catalogGAV = "..."
repositories{
maven {
url = uri("$artifactoryUri")
credentials {
// TODO: how to access user's local gradle.properties for credentials?
username = "$artifactory_user" // key as generated by JFrog
password = "$artifactory_password" // key as generated by JFrog
}
}
}
versionCatalogs {
create("libs") {
from("$catalogGAV")
}
}
}
now, facing the problem that the user's gradle.properties does not seem to be loaded, yet - but hardcoding credentials is not viable :)
Question:
Is the only option to manually check for and load the user's gradle.properties file?
Originally, when reading the documentation, I assumed that the settings file would probably try to look up existing repository definitions from the project's build.gradle.kts, but that wasn't the case either. If I understand it correctly, the settings file is evaluated before everything else, isn't it?
Manually loading the user's config just seems odd to me, therefore, I wanted to ask whether or not I'm missing a mechanism or lifecycle hook that would take care of this. Also possible that I use the version catalog feature incorrectly :D
Any hints very much appreciated!
See the docs here: https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:handling_credentials
Named repository credentials
If you named the repository and add credentials(PasswordCredentials::class)...
// ./settings.gradle.kts
dependencyResolutionManagement {
repositories {
maven {
name = "mySecureRepository"
credentials(PasswordCredentials::class)
// url = uri(<<some repository url>>)
}
}
}
then Gradle will automatically fetch the username/pass from the first found definition:
Using a command line argument
./gradlew build -PmySecureRepositoryUsername=my-username
environment variables prefixed with ORG_GRADLE_PROJECT_ (this is useful for CI/CD)
ORG_GRADLE_PROJECT_mySecureRepositoryUsername=my-username
ORG_GRADLE_PROJECT_mySecureRepositoryPassword=my-password
$GRADLE_USER_HOME/gradle.properties
mySecureRepositoryUsername=my-username
mySecureRepositoryPassword=my-password
gradle.properties in the project root - obviously don't put credentials in your project!
gradle.properties in the Gradle installation directory
Manual providers
If you need to manually set the property names, then you can define your own providers.
// ./settings.gradle.kts
val artifactoryUser = providers.gradleProperty("artifactory_user")
val artifactoryPassword = providers.gradleProperty("artifactory_password")
dependencyResolutionManagement {
repositories {
maven {
name = "mySecureRepository"
credentials {
username = artifactoryUser.get()
password = artifactoryPassword.get()
}
// url = uri(<<some repository url>>)
}
}
}
Again, then Gradle will fetch these properties from either
$GRADLE_USER_HOME/gradle.properties
artifactory_user=my-username
artifactory_password=my-password
or environment variables
ORG_GRADLE_PROJECT_artifactory_user=myUsername
ORG_GRADLE_PROJECT_artifactory_password=my-password

Liquibase Gradle plugin appears to have url and referenceUrl reversed

I have a very simple Spring Boot 2.0.4 project. Following the various examples for setting up the Liquibase Gradle plugin I wanted to be able to run the diffChangeLog target to update my change log XML file. The configuration looks like this:
liquibase {
activities {
main {
url 'jdbc:postgresql://localhost:5432/example_db'
username 'user'
password 'password'
driver 'org.postgresql.Driver'
referenceUrl 'hibernate:spring:com.example?dialect=org.hibernate.dialect.PostgreSQL9Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy'
referenceDriver 'liquibase.ext.hibernate.database.connection.HibernateDriver'
classpath 'src/main'
changeLogFile "src/main/resources/db/changelog/master.xml"
}
runList = 'main'
}
}
The database is empty except for the databasechangelog and databasechangeloglock tables. When I run gradle diffChangeLog the change log XML file is never updated. The output from gradle diff shows "NONE" for everything. My project does have an entity and it is annotated with #Entity.
What am I doing wrong?

gradle task not recognizing the sonar-project.properties file in project workspace

I have created a sample spring boot project along with sonarqube gradle plugin in it .I have add all the needed properties like login token to sonar-project.properties.But while running gradle task I get exception of authentication
Gradle plugin added
plugins { id "org.sonarqube" version "2.6" }
Screenshot of project structure
I also suffered from this pain and my workaround was to parse the settings file and apply it:
sonarqube {
// this is silly but specifying the actual settings file is not supported
properties {
def props = new Properties()
file("sonar-project.properties").withInputStream { props.load(it) }
props.each {
property("${it.key}", "${it.value}")
}
}
}
Gradle analysis doesn't read sonar-project.properties. Instead, add those values to build.gradle as shown in the docs
sonarqube {
properties {
property "sonar.login", "xxxxxxxx"
}
}

Gradle flyway script to update multiple databases

I have a Gradle script which uses the flyway plugin to create some database tables, and now I need to update the script so that it can work with 2 separate sets of flyway scripts, each of which updates a separate database.
In the single-database version of the script I simply do this:
flyway {
url = 'jdbc:edb://localhost:5432/mydb'
schemas = ['my_schema']
user = 'my_user'
password = 'my_pass'
locations = ['filesystem:src/main/resources/db/flyway/my_db']
}
I've been experimenting with declaring a new task to run the scripts for the second db:
task flywayMigrate2 << {
ext {
flyway {
url = 'jdbc:edb://localhost:5432/mydb2'
schemas = ['my_schema2']
user = 'my_user2'
password = 'my_pass2'
locations = ['filesystem:src/main/resources/db/flyway/my_db2']
}
}
}
flywayMigrate2.finalizedBy flywayMigrate
My Gradle skills are poor, but I know this isn't the right way to do it - my understanding is that the ext block overwrites the original flyway configuration, so if I wanted to run flywayMigrate after flywayMigrate2 it would continue to use the second set of config values rather than reverting to the original set.
I can't be the first person to need to do this, but I'm struggling to find a decent approach, can anyone help?
The flyway { ... } extension object is for configuring properties which are common to all flyway tasks. Each task also has properties which can be configured, my guess is that task level properties override properties configured on the flyway { ... } extension object.
I think you'd just configure two FlywayMigrateTask instances in your build.gradle
import org.flywaydb.gradle.task.*
task migrate1(type: FlywayMigrateTask) {
url = 'jdbc:edb://localhost:5432/mydb1'
user = 'user1'
locations = ['filesystem:src/main/flyway/db1/migration']
// etc
}
task migrate2(type: FlywayMigrateTask) {
url = 'jdbc:edb://localhost:5432/mydb2'
user = 'user2'
locations = ['filesystem:src/main/flyway/db2/migration']
// etc
}
See also AbstractFlywayTask.java
I don't think that you have to define another Gradle task in order to introduce a second Flyway configuration.
According to the documentation you simply can overwrite either using Gradle properties
gradle -Pflyway.user=myUsr -Pflyway.schemas=schema1,schema2 -Pflyway.placeholders.keyABC=valXYZ
or system properties
gradle -Dflyway.user=myUser -Dflyway.schemas=schema1,schema2 -Dflyway.placeholders.keyABC=valueXYZ
or providing an external Flyway config
gradle -Dflyway.configFiles=path/to/myAlternativeConfig.conf flywayMigrate
The Flyway Gradle plugin follows the following configuration order:
System properties
Environment variables
Custom config files
Gradle properties
Flyway configuration section in build.gradle
<user-home>/flyway.conf
Flyway Gradle plugin defaults
Alternatively you could introduce a new task that overwrites the Gradle properties of Flyway.
task migrate2(FlywayMigrateTask) {
project.ext['flyway.user']='myUsr'
project.ext['flyway.password']='mySecretPwd'
project.ext['flyway.schemas']='schema1,schema2,schema3'
project.ext['flyway.placeholders.keyABC']='valueXYZ'
project.ext['flyway.placeholders.otherplaceholder']='value123'
}

Gradle: How do I run my LIquibase changesets as part of my normal build process?

I'm using Gradle 2.7 with the Gradle Liquibase plugin v 1.1.1. How do I run my changeSets as part of doing my normal build using
gradle build
? I currently have this in my build.gradle file ...
liquibase {
activities {
main {
File propsFile = new File("${project.rootDir}/src/main/resources/liquibase.properties")
Properties properties = new Properties()
properties.load(new FileInputStream(propsFile))
changeLogFile 'src/main/resources/db.changelog-1.0.xmlll'
url '${url}'
username '${username}'
password '${password}'
}
runList = main
}
}
However when I run the above command ("gradle build"), the above is not run. I know its not run because the username/password are incorrect and I have no change log file ending in ".xmlll". WHat else do I need to add to assure that hte plugin always attempts to execute the changeset?
You need to define a task dependency from build to update.
build.dependsOn update
To get task to run before your tests (assuming you didn't define a new one), you can do
test.dependsOn update
Ref:
Gradle task docs
You can define this in your gradle build file
apply plugin: 'liquibase'
dependencies {
classpath 'org.liquibase:liquibase-gradle-plugin:1.2.0'
}
liquibase {
activities {
main {
changeLogFile 'changelog.xml'
url 'jdbc:h2:db/liquibase_workshop;FILE_LOCK=NO'
username 'sa'
password ''
}
}
And then run this command
gradle update

Resources