Aug 22

Maven javap Plugin

Builds, Java No Comments »

Javap is one of those utils that gets installed with Java, that some never find. Javap is helpful for poking around in bytecode found in the classpath.

One of the ways I use javap is to just find out if a certain class is in my CLASSPATH (as well as learning about the methods etc).

As soon as you are in a real build environment, you need to make sure that a class is in the CLASSPATH that your build is working on.

Since I spend time in Maven-land, I use a tiny little maven plugin which does the work to find out if a class is in the dependency list for a project:

maven -Dclass=java.lang.String javap

The bulk of the work looks kinda like this:

<goal name="javap:classpath:check" description="Check Classpath">
<fail message="Must set the 'class' variable. E.g. maven -Dclass=java.lang.String javap." unless="class"/>

<available property="class.found" classname="${class}" classpathref="maven.dependency.classpath"/>

<j:choose>
<j:when test="${class.found}">
<echo>Class Found: ${class}</echo>
</j:when>

<j:otherwise>
<echo>Class NOT Found: ${class}</echo>
</j:otherwise>
</j:choose>
</goal>

Download Maven Javap Plugin

Jul 27

Why I like Maven: Commonality and Variability

Builds, Tech 7 Comments »

I realised another reason why I enjoy using Maven the other day.

Let’s start from the beginning….

I often have my build self-contained, so I can run goals/targets to do everything:

% maven/ant dbstart

% maven/ant tomcat-start

% maven/ant redeploy

This way all of the properties are setup correctly for the given project. No futzing around making changes.

Over time we find useful, generic (common) goals that we reuse on each project.

I see this happen in two ways in the ant world (not that it has to be like this!):

  • Don’t even reuse the targets a lot
  • Copy ‘n paste reuse: Oh foo was useful in the last project lets copy it in here

Before you look around there are 4 versions of dbstart in 4 different projects.

Now, what if you are a good boy, and you abstract out the commonality into a seperate build.xml and you just include that, as you can now in ant 1.6?

You end up with scripts such as this jsp precompile that projects use (e.g. AppFuse).

What if fhanik changes his script? Bah, whatever.

Here’s where Maven comes in

I have created plugins such as maven-db-plugin, which abstract all of the database stuff into a nice module. Now I have db:start, db:stop, db:dump, db:populate, etc etc in one nice module.

When I start a new project, I simply declare this dependency and I am done. The variability comes in the various maven properties that I can set in my project (e.g. using mysql, the jdbc driver, the user/pass, etc). Maven 2 has even nice auto-plugin installation which makes this even cleaner!

The nice thing about this is that development on making the db plugin is seperate from the project. If I release a new version of the plugin that fixes a bug, or adds a feature, I have the option to use that version in any project with a simple dependency change.

I end up with a lot less dead code, and my build related files stay nice and small, as all of the commonality is elsewhere.

This may sound like a very simple thing, but I sure appreciate it!

Jul 07

% maven console

Builds No Comments »

I have recently had a few people on various projects yell “maven is slow!”. I haven’t thought that recently, probably because everything seems slow on the Mac ;)

However, if I know I am in for some solid coding, and will be running maven a lot, I bring up the maven console:

maven-console-cmd.jpg

I have been surprised at how many people using Maven didn’t know about the console.

Now you pay the JVM startup price once, and after running a goal, everything is nicely cached and JIT’d and everything else. Now your mavenisms will scream in comparison.w

May 03

Scripting Maven with Groovy

Builds, Groovy, Java, Tech 2 Comments »

Imagine Maven talking to Jelly talking to Ant talking to Groovy :)

Jeremy Rayner contributed a nice Groovy Ant task, which we can piggy back on in Maven.

Guillaume Laforge put in the magic to make sure that the Maven POM is injected into the scripting engine, so you can play with $pom:

<project default="groovy" xmlns:ant="jelly:ant">
<goal name="groovy">
<ant:taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="maven.dependency.classpath"/>
<ant:groovy>
println pom.eachPropertyName{ println it }
println pom.name
</ant:groovy>
</goal>
</project>

It would be cool to be able to <ant:groovy script=”….”/>, or to write tags IN Groovy itself.

Of course, with m2 we will be able to write plugins with Groovy (as well as BeanShell and the like).

Brett Porter also talked about his addition to Maven to support CVS/SVN as a Maven repository itself. I personally am fine with using a traditional repository, where the http://….. is a SVN view itself, but I do hear people asking for exactly what Brett has implemented. Kudos Brett for doing this even though you won’t be using it yourself!

Apr 12

Maven 2 on the right track…

Builds, Tech 2 Comments »

Matt Raible thinks that Maven 2 is looking good.

He says that he doesn’t like Maven 1, and from the entry it is due to:

  • Speed (on his Mac)
  • Transitive dependencies (lack off)
  • Local Jar Files????

I don’t notice the speed difference between maven and ant on my powerbook or DELL. Well, I do notice it if I do a full clean on a huge build. But that takes for ever on both :)

Maven 2 has transitive dependencies, which is really nice. However, apart from the initial painful setup, it hasn’t been THAT big a deal for me.

I don’t really get the local jar thing. I guess Matt could just go into maven.jar.override mode, but why you would wnat to checkin copies of jar files is beyond me. Whenever I do a search on someones computer and see 56 struts.jar files I cringe.

More power to you :)

Apr 08

Maven 2.0 Technology Preview Release

Builds, Java, Tech 11 Comments »

There has been a lot of talk on the release schedule of Maven in the past (remember people desperate for 1.0 final? :). Now we have people asking to see the new and improved Maven 2.0, and we have a tech preview release:

The first Maven 2.0 Technology Preview release is now out.

Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.

http://maven.apache.org/maven2/

We’re looking forward to hearing your feedback, ideas, and (to a lesser extent :) bug reports.

If you need help with the release, please consult the documentation frequently as we continue to update it, and subscribe to the users@maven.apache.org mailing list. For more information, please see http://maven.apache.org/maven2/about.html#get-help

We welcome contributors to the Maven project – if you are interested in helping out, please get involved!

Thanks to everyone who has worked on this release!

– The Apache Maven Team

Features

Maven 2.0 has the following major features:

  • Simple project setup that follows best practices – get a new project or module started in seconds
  • Consistent usage across all projects means no ramp up time for new developers coming onto a project
  • Superior dependency management including automatic updating, dependency closures (also known as transitive dependencies)
  • Able to easily work with multiple projects at a time
  • A large and growing repository of libraries and metadata to use out of the box, and arrangements in place
    with the largest Open Source projects for real-time availability of their latest releases
  • Extensible, with the ability to easily write plugins in Java or other scripting languages
  • Instant access to new features with little or no extra configuration

The following features are available in Maven 1.0 and will be available and much improved in Maven 2.0 through the coming releases:

  • Deployment and release management
  • Comprehensive project information and reporting
  • Website and documentation building tools

On the reasons/goals

You’ve seen above the goals that Maven aims to achieve, however there have also been questions about why Maven 2.0 is rewritten from the successful Maven 1.0. In summary, the main goals of the new Maven 2.0 architecture are:

  • To be simple to use – it should be more obvious and consistent about how things are working
  • Fast – a new architecture and smaller memory footprint make it as fast as possible
  • To be able to implement the features demanded that were not possible under the Maven 1.0 architecture

Unfortunately, to reach these goals – we’ve had to sacrifice backwards compatibility to do this. Instead of making many small incremental changes that would break compatibility often over time, we decided to build on a new, solid base that can be reliable for the future, and also to maintain the existing Maven 1.x product to ensure that existing users are not left out in the cold.

Mar 15

Using Maven to modularize JavaScript development

Ajax, Builds, JavaScript 1 Comment »

A lot of developers ‘poo poo’ any code that is written in JavaScript.

  • “JavaScript isn’t a real programming language”
  • “JavaScript is just about browser hacker scripts”
  • “You can use it to focus(). Big deal.”
  • “JavaScript is for the HTML designers, not for REAL coders”

Giving thought to your JavaScript code

As such, any JavaScript code in a project, doesn’t get the thought that it deserves. Why would you be anal about unit testing your Java code, and ignoring your JavaScript code?

You no longer need too, as we have JsUnit, and other tools.

Dependencies are dependencies

As soon as you stop thinking of your JavaScript code as a bastard step-child, you can apply the same practices that we have in our other worlds (e.g. Java).

One of the problems with Java web applications, is that you can often do a search for files on a developers hard drive, and see MANY of the same files.

For example, you search for struts.jar, and there are 23 instances of it on the file system. Of course, they are not all the same size, since they are various versions (but you don’t know).

We get around that problem by using a tool such as Maven, or Ivy.

Now, we can define our project dependencies, and the correct versions are tracked, and downloaded automatically. Very nice.

WEB-INF/lib == /scripts

Why don’t we do this with JavaScript code? We have the same problem with commonscript.js as we do with struts.jar. So why not manage it?

Maven JS type

Maven has the base framework that we need to make this quite trivial. First, we can just agree on the ‘type’ of dependency. I am using js. Then you can just add dependencies as per normal:

<dependency>
<groupId>adigio</groupId>
<artifactId>xhr-test</artifactId>
<version>0.1</version>
<type>js</type>
</dependency>

This means that maven will try to grab:

/[groupId]/[type]s/[artifactId]-[version].[type]

or in the example above:

/adigio/jss/xhr-text-0.1.js

from the various repositories that you have setup in your project.properties:

maven.repo.remote=http://adigio.com/maven,http://www.ibiblio.org/maven,http://www.codeczar.com/maven,http://xdoclet.sourceforge.net/repository,http://dist.codehaus.org

NOTE: ‘[type]s’ is hard-coded. There is no way to map “when you see type ‘js’ look in directory ’scripts’, or something like that. This means that ‘jss’ looks a lil’ silly :).

maven-war-javascript

So, we didn’t have to do anything to get Maven to start grabbing dependencies for us. But, in our projects we don’t just want to grab some JavaScript modules and put them in your local repository. We want to use them :)

Rather than writing some manual goals to handle this, I wrote a Maven plugin which piggy-backs on the war plugin.

The maven-war-javascript-plugin offers a war:js / war:js:copy-scripts goal. This manually looks through your dependencies, and copies any JavaScript modules to your web app (in the scripts directory by default. To change, use the maven.war.javascript.dir property).

However, although you have a goal in which you can kick off this task, in practice you don’t need to use it. The plugin registers itself with the war module, and whenever it is invoked, it sneaks in and does the copy. So, it is a seemless introduction!

Installation

To download and install the plugin, you can simply:

  • Add: http://www.adigio.com/maven to maven.repo.remote
  • Run the commmand: % maven -DartifactId=maven-war-javascript-plugin -DgroupId=adigio -Dversion=0.1 plugin:download

Conclusion

So, now I can take JavaScript more seriously, and can start managing my JS dependencies with the care and loving touch that I do with the immense amount of open source library bloat :)

From Ajaxian.com

Mar 10

RE: Ivy is everything Maven should be

Builds, Tech 198 Comments »

Colin Sampaleanu claims that Ivy is everything Maven should have/could have been 2.5 years ago.

While I understand where he is coming from, and I think Ivy is a nice piece of software, I have to stand up for Maven again.

Even though, I know that I will get bashed for it.

Handling dependencies is a very nice thing. And, having transitive closures on those dependencies is going to be great to have in m2.

However, this isn’t the only part of a build, nor of Maven. Maven is my build container. It takes care of so much that I don’t have to worry about, and I haven’t had to get deep into Jelly code, like others have expressed.

m2 is not going to come rushing out there, and you can’t blame the authors! They are going to learn from their mistakes, and my guess is that when m2 finally does rear its head, we will be impressed.

Also, in related news, Vincent Massol is writing a Maven book for O’Reilly.

disclaimer: just because I have had a good experience with Maven does not mean that I am trying to ram it down YOUR throats, and I understand if you don’t chose to use it :)

Feb 25

First Video Game Written In Ant

Builds No Comments »

Jon Aquino has started a new craze. The last two JavaOne’s have had Vodafone telling us “write video games for mobile phones and you will make millions!!!”.

Maybe this year we will be told to write Ant video games! :)

Fair play to Jon for showing that this is possible. The one, practical, take away point is that you can check out the new macrodef functionality in Ant 1.6, and the Ant Contrib library which gives you the if/then/else/for/.... tags and more.

<macrodef name="check-crash">
<sequential>
<if><islessthan arg1="${left-clearance}" arg2="0"/>
<then><die/></then></if>
<if><islessthan arg1="${right-clearance}" arg2="0"/>
<then><die/></then></if>
</sequential>
</macrodef>
Feb 10

Maven: Extension Points in your Build System

Builds, Tech 54 Comments »

Maven gets a lot of flack. Hani enjoy’s making fun of it. I even joked about it a little via:

All I wanted was a jar and I got a website

However, the more I get to play with it, the more I like it. And, it sure beats the alternatives :)

One side effect that I have noticed is that it allows me to have clearly defined extension points in my build. And, even more importantly, it allows me to NOT think about every extension point when designing my projects build.

When using Ant, I always found myself spending time really thinking about the dependencies.

Hmm, shall I have this general build target depend on a customer dion-build which I can later override and do cool stuff in sub-projects?

I found that I ended up with a bunch of:

<target …. if=”some.magic.property”>

In my Maven projects, I don’t seem to need any of this. Why don’t I?

I think it stems from:

  • The Plugins: I try really hard to rely on plugins to do the work for me. First, I try to follow their defaults. Second, I tweak their properties to give me some flexibility if needed. Only as a TRUE last resort do I look to hack the maven.xml. I find that it is rare to get to the last resort.
  • pre/postGoal: A lot of the good plugins have nice extension points. You can almost setup base goals which are NO-OPs, which you can later extend by implementing your own. However, even if this doesn’t exist, via pre/postGoal settings, you can extend anything!

Being able to extend anything with a pre/postGoal has proven to be very productive. What I really like about it, is that you don’t have any coupling between the original goal, and the extension mechanism.

For example, if you want to extend the java:compile goal to do something else, you can preGoal it to have the extension, say generating some other source code before the compile step. Note that we are not having to tweak the original goal at all. There is no coupling here. Maybe this is a personal preference, but that feels much cleaner than piecing together the puzzle via depends=”".