Liquibase changelogs, should I create a directory for a release with contains no changelogs? - liquibase

0.4 started this week so our team created a new directory when the first changelog was created.
Should we create a v0.3 even though there was no Liquibase changelogs introduced, but there was an application release of v0.3.
What's the best practice here?
.
├── changelog-root.xml
├── v0.1
│     ├── 1661285844-initialschema.xml
│     └── 1661285857-createstudenttable.xml
├── v0.2
│     └── 1661295851-agecolumnonstudent.xml
└── v0.4
      └── 1661395851-studentagechangetype.xml
changelog-root.xml is the top level changelog and includes references to all other changelogs:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd">
<includeAll path="v0.1/"/>
<includeAll path="v0.2/"/>
<includeAll path="v0.4/"/>
</databaseChangeLog>

Related

Command to get paths to jars for ivy-managed dependencies

Is there a way to get the paths to the JAR files for ivy-managed dependencies so that a program can be called from the command line and the JAR files are all correctly included in the class path.
Some thing like (for Linux bash and similar scripts):
java -cp `ivyget.sh ivy.xml`
which could then expand to
java -cp "/path/to/first.jar:/path/to/second.jar"
Is something like this possible?
Ivy can be used in a standalone fashion, see the documentation. I have included an example below.
While this is a nifty feature I prefer to just use ivy for downloading. If your java program has options (eg -option1 or --option2) then ivy is not capable of properly parsing the command-line.
Example
The following project is used to manage a database schema using liquibase
├── changesets
│   └── scottTiger.xml
├── ivy.xml
├── liquibase.properties
└── liquibase.sh
The project is executed by running the shell script
./liquibase.sh update
liquibase.sh
#!/bin/bash
java -jar $HOME/.ant/lib/ivy.jar \
-error \
-ivy ivy.xml \
-main liquibase.integration.commandline.Main \
-args $#
ivy.xml
The ivy file pulls in the liquibase and H2 database projects as dependencies
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<dependencies>
<dependency org="org.liquibase" name="liquibase-core" rev="latest.release" conf="default"/>
<dependency org="com.h2database" name="h2" rev="latest.release" conf="default"/>
</dependencies>
</ivy-module>
liquibase.properties
Run-time configuration file, where the DB type is set to H2.
url=jdbc:h2:./db/scottTiger
driver=org.h2.Driver
username=user
password=pass
changeLogFile=changesets/scottTiger.xml
logLevel=info

Ivy optional configuration mapping (source, javadoc)

Is it somehow possible to specify a optional defaultconfmapping for ivy?
What im looking for is to specify in the defaultconfmapping to get all source jars, but some lib dont have source jars available, and those would be fine to skip.
something like:
<dependencies defaultconf="default" defaultconfmapping="default->default,sources(?onlyifavailable)" >
is this somehow possible in ivy?
Else is there a way to only specify to NOT get a conf target?
ie:
<dependency org="org.lib" name="example" rev="default->!sources" />
The main thing i'm looking for is a way to define all (most) configuration mappings in the defaultconfmapping and not duplicate these mappings on individual items.
This means i'm looking for either an option to 'get but ignore if not there' or 'only adjust this part of the mapping without having to duplicate the parts that are still the same'
(one of the reasons is the large amount of dependecies we have)
If you have an empty fallback, it essentially makes the configuration optional:
<dependencies defaultconf="default" defaultconfmapping="default->default,sources()" >
Default configuration mappings are defined on the optional configuration declaration within your ivy file:
For example
<configurations defaultconfmapping="compile->default;sources;javadoc">
..
..
This creates 3 configuration mappings (which I think is what you're looking for):
compile->default
sources->sources
javadoc->javadoc
Personally I prefer to default an explicit configuration mapping on each dependency, but that's more pendantic.
Example
The following example generates an ivy report for each configuration and saves the source and javadoc jars in specific directories:
├── build.xml
├── ivy.xml
└── target
├── ivy-reports
│   ├── com.myspotontheweb-demo-compile.html
│   ├── com.myspotontheweb-demo-javadoc.html
│   ├── com.myspotontheweb-demo-runtime.html
│   ├── com.myspotontheweb-demo-sources.html
│   ├── com.myspotontheweb-demo-test.html
│   └── ivy-report.css
├── javadoc
│   ├── junit-4.11-javadoc.jar
│   ├── slf4j-api-1.7.5-javadoc.jar
│   └── slf4j-log4j12-1.7.5-javadoc.jar
└── sources
├── junit-4.11-sources.jar
├── slf4j-api-1.7.5-sources.jar
└── slf4j-log4j12-1.7.5-sources.jar
build.xml
<project name="demo" default="resolve" xmlns:ivy="antlib:org.apache.ivy.ant">
<!--
================
Build properties
================
-->
<property name="build.dir" location="target"/>
<target name="resolve" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:report todir='${build.dir}/ivy-reports' graph='false' xml='false'/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="test.path" conf="test"/>
<ivy:retrieve pattern="${build.dir}/[conf]/[artifact]-[revision](-[classifier]).[ext]" conf="sources,javadoc"/>
</target>
</project>
ivy.xml
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations defaultconfmapping="compile->default;sources;javadoc">
<conf name="compile" description="Required to compile application"/>
<conf name="sources" description="Source jars"/>
<conf name="javadoc" description="Javadoc jars"/>
<conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
<conf name="test" description="Required for test only" extends="runtime"/>
</configurations>
<dependencies>
<!-- compile dependencies -->
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5"/>
<!-- runtime dependencies -->
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default;sources;javadoc"/>
<!-- test dependencies -->
<dependency org="junit" name="junit" rev="4.11" conf="test->default;sources;javadoc"/>
</dependencies>
</ivy-module>

Ivy dependency management for legacy repository

We have a repository which doesn't have ivy.xml and other metadata files. Since, its published by another team which doesn't use ivy/maven but will continue to deliver code frequently.
The jars needed for dependency are stored in flat structure inside a single directory with no revision data. The organization / module /revision structure is absent.
Does ivy allow such dependency resolutions in the core product or will I have to write a custom resolver?
Thanks
The standard resolvers should be able to pick up the atifacts (url, filesystem, etc). The problem you'll face is that, by default, ivy assumes a revision never changes. Without version information you're going to have tweak the standard resolver settings to force ivy to always check the artifact.
The ivy concepts page explains how this works:
Some people, especially those coming from maven 2 land, like to use one special revision to handle often updated modules. In maven 2 this is called a SNAPSHOT version, and some argue that it helps save disk space to keep only one version for the high number of intermediary builds you can make whilst developing.
Ivy supports this kind of approach with the notion of "changing revision". A changing revision is just that: a revision for which Ivy should consider that the artifacts may change over time. To handle this, you can either specify a dependency as changing on the dependency tag, or use the changingPattern and changingMatcher attributes on your resolvers to indicate which revision or group of revisions should be considered as changing.
Personally I dislike this kind of dependency management. Your build is a moving goal post and it's hard to keep it stable.
I would encourage to to persuade the other team to at least append a build number to each artifact they publish. Your ivy build could then use a dynamic revision to resolve the artifact. The key point is that when you ship your code, your module will have a dependency against a specific version of its 3rd party libraries.
Update
The following is an example project. It uses Maven Central and a local repo, to download its dependencies.
├── build
│   ├── compile
│   │   ├── artifact1.jar <-- Changing artifact
│   │   └── slf4j-api.jar
│   ├── runtime
│   │   ├── artifact1.jar <-- Changing artifact
│   │   ├── artifact2.jar <-- Changing artifact
│   │   ├── log4j.jar
│   │   ├── slf4j-api.jar
│   │   └── slf4j-log4j12.jar
│   └── test
│   ├── artifact1.jar <-- Changing artifact
│   ├── artifact2.jar <-- Changing artifact
│   ├── artifact3.jar <-- Changing artifact
│   ├── hamcrest-core.jar
│   ├── junit.jar
│   ├── log4j.jar
│   ├── slf4j-api.jar
│   └── slf4j-log4j12.jar
├── build.xml
├── ivysettings.xml
└── ivy.xml
The local repo is un-versioned and has no ivy files. Normally the ivy resolvers require ivy files (or POM in the case of Maven) to determine if a remote module has changed. In the absence of metadata you can mark the dependency as changing in the ivy file.
build.xml
<project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="build" description="do something">
<ivy:retrieve pattern="build/[conf]/[artifact].[ext]"/>
</target>
<target name="clean" description="Cleanup build files">
<delete dir="build"/>
</target>
<target name="clean-all" depends="clean" description="Additionally purge ivy cache">
<ivy:cleancache/>
</target>
</project>
Notes:
Stand build file using ivy. The retrieve task assembles the files into their various configuration groupings.
ivy.xml
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="compile" description="Required to compile application"/>
<conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
<conf name="test" description="Required for test only" extends="runtime"/>
</configurations>
<dependencies>
<!-- compile dependencies -->
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/>
<dependency org="myorg" name="artifact1" rev="NA" conf="compile->default" changing="true"/>
<!-- runtime dependencies -->
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default"/>
<dependency org="myorg" name="artifact2" rev="NA" conf="runtime->default" changing="true"/>
<!-- test dependencies -->
<dependency org="junit" name="junit" rev="4.11" conf="test->default"/>
<dependency org="myorg" name="artifact3" rev="NA" conf="test->default" changing="true"/>
</dependencies>
</ivy-module>
Notes:
The "myorg" dependencies have a dummy "NA" entry as their revision and are marked as "changing".
ivysettings.xml
<ivysettings>
<settings defaultResolver="central" />
<resolvers>
<ibiblio name="central" m2compatible="true"/>
<url name="myorg-repo">
<artifact pattern="http://localhost:8080/userContent/[artifact].[ext]"/>
</url>
</resolvers>
<modules>
<module organisation="myorg" resolver="myorg-repo"/>
</modules>
</ivysettings>
Notes:
The "myorg-repo" resolver is setup to download only the "myorg" dependencies. This enables all other dependencies to be resolved by Maven Central.
The "myorg-repo" resolver just declares an artifact pattern, I'm assuming there are no ivy files to be retrieved.
Understanding ivy pattern helped me resolve the issue. The catch is never specify an ivy pattern whenever the repository doesn't have ivy files.

Maven 3 Profile Properties - enhancement or bug?

In Maven 2, I was able to set profile properties like these:
<profiles>
<profile>
<id>test</id>
<properties>
<region>test</region>
<application-url>http://localhost:8080/myTestApp</application-url>
<cookie-name>TestCookie</cookie-name>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<region>production</region>
<application-url>http://prodserver/myProductionApp</application-url>
<cookie-name>ProductionCookie</cookie-name>
</properties>
</profile>
<profiles>
At compile time Maven would replace these configuration values in my spring beans. For instance, if I had a spring bean defined like this:
<bean id="cookie-name" class="java.lang.String">
<constructor-arg value="${cookie-name}"/>
</bean>
and I specified -P test when i build the project, Maven would set the set the bean to look like
<bean id="cookie-name" class="java.lang.String">
<constructor-arg value="TestCookie"/>
</bean>
and when I specified -P production, maven again replaced the text with the correct property
<bean id="cookie-name" class="java.lang.String">
<constructor-arg value="ProductionCookie"/>
</bean>
As the number of environments and customers we support has increased, I've been taking more advantage of this functionality.
I've tried to upgrade to Maven 3, but it seems like this behavior has disappeared or is broken. I can't seem to find what it has been replaced by.
Anyone have any insights on how or if I can upgrade to Maven3 while preserving this behavior?
I've tried to upgrade to Maven 3, but it seems like this behavior has disappeared or is broken. I can't seem to find what it has been replaced by.
Resources filtering just works fine with Maven 3. Given the following project structure:
.
├── pom.xml
└── src
├── main
│   ├── java
│   │   └── com
│   │   └── stackoverflow
│   │   └── App.java
│   └── resources
│   └── beans.xml
└── test
└── java
└── com
└── stackoverflow
└── AppTest.java
With the following pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>Q4206883</artifactId>
<version>1.0-SNAPSHOT</version>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>test</id>
<properties>
<region>test</region>
<application-url>http://localhost:8080/myTestApp</application-url>
<cookie-name>TestCookie</cookie-name>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<region>production</region>
<application-url>http://prodserver/myProductionApp</application-url>
<cookie-name>ProductionCookie</cookie-name>
</properties>
</profile>
</profiles>
</project>
And where beans.xml contains:
<bean id="cookie-name" class="java.lang.String">
<constructor-arg value="${cookie-name}"/>
</bean>
Running maven with any of the profiles e.g.:
$ mvn -P test process-resources
[INFO] Scanning for projects...
...
Produces the expected result:
$ cat target/classes/beans.xml
<bean id="cookie-name" class="java.lang.String">
<constructor-arg value="TestCookie"/>
</bean>
Tested with:
$ mvn --version
Apache Maven 3.0 (r1004208; 2010-10-04 13:50:56+0200)
Java version: 1.6.0_22
Java home: /usr/lib/jvm/java-6-sun-1.6.0.22/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux" version: "2.6.35-22-generic" arch: "i386" Family: "unix"
If this is not what you get, please provide some pieces allowing to reproduce.
Can only post 1 link at a time and apparently only one answer every 3 minutes :-(
http://jira.codehaus.org/browse/MRESOURCES-117
The latest released version (2.4.3) of the maven-resources-plugin is broken.
http://jira.codehaus.org/browse/MRESOURCES-104

Maven Java EE and module project pom

i am new to maven.
i have a Java EE Web project and a model project,web project is depend on model because module has some standard classed which need to be jar in web.
web needs model jar file.
how can i write the 2 projects which one is depend on another ?
give me a sample coding on both project pom.
A typical maven multi-modules project structure would involve 3 modules here: an aggregating parent module (allowing to start a multi-module build on all modules), the model module and the web module. Something like this:
.
├── mymodule
│   ├── pom.xml
│   └── src
│   ├── main
│   │   ├── java
│   │   └── resources
│   └── test
│   ├── java
│   └── resources
├── mywebapp
│   ├── pom.xml
│   └── src
│   └── main
│   ├── resources
│   └── webapp
│   ├── index.jsp
│   └── WEB-INF
│   └── web.xml
└── pom.xml
Where the parent pom.xml (at the root) would be like this:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>Q4176120</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Q4176120 - Parent POM</name>
<url>http://maven.apache.org</url>
<dependencies>
...
</dependencies>
<modules>
<module>mywebapp</module>
<module>mymodule</module>
</modules>
</project>
The mymodule/pom.xml would be a regular POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>Q4176120</artifactId>
<groupId>com.stackoverflow</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<!--groupId>com.stackoverflow</groupId--> <!-- inherited -->
<artifactId>mymodule</artifactId>
<packaging>jar</packaging>
<name>Q4176120 - Module</name>
<dependencies>
...
</dependencies>
</project>
And mywebapp/pom.xml would declare a dependency on the mymodule artifact:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>Q4176120</artifactId>
<groupId>com.stackoverflow</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<!--groupId>com.stackoverflow</groupId--> <!-- inherited -->
<artifactId>mywebapp</artifactId>
<packaging>war</packaging>
<name>Q4176120 - Maven Webapp</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mymodule</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<finalName>Q4176120</finalName>
</build>
</project>
With this structure, you can start a multi-modules build from the parent directory i.e. run a goal on all modules (and maven will calculate the right build order):
$ mvn install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Q4176120 Parent POM
[INFO] Q4176120 Module
[INFO] Q4176120 Maven Webapp
[INFO]
...
Note that I also used inheritance in the above samples (mymodule and mywebapp inherit from a parent that is declared in the <parent> element) so that I can group common parts in a parent POM and avoid repeating things. This is not mandatory, you can use aggregation without inheritance but this is very handy and aggregation and inheritance often go together in practice.
Resources
Maven Documentation
Project Inheritance vs Project Aggregation
Maven Book
3.6.2. Multi-module vs. Inheritance
You create 2 maven projects: web project and jar project. web project will depend on the model project. So you will add the model project as a dependency in the web projects pom.xml
I suggest you read maven basics here: http://www.sonatype.com/books/maven-book/
You model project pom.xml might look like this
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.abc</groupId>
<artifactId>>model-module</artifactId>
<name>My Model Module</name>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
Your web app pom.xml might look like this. notice the dependencies section
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.abc</groupId>
<artifactId>>my-web-app</artifactId>
<name>My First Web Application</name>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.abc</groupId>
<artifactId>model-module</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>