Showing posts with label versioning. Show all posts
Showing posts with label versioning. Show all posts

Thursday, March 12, 2009

Letting Maven use local libraries

Sometimes it is useful to have Maven use some JARs that are checked in with the project, e.g. since you don't trust anything else or you just can't find a library in an existing repository and don't want to run your own.

It actually turns out to be pretty easy. Add something like this to your pom.xml:


<repository>
<id>local</id>
<name>Local repository in project tree</name>
<url>file:${basedir}/lib</url>
</repository>


Afterwards Maven will try to find a repository in the "lib" folder in your project. Let's assume you want this dependency in the local repository (hopefully something with better chosen IDs, but I decided to keep an existing pattern here):


<dependency>
<groupId>owlapi</groupId>
<artifactId>owlapi</artifactId>
<version>2.2.0</version>
</dependency>


What you need for this is a folder structure representing those three bits of information: groupId, artifactId and version (in that order), i.e. lib/owlapi/owlapi/2.2.0. In that folder Maven expects at least four things: the JAR file, a matching POM file and the SHA1 sums for both. All files are named using the artifactId and the version, i.e. "owlapi-2.2.0.jar" for the JAR, the same for the POM but with the different extension.

To get the SHA1 sums you can do this (assuming you run bash and have the sha1sum tool available):


for file in `ls`; do sha1sum $file > $file.sha1; done


If you are nice and add the sources (has to be a JAR with "-sources" in the name), then the result looks something like this:



The POM itself just contains the basic description (and possible dependencies):


<project>
<modelVersion>4.0.0</modelVersion>
<groupId>owlapi</groupId>
<artifactId>owlapi</artifactId>
<packaging>jar</packaging>
<name>OWLAPI</name>
<version>2.2.0</version>
<url>http://owlapi.sourceforge.net/</url>
<description>Java interface and implementation for the Web Ontology Language OWL</description>
<licenses>
<license>
<name>GNU Lesser General Public License, Version 3</name>
<url>http://www.gnu.org/licenses/lgpl-3.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>http://sourceforge.net/svn/?group_id=90989</url>
</scm>
<dependencies>
</dependencies>
</project>


That's all there is -- next time you run Maven it should "download" the files from that location. Considering that the POM also provides a uniform way of storing licence, source and version information it is actually a quite useful approach for storing dependencies inside your project's space.

Wednesday, February 25, 2009

Using fake query parameters to identify resource versions

When setting the cache expiry headers to somewhere in the far future as to make browsers not hit your server again for a long time (practically forever), you need some way to get the browser to newer versions of your otherwise static files. So far I have used a pattern containing the version of the artifact as part of the path:

http://my.server/js/lib/v123/lib.js

I just noticed the Sonatype repository using a different scheme, which is more like this:

http://my.server/js/lib/lib.js?v123

The version number is stored in a query parameter in this scheme. I assume that this parameter is actually ignored as most webservers would do with static content.

The advantages I see in this approach are:
  • updates can be done in-place (easier deployment, no need to keep multiple copies around)
  • the target doesn't even have to be aware of the scheme
  • the client could even go as far as generating a URL based on its revision, causing a retrieval for each of its upgrades, which would be too much but very safe
Disadvantages I see:
  • any reference will always retrieve the newest version (which could break things subtly if for some reason old references are still around somewhere)
  • (related to the one above) it's just not a proper URI since it identifies a resource with the query parameter (unless you consider the resource as spanning all versions and the versions different representations of it)
  • I don't know if I trust all caches to handle the query part properly (I never even looked into that)
It's an interesting approach and I can see it being a lot easier to manage than having distinct directories for each version. It somehow doesn't feel right, though.