A Karaf feature for liquibase-core
This project contains a karaf feature for easily using Liquibase from OSGi-based applications running in apache karaf.
If you haven’t yet encountered it: liquibase is a really smooth solution for handling your RDBMS schemas. Smooth initial startup, and smooth evolution of schemas (adding columns, adding tables, dropping columns and dropping tables).
Liquibase does the same job as ad-hoc delta script solutions, but liquibase does the job in a clean and robust way, tested and refined over the 11 years of its existence.
From a karaf user standpoint, liquibase has one major quirk and annoyance: the liquibase logging (as in “logging of errors and messages”, not as in “database schema changelogs”) floods the karaf console. This karaf feature aims to fix that, by putting the liquibase logging messages into the regular karaf log (using liquibase-slf4j to reroute the logging).
Project status
Release history
Note: The versions 3.8.1 through 3.10.0 aren’t proper OSGi bundles, so I haven’t created karaf features for these versions.
Version 3.10.1 and 4.0.0 are OSGi bundles and I will create karaf features for these versions.
Date | Version | Liquibase version | Liquibase slf4j version | Comment |
---|---|---|---|---|
<2019-11-18 Mon 21:25> | 3.8.0 | 3.8.0 | 2.0.0 | |
<2019-11-18 Mon 20:42> | 3.7.0 | 3.7.0 | 2.0.0 | Use snakeyaml 1.23 |
<2019-11-18 Mon 19:33> | 3.6.3 | 3.6.3 | 2.0.0 | |
<2019-11-17 Sun 22:58> | 3.6.2 | 3.6.2 | 2.0.0 | |
<2019-11-17 Sun 22:09> | 3.6.1.1 | 3.6.1 | 2.0.0 | Loads snakeyaml 1.18 instead of 1.17 |
<2019-11-17 Sun 17:35> | 3.6.1 | 3.6.1 | 2.0.0 | Broken because of wrong snakeyaml version |
<2019-11-17 Sun 21:27> | 3.6.0.1 | 3.6.0 | 2.0.0 | Loads snakeyaml 1.18 instead of 1.17 |
<2019-11-17 Sun 16:01> | 3.6.0 | 3.6.0 | 2.0.0 | Broken because of wrong snakeyaml version |
<2019-11-16 Sat 23:09> | 3.5.5 | 3.5.5 | 2.0.0 | Use version 3.5.1 of maven-bundle-plugin |
<2019-11-16 Sat 11:28> | 3.5.4 | 3.5.4 | 2.0.0 | Updated pom.xml release config, update karaf to 4.2.7 |
<2017-08-06 Sun 18:48> | 3.5.3 | 3.5.3 | 2.0.0 | First release with the same version as the liquibase version |
<2017-08-06 Sun 15:18> | 1.0.2 | 3.5.3 | 2.0.0 | First successful release |
<2017-08-06 Sun 12:03> | 1.0.1 | 3.5.3 | 2.0.0 | Failed release |
<2017-08-05 Sat 21:37> | 1.0.0 | 3.5.3 | 2.0.0 | Failed release |
Installing the liquibase feature in karaf
To install this feature:
- start karaf and give the following commands to the karaf console:
feature:repo-add mvn:no.priv.bang.karaf/liquibase-core-karaf/LATEST/xml/features feature:install liquibase-core
After this, the liquibase Java API is available to your OSGi applications and the liquibase logging will go to the karaf log.
Using liquibase from a karaf feature
To use liquibase from your own, manually edited, karaf feature, include the feature’s feature repository and depend on the liquibase-core feature:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="ukelonn.bundle.db.liquibase">
<repository>mvn:no.priv.bang.karaf/liquibase-core-karaf/3.8.0/xml/features</repository>
<feature name="ukelonn-db-liquibase">
<feature>liquibase-core</feature>
</feature>
</features>
Using liquibase from a generated karaf feature
If you generate your karaf feature repository using the karaf-maven-plugin, you can include the liquibase-core feature into your generated feature repository, by adding this dependency to the maven project building the feature repository:
<dependency>
<groupId>no.priv.bang.karaf</groupId>
<artifactId>liquibase-core-karaf</artifactId>
<version>3.8.0</version>
<type>xml</type>
<classifier>features</classifier>
</dependency>
Building the feature for a different version of Liquibase
The version number of this karaf feature is intended to be the same as the Liquibase version it is a feature for.
This makes it simple for me to roll and release a new version of the feature when a new version of Liquibase is out.
But unfortunately this means that a SNAPSHOT version of the feature won’t be able to refer to a real Liquibase version… at least not without a little edit:
- clone this project:
mkdir -p ~/git cd ~/git git clone https://github.com/steinarb/liquibase-karaf-feature/
- edit the pom, changing the liquibase.version property
<liquibase.version>${project.version}</liquibase.version>
change it into an actual version
<liquibase.version>3.5.4</liquibase.version>
- then build the project with maven:
cd liquibase-karaf-feature mvn clean install
Test a new version
I have created the project liquibase-sample to test new versions of this karaf feature.
The liquibase-sample has a minimal OSGi component that loads and creates a schema in a derby in-memory database from a liquibase changelog file.
The liquibase-sample application can also be used to verify that the liquibase logs are redirected to the karaf logs.
Notes on the liquibase logging issues
The liquibase logger can be replaced if liquibase finds an implementation of the Logger interface in the package “liquibase.ext.logger” (or a sub-package of this package). The requirements to replace the liquibase logger are outlined in the article Fixing liquibase logging (in Spring) with SLF4J and Log4J.
There already is a solution that uses the approach outlined in the article to replace the liquibase logger with slf4j. This solution is called liquibase-slf4j, and for a non-OSGi program using slf4j, it is enough to add a maven dependency to liquibase-slf4j.
Using liquibase-slf4j won’t work out of the box with karaf:
- liquibase-slf4j isn’t an OSGi bundle
- Even if liquibase-slf4j is made into an OSGi bundle (e.g. by using the wrap protocol in karaf to load the maven dependency), the classloader won’t find the replacement logger
This message on the karaf mailing list outlines the necessary approach:
- Make the liquibase-slf4j into an OSGi fragment instead of an OSGi bundle
- Attach the liquibase-slf4j OSGi fragment to the liquibase-core bundle
This approach effectively makes the liquibase-slf4j contents part of the liquibase-core bundle, and the liquibase classpath scanner will find the replacement logger.
Feature uninstallment issue with the liquibase-slf4j fragment bundle
With karaf 4.1.1 (verified on both Windows 7 and debian GNU/linux, Java 1.8 both places), running the following command will shut down karaf:
feature:uninstall liquibase-core
With karaf 4.0.9 and karaf 4.0.7, uninstalling the liquibase-core doesn’t crash karaf.
If liquibase-slf4j is removed from the “liquibase-core” feature, then uninstalling the feature won’t crash karaf. So the problem is related to differences in logging from karaf 4.0.9 and 4.1.1.
This has been reported as karaf bug .
This issue is verified fixed in karaf 4.1.2-SNAPSHOT.
License
This maven project is licensed with the Apache v 2.0 license.
The details of the license can be found in the LICENSE file.
The liquibase-slf4j jar is covered with the MIT license, copyright 2012-2015 Matt Bertolini. This license and copyright also covers the rebundled version of the jar that results from the “com.mattbertolini.liquibase-slf4j-osgi” maven module.