Maven Settings

So there are so many settings that get set before running a Maven build that it gets crazy.  There was a Confluence wiki that I used as part of Codehause (before they closed their doors) that I referenced a bunch when I was doing hard-core Maven plugin development that was extremely helpful.  You see, there are a bunch of ways that you can get the maven properties, but each of them requires setting up something in your project or running some odd command – but all I want is a simple reference.  So, I looked at this confluence site (which can still be found here, at least for the short term future) and compiled a list of very useful properties that everyone should have at their fingertips.  That way, whether you are setting up a project or doing plugin development, you can hit this reference.

Understanding Where The Properties Come From

First though, I’d like to cover the several ways that these properties are set.  Some are clear, some are not so much.

Maven loads up the XML files into Java Objects, and provides them for Maven plugins and the developer to use.  These XML files include pom.xml files, parent pom.xml files, as well as the settings.xml (and occasionally security-settings.xml, but I won’t cover that too much here).  The hierarchy can be a bit hard to follow for the uninitiated, but remember that all properties are resolved and then inherited (IN THAT ORDER) and the inheritance works in the way that pom.xml > parent pom.xml > settings.xml.  Or, a better way to think of it is that the most specific one wins.  Also, just in case it wasn’t clear, this is all case-sensitive, so “MyProgram” and “myprogram” are two separate variables.

When you want to access a variable, you just use the Ant model of variable replacement, which is the following: “${var_name}”.  This will evaluate the var_name and resolve it as part of your maven build.

Continue reading

My New Favorite Toys

OK, I’m going to admit it.  I tend to get really excited about Configuration Management (CM) type work and I have no idea why.  This is one of those.

Machine Images/Virtual Machines

Ok, these have been around.  If you don’t know what a machine image is, then stop and go download Oracle’s VirtualBox, because it is something that everyone should know.  These were revolutionary when they first were introduced.   So much so that most Operating Systems support some form of images (disk or machine) right out of the box.  Especially because a number of companies, including VMWare and Parallels, found out that they could manage your hardware better than the Operating System (which was originally supposed to do just that, but has really turned into something much more complex and more like a user interface). So, it turned out that if you used machine images, you could have a snapshot to a point in time. Sure, it still required some configuration after getting it going, but after that, it was cake. IT departments (and Dell/Norton, with their Ghost Image partition) were loving it. It really cut the mind-numbing monotony of setting up new boxes.

Puppet and Chef

Essentially, Puppet and Chef do the same thing.  Both start on the assumption that you have a base image installed on your box. Both represent a language that gives you the ability to install the software, users, and whatever else is necessary on a box to have it ready for tasking.  Both have claimed to support all major OS options.  This way, you could install the same users on the Windows boxes and Unix boxes in one script!  Of course the multiplatform argument is crap, but it still is a great option to finish what Machine Images started.

Take passwords for example.  Each OS handles this so completely differently that you would have to create a different module for the password for each OS.  Too much hassle.  Most companies are going to pick an OS and stick with it.  Heck, most are going to pick the same hardware too. This is the suggested use for almost all companies anyways.  Google, Yahoo, Amazon, etc. all use proprietary hardware.  But it’s THE SAME proprietary hardware.  Every machine has the same specifications.  (If you want, check out the Google server machines or the data center).  And I’m guessing most of them aren’t Windows boxes.  Just sayin’.

So, you create a new machine configuration for each type of machine.  One for your Web servers, one for the database servers, etc. Makes scripting all boxes that you might want to make really easy. Plus, in a cloud environment, like Amazon EC2 or privately held HDFS clusters, this makes setting up servers a breeze.

The difference between Puppet and Chef is their target audience.  Although they are technically competing products, both companies have pretty much stated that their real competition is the rats net of batch/shell scripts that you’ve probably written, or even better yet the documented instructions like the following.  We’ve all written these before.  And they even sometimes work.  Sometimes. Continue reading

Groovy Scripting or Gradle – check if binding variable (or Gradle property) is defined

In scripting, its helpful to create global variables.  It’s definitely not a good idea for any form of scalability, obviously, but Groovy has done a good job in creating this slight separation of function.

The difference is that the following won’t work:

but the following will work:

This can cause some problems in scripting if you need to either provide default values or if you need it to provide a better exception if the variable isn’t found. Continue reading

Making the Maven Version and Subversion Version Match

Let me start this out – this is strongly discouraged. Not only by me, but by Maven and any standards that you will ever come across. Your release version should almost never be your SCM version. Some tools allow you to pull in the SCM version as a variable and use it as a maven variable. This is great, because you can inject it into places to tie your release version to your project. Note the difference. I even wrote a great article about injecting variables into WAR files here and you can use the buildnumber plugin to inject your build numbers!

But, some groups (we’ll just nickname them “Oogle” for now) are being annoying and don’t want to do full blown releases, as that might mean that they have to support old releases. I totally understand that principle, so I’m not going to knock it. But, if you don’t have a release, how does one differentiate between versions?

Well, at this mythical company Oogle, they have stated you should use their subversion revision as the way to refer to their releases. Well, we can do that, but God help us if you switch to Git or some other form of DVCS. One thing about release numbers is that they should be sequential, so that you know which version precedes another, and human readable. In many of the new DVCS flavors, they use the SHA-1 hash, which is some long string of numbers and letters that is not sequential, nor human readable. But, for now, we can work with Subversion. Continue reading

Using Maven to Package JavaScript Library

Hopefully, the article about using JavaScript libraries should have swayed you should use Maven or some other repository to disseminate your libraries. But now you’ve hit a point that you have found a library that doesn’t exists in any Maven Repository (at least not ones that you have access to). What to do now? No worries. Publishing an artifact is easy.

First, assuming your code is in the location ${basedir}/src/main/javascript, create a file in ${basedir}/src/main/resources called “assembly.xml”. This file should contain the following:

This file will tell the assembly plugin how to package (into a zip, gzip-tarball, and bzip2-tarball) and what to include (“*”, or everything – you can include only specific things or exclude specific things. Please see the Assembly Plugin for more information about configuring includes/excludes). Continue reading

How to use a Maven JavaScript Dependency

Using a Maven Repository to handle your dependencies is just a good idea. This is what it does best. Due to the central repository idea, many other build tools have copied it. Arguably, some would say they have improved upon it as well, but the idea is the same. Ivy (for Ant) , Buildr, and Gradle, for example, use the same artifacts that Maven does. Node Package Modules(npm) is another form for direct JavaScript inclusion, though it requires that you are tied into Node.js. It’s probably a good idea to publish to npm as well for a JavaScript dependency, but I’ll have to post another article on that later.

So if you take away anything, it is that setting up a standard for your dependency is a good idea. It allows people to easily just add a couple of lines and they are using your library without a problem. The reasons are these:

  1. You are able to guarantee that no one has gone in and fiddled with the library that you’ve downloaded (yes – it has happened to me in production, which causes a licensing nightmare for some products, especially if the Junior developer wasn’t smart enough to know that you can’t just change someone else’s files without adjusting the licenses.)
  2. Design by extension is the correct way to develop anyways. If you want to change their code, take a class that they are using and wrap it to do what you want. That way, when the version changes and you upgrade, you still have the changes. Looking at #1 – if one developer has made this change and then the team is required to upgrade the library, things will start breaking and you won’t know why.

So most people will be with me at this point, but if you ask them how to do it, they are now going to stop and say “Wait… isn’t Maven for Java?” My response is a simple “No.” It was built originally with Java in mind, and has heavy adoptance in the Java world and the plugins are written in Java, but Maven itself is actually language agnostic. For example, if you want to use Maven for C/C++, I would suggest using the Nar Plugin or if you want to use like to use Google’s Closure Tools, I suggest using the Closure JavaScriptFramework or if you want to compile with Dalvik down to and Android app, you can use the Maven Android plugin. You get the general idea. It can handle quite a bit, once you know what you are doing. Continue reading

Maven WAR Filtering

So it looks like you can adjust your war plugin to use filtering, as such:

This will automatically scan your deployment discriptors, including web.xml.

 

So we put the following in a web.xml:

At which point you can use this in your JSP:

This will then resolve in any jsp page you have, and you can just use the “apiVersion” variable in any way you want.