tag:blogger.com,1999:blog-54508017454573004012024-03-12T18:48:27.279-07:00Mavenize your developmentGet going with the Maven 2 platform... It will halp projects!robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comBlogger41125tag:blogger.com,1999:blog-5450801745457300401.post-9944920384919615782009-09-30T11:16:00.000-07:002009-09-30T11:23:11.304-07:00Building a Site and using PropertiesWhen building a site in Maven you are likely to want to use custom properties, such as the version #, artifact/group ids and so forth. This isn't as easy as it should be. First you'll need to attach an extra '.vm' to the end of any apt, fml file that you want to be filtered. Without this the ${property} references in these files will not be replaced with values.<br /><br />A word on the properties you'll use in these site template files. They may not have '.'s in them. That's right you can't have a property such as 'pom.version' in your templates. So instead you'll need to add properties that do not use this character.<br /><br /><pre><br /><properties><br /> <currentVersion>${pom.version}</currentVersion><br /><properties><br /></pre><br /><br />Then in your apt file you can now put in ${currentVersion} and it will resolve to the pom's version element value in the generated html file.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-86064373458840172322009-06-21T21:00:00.000-07:002010-05-18T16:48:48.153-07:00Authenticating When Using the SCM PluginIf you are using the SCM plugin with Mercurial then you will likely need to pass the username and password to it. This can be done with the following arguments to the mvn command:<br /><br />"-Dusername=<username> -Dpassword=<password>"<br /><br />You also can create a server element in your 'settings.xml' file (in ~/.m2) which has an id that matches the host part of the SCM url, then set the username/password in the respective elements. This'll keep you from having to put in the values on the command line again and again.<br /><pre><br /><server><br /> <id>www.blueleftistconstructor.com</id><br /> <username>rob</username><br /> <password>pass</password><br /></server><br /></pre><br />When using the release plugin I've always had to use this technique to 'push' the changeset from my local mercurial repo to the remote one.<br /><br />Note that one unfortunate side effect here is that the HG Maven plugin WILL OUTPUT YOUR CREDENTIALS IN CLEAR TEXT!!!<br /><br />This doesn't bother me all that much since I run a pretty tight ship, but if this violates your comfort level you may be out of luck as far as the release plugin goes.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-25334057927755954822008-12-20T22:54:00.000-08:002008-12-20T23:19:43.579-08:00Mercurial (HG) Source Control with MavenI've been using <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a> for quite some time now. I've also been back up to my old tricks. On switching jobs a while back I came back into using Maven. I've also been hacking up some projects with pals and we host them on my site <a href="https://www.blueleftistconstructor.com">blueleftistconstructor</a>. We found it would be easier to work on, distributed as we are, if we used Maven and created a Maven repository.<br /><br />Well these projects are under Mercurial source control. I won't go to much into why I use Mercurial, especially why I use it over git, darcs and so forth. Lets just say I suits me and my partners.<br /><br />So how easy is it to use Maven with Mercurial? Very easy it turns out. There was a little snag which I will get to later. First though you need to go get Mercurial. If you have a Mac you probably can just use <a href="http://peak.telecommunity.com/DevCenter/EasyInstall">easy_install</a>, which is likely already installed. Try this:<br /><blockquote>easy_install mercurial</blockquote>Using easy_install is my perferred method of installation. Otherwise download from the site.<br /><br />Once you have verified Mercurial installed you just need to go into your projects root folder and type 'hg init' and you'll see Mercurial taking care of adding needed files. Now you will want to use the 'hg add' command to add files into source control. Read the docs for more information on how you can 'ignore' files.<br /><br />Ok now we are ready to tell Maven that we are using HG to control. You will need to configure the scm section of your projects pom. It should look something like this:<br /><br /><pre><br /><scm><br /> <connection>scm:hg:https://www.blueleftistconstructor.com/hg/netflix-client</connection><br /> <developerConnection>scm:hg:https://www.blueleftistconstructor.com/hg/netflix-client</developerConnection><br /> <url>https://www.blueleftistconstructor.com/hg/netflix-client</url><br /></scm><br /></pre><br /><br />Note that you will have to replace the URLs above with your own. The 'connection' URL is a public accessible URL, while 'developerConnection' is not going to be read only. The 'url' is a source control browser such as ViewVC or Fisheye.<br /><br />Thats it. You now can use all sorts of Maven commands to manage source control actions. I myself don't often use these. The real benefit here is in releasing versions of your software. With the source control repo configured Maven takes care of committing, tagging, and rolling the version number up.<br /><br />For more on releasing a Maven project that is configured for source control <a href="http://mavenize.blogspot.com/2007/07/release-plugin.html">read this</a>, and <a href="http://mavenize.blogspot.com/2007/07/release-plugin-ry-run.html">this</a>.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-57036223382826877802008-04-21T08:57:00.000-07:002008-04-21T09:18:31.627-07:00Go west young manThis is (likely) my last post to this blog. I've spent the past 2 and a 1/2 years using Maven primarily in my Java projects and my companies. Part of this I think is just growing up. When I first started using Maven I had just started work at a company who's development team consisted of some novice Java users. It of course did not help then that a lot of the software they had was written in Java. Queue some of the ugliest Ant build files I have ever seen. These people obviously had never been exposed to C/C++ and make in an academic environment... as they would have been heckled for such lack of simplicity. These Ant build scripts just wouldn't fly for me. So I found Maven. I used it to simplify the build environment, for my co-workers and myself. I encountered problems while using Maven which I solved. I watched the community slowly build up. I started a blog and shared my knowledge. It was fun.<br /><br />I've progressed A LOT in the past two years. I am no longer a guy who is fresh out of college, smart but unprepared for nastiness which the enterprises of the world contain. I've honed my technique, worked on numerous projects (many more than the majority of people out of college for only a few years), and I have made honest appraisals of the things I have done. I'm at a point now where the expressivity of a tool such as Ant makes it much more viable than something like Maven. If Maven was Java, then Ant would be Python. I can do the same two things in both, but one is much easier to use (Python, duh).<br /><br />Other things that have pulled me away from Maven, and more specifically Maven's ideology, are tools such as Gant (Groovy language + Ant) and scripts in Pylons (Python web framework). Being able to use the full power of a language right there in a build file, is a beautiful and powerful thing. I also would argue this is daunting for the novice. I have come full circle from Ant to Maven and back to Ant. I'm now ready to work on projects where the full responsibility is mine in making sure the build files are clean, coherent and useful. I recognize now that this is not a lot of responsibility, that the fact my previous co-workers could not handle it speaks volumes for the type of organization they were running.<br /><br />Please drop a line if you have any questions about articles I've written here. You can reach me at mentalstasis. at. hotmail. com. I'm always interested in some convo with other computer professionals out there so don't hesitate. Thanks to all you readers out there, and best of luck.<br /><br />-Rob O.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-82810144286734596722008-01-20T19:39:00.000-08:002008-01-20T22:28:30.882-08:00Utilizing Maven Plugins: Jetty plugin<span style="font-weight:bold;">The problem:</span> You would like to use a non-standard Maven plugin, such as the Jetty plugin.<br /><br /><span style="font-weight:bold;">The solution:</span> First things first you will probably need to register the plugins group, so that Maven will know where to look. To do this you should put an entry in your settings.xml file. For our example here we will use the Jetty plugin. It has a group id of 'org.mortbay.jetty'. In your settings.xml file put an entry such as:<br /><br /><pluginGroups><br /> <pluginGroup>org.mortbay.jetty</pluginGroup><br /></pluginGroups><br /><br />What this little piece of configuration does is tell Maven to search for plugins registered under the given group id. You can have as many 'pluginGroup' elements in your xml file as you want/need. In all my work with Maven I have only actually registered two plugin groups, one of which is Jetty... but if you create your own you will need to register your plugin group.<br /><br />Lets start by creating a web application using a Maven archetype:<br /><br />mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp<br /><br />This will create a folder called 'my-webapp'. Change over to this directory. Now we are going to use the long way of specifying the plugin. This is ugly and you certainly will not want to use this form often (likely ever).<br /><br />mvn org.mortbay.jetty:maven-jetty-plugin:run<br /><br />You should now be able to hit your web app on http://localhost:8080. The above command could be broken down as 'mvn groupId:artifactId:goal'. More on this in a bit. Now lets run the same 'run' goal using a short command syntax. Here is a simpler way to do the same thing:<br /><br />mvn jetty:run<br /><br />Much easier. Now I'll explain a bit. Since we put the plugin group entry in our settings.xml file we do not need to specify it like we did in the long command above. In the long command, after the group id, we have 'maven-jetty-plugin'. Maven expects the artifact id to be in a form 'maven-<plugin name>-plugin'. For the Jetty plugin the artifact id is 'maven-jetty-plugin'. In the part after the colon in the long command we specify this artifact id. Now in the simple version we just have 'jetty'. Maven will take the 'jetty' value and automatically know to look for 'maven-jetty-plugin'. This saves you from typing out the whole shebang.<br /><br />If your are interested in creating your own plugin I suggest you check <a href="http://maven.apache.org/plugin-developers/index.html">this link out</a>. It is not nearly as hard as you may imagine.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-59354560581943777332008-01-11T00:09:00.000-08:002008-01-11T00:13:02.695-08:00Exercise: ContinuumToday's article is going to be a step by step on getting a pretty hefty Maven based project up and running on your machine. I will finish by having the project set up in Eclipse of better development. The project is Continuum. It is a continuous integration server created by the Maven community.<br /><br />We will start by checking out Continuum. Use this command to get the project from Subversion: <br /><br />svn checkout http://svn.apache.org/repos/asf/maven/continuum/trunk/ continuum<br /><br />Once you have the project downloaded 'cd' on over into it. Do a ls or dir command. You will now find you are looking at a multi-module Maven project! Egads thats a different sight in comparison to a non-multi-module project. Well lets kick things off by running:<br /><br />mvn install -Dmaven.test.skip<br /><br />We don't want to test, for now. You will need to run install so that each module's artifact (jar) gets put into your local repo. This is important because a module can rely on artifacts created by other modules, and so the artifacts must be available via repo. This will take a bit, Continuum is fairly big. Once things are done you will want to prep Continuum for Eclipse. Run the command:<br /><br />mvn eclipse:eclipse<br /><br />This will go into each module and create the Eclipse meta files, so that you can import them into Eclipse no problems.<br /><br />We now are at the last step. Open up Eclipse, right click in the 'package manager' view (window). Select 'import'. This pops up a window, select 'general > existing projects into workspace'. Point to the folder containing all the modules and click ok. You will notice Eclipse finds a project for each module. Click ok. After a bit of grunting Eclipse will present you will a view full of projects, one for each module.<br /><br />At this point you may need one last thing. If you do not have the M2_REPO Eclipse you will need to set it. Check the 'problems' view, if you see a bunch of messages about this not being set... bingo. Go into preferences then "java > build path > classpath" and add the var, giving it a value of the location of your local repo. Mine is "/home/ottaway/.m2/repository".robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-21384033866540143042007-12-20T23:23:00.000-08:002007-12-20T23:44:47.311-08:00Going Offline<span style="font-weight:bold;">The problem:</span> You want Maven to stop making all those network calls when you issue it commands like clean, build, test, package etc. You might want to work on a project while you have no network connection.<br /><br /><span style="font-weight:bold;">The solution:</span> You can use the off line mode for Maven to keep it from making any network calls. You can do so by issuing the -o flag to the mvn command. When using this mode Maven will need to have all the jars it needs in your local repository (~/.m2/repository by default). To make this easier you can use a trick provided by the dependency plugin. Imagine we just checked out a project. Now we want to work on this project off line. To get all the dependencies needed by the project you can issue the command "mvn dependency:go-offline". This will download the dependencies you need. Now note it will not make sure you have all the plugins you need. Say you want to run "mvn -o site:run", creating a site for your project and making it available via Jetty. You will need to have used this plugin before so that it is in your local repo. The same goes for compile, package, test and the like.<br /><br />The million dollar question is why use off line mode? Well it could be that it makes quicker the process you are doing with Maven, since Maven will not try to call out to any network repos. I've timed the difference between using it and not using it for some fairly large projects and found it doesn't make a huge difference. For really big projects (I cannot really name one) it might shed enough seconds to make it worth using often, maybe even creating an alias. This 'huge' project mind you would probably have upwards of 200 jar (dependencies) or more being managed. Another reason one might use off line is as follows: you have a local network repository used by the developers at work. One day the person you administers this repository is going to move it somewhere new. This going to take a few hours. Using off line mode you could weather this time if prepared without noticing too much that the repository is down. This could also be helpful in situations where you are going to not be able to reach the repository, like working at home with no network connection, or the server hosting the repo crashed.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-56244933593318722132007-12-16T21:42:00.001-08:002007-12-16T22:32:08.437-08:00Using Maven for Bash Script ProjectsI recently created a Maven project unlike any I have ever created. This project contained no Java sources! No it was not a Groovy project ;) It was a project that contained only bash scripts. Read up for the why and the how.<br /><br />I created a set of bash scripts that allow invoking SOAP services, returning the XML response. The SOAP services provide information on email distribution lists, such as which addresses are on a list and which lists a user's email address is subscribed to. These scripts are likely to change and grow over time so I made sure to put them into Subversion. Not too shabby. But what about distributing the scripts? What about managing versions of the scripts? I have become accustomed to having the aforementioned handled in my projects via Maven. Maven makes such things simple to set up and automate. I determined I could move these bash scripts into a Maven project to cultivate these benefits.<br /><br />Now the how. For packaging I use the Maven assembly plugin. It allows created automated creation of zip tar.gz and gzip archives. These archives work great work distributing a project. I started my work by creating a skeleton Maven project. I put the scripts and related files into the src/main/scripts folder of the project. Next I created a xml file used by the assembly plugin to direct how files will be structured in the created compressed archive or archives. Here my file:<br /><pre><br /><?xml version="1.0"?><br /><assembly><br /> <id>zimbrascripts</id><br /> <formats><br /> <format>zip</format><br /> </formats><br /> <includeBaseDirectory>false</includeBaseDirectory><br /> <dependencySets><br /> <dependencySet><br /> <outputDirectory>hacksdb/lib</outputDirectory><br /> </dependencySet><br /> </dependencySets><br /> <fileSets><br /> <fileSet><br /> <directory>src/main/scriptapp/bin</directory><br /> <outputDirectory>zimbrascripts/bin</outputDirectory><br /> <fileMode>0755</fileMode><br /> <directoryMode>0755</directoryMode><br /> </fileSet><br /> <fileSet><br /> <directory>src/main/scriptapp/etc</directory><br /> <outputDirectory>zimbrascripts/etc</outputDirectory><br /> <fileMode>0644</fileMode><br /> <directoryMode>0755</directoryMode><br /> </fileSet><br /> <fileSet><br /> <directory>src/main/scriptapp/tokens</directory><br /> <outputDirectory>zimbrascripts/tokens</outputDirectory><br /> <fileMode>0600</fileMode><br /> <directoryMode>0777</directoryMode><br /> </fileSet><br /> <fileSet><br /> <directory>src/main/scriptapp/xml</directory><br /> <outputDirectory>zimbrascripts/xml</outputDirectory><br /> <fileMode>0644</fileMode><br /> <directoryMode>0755</directoryMode><br /> </fileSet><br /> </fileSets><br /> <files><br /> <file><br /> <source>src/main/scriptapp/README.txt</source><br /> <outputDirectory>zimbrascripts</outputDirectory><br /> </file><br /> </files><br /></assembly><br /></pre><br />I'll write up a more thorough article on using the assembly plugin later. For now suffice to say this file will instruct Maven to create a zip archive containing the files listed above. The last thing we want to do is configure the assembly plugin in the project's POM file. I used the following XML in my projects pom:<br /><pre><br /><build><br /> <plugins><br /> <plugin><br /> <artifactId>maven-assembly-plugin</artifactId><br /> <configuration><br /> <descriptors><br /> <descriptor>src/main/assembly/assembly.xml</descriptor><br /> </descriptors><br /> </configuration><br /> <executions><br /> <execution><br /> <id>make</id><br /> <phase>package</phase><br /> <goals><br /> <goal>assembly</goal><br /> </goals><br /> </execution><br /> </executions><br /> </plugin><br /> </plugins><br /></build><br /></pre><br />In the above config I also bind the assembly goal to the package phase. This means when I execute "mvn package" the assembly plugin will fire off and create the zip archive. Nice! Otherwise you can also use "mvn assembly:assembly" should do the job. Now so that I could use the scm and release plugins to check in changes to SVN and create tagged releases of the project I added the following to the POM:<br /><pre><br /><scm><br /> <connection>scm:svn:https://svn.com/DistributionLists/DistListScriptsMaven/trunk/</connection><br /> <developerConnection>scm:svn:https://svn.com/DistributionLists/DistListScriptsMaven/trunk/</developerConnection><br /> <url>https://svn.com/DistributionLists/DistListScriptsMaven/</url><br /></scm><br /></pre> <br />Now to release the current version of the project I can type "mvn release:prepare". This will tag the current version in SVN, then update the POM to the new version number and check those changes into the SVN trunk. This saves me the hassle and reduces the chances of user error in this boring, repetitive process. In the vein of the SCM configuration you could now use other plugins such as the JIRA reporting plugin, site plugin etc. to bolster this simple bash script project.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-8171941363855213622007-12-01T08:10:00.000-08:002007-12-20T23:09:59.148-08:00Big Project Troubleshooting Pt. 1: Transitive DependenciesMaven is complex, but so is Ant or Make once a project passes a certain size. With Maven many things are done in a standard way, so that when a project becomes large you still should be able to work with it easily. With Ant or Make a large project will likely have many arbitrarily named targets which you will have to study and learn. With Maven all those named targets are pretty much standardized by the plugins which provide all functionality. Large projects in Maven commonly have the same sorts of issues. These can be pretty nasty to for the uninitiated. So to help you out I'm going to write a series of articles tackling the problems faced in big Maven projects. In this article I'm going to give you some information on issues related to dependencies.<br /><br />The dependency mechanism is the main reason many people become interested in Maven. It sure makes life easy... but everything cannot always be automated. Sometimes you will need to give Maven some help. It will try to correctly resolve the dependencies needed by your project by creating a graph. More on this in a second.<br /><br />Maven has what is called a 'transitive dependency'. Let me explain transitive dependencies for those who don't know. A dependency of a project is defined via a project's pom.xml. Every dependency has a pom.xml (in the repository with the dependency) which is used by Maven to find the dependencies relied upon by a dependency. These 'relied upon' dependencies are also known as transitive dependencies. They are included into your projects class path automatically. Now you can have any number of levels of transitive dependencies because Maven also will get the each transitive dependency's dependencies. In Maven this forms what is called the dependency graph. Yes this is the same graph I spoke of earlier. It looks like a tree, with your project as the root node, tree level one as the dependencies of your project and subsequent levels being transitive dependencies.<br /><br />Now lets talk about the sticky points. If there are two or more versions of the same dependency in the graph of the dependencies for your project then Maven will need to make a choice as to which one to use. By default Maven will use the version that is the closest to the top node of the tree. If this version is older than the other version(s) you may have a problem. Likely a NoClassDef where a class from the new dependency cannot be found, because it does not exist in the older version. When you get this error it should be obvious which dependency the error is being caused by. The stack trace should give the full package path to the class. We can use this to figure out how to fix the problem.<br /><br />At this time you probably could open a terminal session and cd to your local repository location (~/.m2/repository by default) and then cd into the dependency's folder in the repository. This can be helpful since it will allow you to see which versions of the dependency are being used and which classes are in each dependency. You could execute a "jar -tf {jarname} | grep {ClassName}" command on each jar to search it for the given class. <br /><br />Let us discuss troubleshooting. First you will want to run the mvn dependency:resolve command. This will print out a listing of the resolved dependencies for your project. Resolved dependencies are those calculated by Maven via the dependency graph to be used in the project. You should be able to see which version of the troubled dependency is being used. I had you cd to the dependencies repo location. Check now which versions you have in your repository. You should be able to use the "jar -tf <jarname>" command to check if the class causing the NoClassDef exists in one of the newer version jars (if you have newer version jars). Once you have found a jar that contains the class make note of the version.<br /><br />Now for some debugging. This is where you get waist deep in it. We are going to use the -X option to Maven, which enables debugging. We also want to run just the compile phase which will give us all the info we need on the dependency graph. You might want to do something like "mvn -X compiler:compile > junk.txt" just so that you can use a text editor like Vi to search about the file. Now when you view this output you will be able to find a listing of the absolute classpath, including with jars are being used. You also will get a printout of the dependency graph including info on what ended up making it in. It is pretty easy to find the version of a dependency being used: find the one with the least amount of indent. If one or more versions share the least amount of indent then the newest version will be selected. <br /><br />To get around version problems you can do a number of things. The easiest thing to do is define the newer version of the dependency directly in the pom.xml of the project. This will make sure that the newer version is used because it is 1) at the top of the dependency tree 2) the version is highest. You can also use excludes for a dependency definition in the pom.xml file for the old version of the dependency. Since the old version is excluded the newer (yet further down the graph) version will be used. When using excludes you will need to figure out which dependency in the pom.xml file has the transitive dependency to be excluded. Neither of these fixes are tough to perform, and will become easy to do in time.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-34116330294685030332007-10-04T22:18:00.000-07:002007-10-04T22:53:23.515-07:00Maven Theory: ArchetypesMaven is a complex system to swallow in its entirety. Most persons first encounter it because they want to wield the dependency magic it offers. These persons are not savvy to the notion of repositories and with them the administrative work required to build and manage them. They are not likely to understand that Maven can build complex websites, containing useful reports on project health, with little configuration and user effort. These are things that Maven accomplishes in a very elegant manor (in my opinion). You see Maven 2 was built almost from scratch, using the knowledge gained in the creation of the original Maven. Hence a sound architecture was built in Maven 2 that has proven adaptable to many tasks.<br /><br />In this post I want to talk more about one of the extension points of Maven 2. Archetypes. These are a lot like templates. When invoked an archetype will either create a new project, or add to an existing one. Archetypes can be created by an end user and deployed into a repository. This allows others to access the archetype and reuse it. A little while back I was doing a fair bit of SOAP service programming. I was using <a href="http://xfire.codehaus.org/">XFire</a> in the creation of these projects, along with other Java technologies. After the first couple projects I decided creating an archetype for XFire projects would be handy. So I created an archetype project that could generate a bare bones Maven 2 project. This project would contain a pom with all the needed dependencies, and a simple "Hello World" SOAP service and an integration test. Now whenever I wanted to create a new XFire project I would just invoke this archetype; giving me a good head start! Now I would like to point out that, if you are like me, you would normally just find the 'similar' project then copy and paste. Then you trim down the copy or whatever. That is a viable alternative, although I feel one is better off with a nearly clean canvas when striking out on a project.<br /><br />So now that I have talked your ear off, let me give an example of using a real archetype to generate a full project. The base Maven has an archetype for creating Maven projects. Seems reasonable eh? So to create your next computational masterpiece start with the command:<br /><blockquote>mvn archetype:create -DgroupId=com.someguy -DartifactId=masterpiece</blockquote>And tadah you now have a folder called 'masterpiece' which contains a very basic Maven 2 project. There are other archetypes you can run with out any special setup, including an archetype to create archtypes! Now I'm not advocating creating an archetype as a precursor to any new project. Create one whenever you start to notice a pattern between projects. A good candidate for me was Spring, Hibernate and other dependencies I used very often in web projects. I created a simple archetype to create a bare bones web MVC application using these dependencies. With this I could start creating the controllers and .jsp pages in my application right away, rather than mucking around copying some old ant project :)<br /><br />I will write up some better examples on archetypes down the road. I would like to give an example of creating a simple archetype. Keep tuned in for more, and do not hesitate to leave a comment or contact with ideas.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-35218015525241680712007-09-03T17:18:00.000-07:002007-09-03T17:45:03.755-07:00Bootstrap When Using Pom Inheritance<span style="font-weight: bold;">The problem:</span><br /><br />Parent pom files can allow you to standardize many projects. Project maintenance tasks such as updating shared attributes like repository locations is easy. You can also define things like how tests are run, reports to generate and more.<br /><br />When using a parent pom it must be accessible from one of your defined Maven repositories, but... often times the parent pom contains your repository definitions. When you clean your local repository (removing the parent pom locally) you will no longer have defined repository locations. You will therefore not be able to download the parent pom (if installed in a network accessible repository), and not be able to build projects that inherit from this pom.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />It is common to have a company/organization repository that will contain any parent poms used in inheritance of projects. When you need to get one of these parent poms you will need access to this repository. That means you will need to define the repository. There are a number of ways to do this: put a definition in your projects pom (cold), put a definition in your settings.xml (getting warmer). Neither of these are that great.<br /><br />Putting the repository information into the project makes for crappy upkeep. Think, if you have 10 projects with poms that contain repository definitions, and the repositories move, you need to update all those files with the new information. Therefore do not put (unless you are using Maven small scale...).<br /><br />Don't just put the repository definition into the settings.xml file either. If you do this every time you run Maven this repository will be searched for artifacts. It is much cleaner to define the repository in a profile, in your settings.xml file.<br /><br />Why use a profile? Profiles allow you to enable certain features when needed. In our case we want to activate the parent pom repository definition. So first you need some xml in your pom like so:<br /><pre><br /><profiles><br /> <profile><br /> <id>bootstrap</id><br /> <repositories><br /> <repository><br /> <id>parent</id><br /> <name>Maven repository -- bootstrap</name><br /> <url>http://abc.com/mvn2</url><br /> </repository><br /> </repositories><br /> </profile><br /></profiles><br /></pre><br />This piece of gold will let Maven search the given repository when needed. To activate this you would put the string "-Pbootstrap" in with the Maven command you are executing. How about an example?<br /><blockquote>mvn -Pbootstrap clean package</blockquote>Once you have run this command once the parent pom should be downloaded locally, so you will not need to run activate the bootstrap profile very often.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-64448751905190079772007-07-02T15:24:00.000-07:002007-08-05T20:34:01.362-07:00Setting Command Line Arguments for JVM in Maven<span style="font-weight: bold;">The problem:</span><br /><br />You want to set JVM args for the Maven application (such heap memory).<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />On a Linux/Unix machine the "mvn" command will use a shell variable "MAVEN_OPTS" to pass in options. This is useful if you want to give Maven more memory. In your .profile or .bash_profile put a line like this in:<br /><blockquote>export MAVEN_OPTS=-Xmx1024m</blockquote>Now every time you run "mvn" you will have up to 1024 megs of heap space! Use this to set other JVM arguments.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-72544231023401164082007-07-02T14:27:00.001-07:002007-08-05T20:21:14.599-07:00SCM control<span style="font-weight: bold;">The problem:</span><br /><br />You would like to integrate your source control management directly into a Maven 2 project.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />Source control is needed to maintain the health of any mid to large size project. Maven knows this! Maven has very broad source control management support. Have you heard of <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a>? Well you can integrate Mercurial SCM support right into a Maven 2 project. Or Subversion, CVS, Perforce, etc. To get started is easy, you will need to configure an "scm" section in your projects pom.xml file. I will give an example:<br /><pre><scm><br /> <connection>scm:svn:https://svn.oreilly.com/RobUtils/trunk</connection><br /> <developerConnection>scm:svn:https://svn.oreilly.com/RobUtils/trunk</developerConnection><br /> <url>https://svn.oreilly.com/RobUtils</url><br /></scm></pre><br />Once you have configured your scm section other plug ins (such as release) will be able to leverage it's information. You should see the <a href="http://maven.apache.org/scm/">documentation on SCM</a> configuration to get up and running with your SCM implementation.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-84941484819686058702007-07-02T14:21:00.001-07:002009-12-19T17:49:27.207-08:00Run a specific test<span style="font-weight: bold;">The problem:</span><br /><br />You have a group of unit tests that you run through the Maven <a href="http://maven.apache.org/plugins/maven-surefire-plugin/">Surefire</a> plugin. You do not want Surefire to run all the tests, rather you want only one specific test to run.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />This one is easy, all you need to do is put a little something into your command to tell the Surefire plugin "run just this one test". What does this look like? Here is an example: "mvn -Dtest=FunTest package". Here you want to package your applicaiton, but you are going to run the FunTest first. Notice you don't put a ".java" or ".class" extension onto the name. Thats it, you can use the "-Dtest=..." to run a single test anytime that the Surefire plugin will be run.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-4625252886171262662007-07-02T14:20:00.001-07:002007-08-17T17:47:55.971-07:00Import Maven Project into Eclipse w/ Style (Maven + Eclipse pt. 3)<span style="font-weight: bold;">The problem:</span><br /><br />You have a Maven 2 project, and would like to work on it in Eclipse. Oh, and you want the Maven plug in for Eclipse configured on this project too!<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />The first thing I do when I check out a Maven project is generate the Eclipse project files. Start by going to the project's root folder and typing:<br /><blockquote>mvn eclipse:eclipse</blockquote><br />This will create the files Eclipse uses to understand the project, .project and .classpath. There are links to the jars configured via the pom in the .classpath file. You will want to get rid of these, because the Maven plug in will handle dependency configuration. Go into the .classpath file and delete all "classpathentry" nodes that have "M2_REPO" in the path attribute value. Now save this file.<br /><br />At this point your project should have errors. Eclipse cannot find the jars needed to build properly. Worry not. Now we will enable the Maven plug in. Right click on the project root node in the package explorer to bring up the menu. Select "Maven" and then "enable". After a bit of processing your project should rebuild. Now you have the <a href="http://mavenize.blogspot.com/2007/07/eclipse-plugin-for-maven-2-development.html">benefits of the Maven plug in</a>!robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-5740029918670209242007-07-02T14:19:00.001-07:002007-08-17T17:47:31.729-07:00Eclipse Plugin for Maven 2 Development (Maven + Eclipse pt. 2)<span style="font-weight: bold;">The problem:</span><br /><br />You use the Maven 2 system for your projects. You use Eclipse to write your Java code, and things like running and debugging applications.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />Get the Maven 2 plug in for Eclipse! This is a very nice plugin. This plug in will handle configuring your projects class path. It will add the dependencies defined in your pom to the class path. It will also add and remove dependencies from the class path as you add or remove them in the pom file. It comes with a nice little wizard allowing searching of dependencies, with the ability to add them into your pom with a simple click. This wizard can also be configured to search on the dependencies installed in your local repository.<br /><br />You can find <a href="http://m2eclipse.codehaus.org/">the plugin here</a>. If you like using the Eclipse plugin manager use this url: <a href="http://m2eclipse.codehaus.org/update/">http://m2eclipse.codehaus.org/update/</a><br /><br />Once you have installed the plug in you can create "Maven 2" projects that are configured in the Maven standard format (you know "src/main/java", "src/test/java" folders etc.). You can also right click a project select the "Maven2" option and select "enable". This will configure your project's class path using the project's pom. Note that this means your project must have a pom! Now Eclipse will have access to all classes contained within the jars managed by Maven.<br /><br />This is great, but wait there is more. You of course will want to run Maven <a href="http://m2eclipse.codehaus.org/Maven_2.0_Plugin_for_Eclipse.html">commands from within Eclipse</a>, because having to go back and forth between the IDE and command line is just too much work. Worry not, just go to the "Run" menu, select "External Tools" and select the "External Tools..." menu item. This will bring up a menu where you should see a category called "m2 build". By clicking on this category you can create new launchers for doing Maven commands. One word of caution I've found some, more complex, Maven commands did not work great this way. The one in particular was the "jetty:run" command.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWbWb7fsVEqtPkg8p2_fQoyoe498GOTiwPCu6sxp4_0WJiVSQBUo8gM-fzn8RBu0JQHApF1CExXfYdWuUPNfW2FGYj9fvAZp5VHhUYgKQCqs2A9b8es27dsCHvO7mcBHoMhYyxXRmiEb2F/s1600-h/Picture+1.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWbWb7fsVEqtPkg8p2_fQoyoe498GOTiwPCu6sxp4_0WJiVSQBUo8gM-fzn8RBu0JQHApF1CExXfYdWuUPNfW2FGYj9fvAZp5VHhUYgKQCqs2A9b8es27dsCHvO7mcBHoMhYyxXRmiEb2F/s400/Picture+1.png" alt="" id="BLOGGER_PHOTO_ID_5095418130487538210" border="0" /></a>Click this image to see a bigger versionrobottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-89618273986901444372007-07-02T14:16:00.001-07:002007-08-09T20:39:05.825-07:00Clean project<span style="font-weight: bold;">The problem:</span><br /><br />Your project creates a collection of output like classes, jars, websites and more. You want to delete this output!<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />Ok this is kinda a joke. Simply type "mvn clean" and your project's output is gone. How does this work? Well Maven works like a 70 year old man on an all bran diet, very regular. Java source files go into "src/main/java" while testing sources go in "src/test/java". In the same vein plug ins such as <a href="http://maven.apache.org/plugins/maven-site-plugin/">site</a>, generate their output into a folder called "target".<br /><br />Any Maven project will share this convention, since you know when looking at a Maven project folder that "src" contains sources, resources and such, and "target" contains output created from the sources. So think about it this way: sources (in "src" folder) are transformed via Maven plug ins into output (in "target" folder).<br /><br />I will mention that these conventions can be overridden, but.... that is not a good idea and you should never do so.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-48553358112784199082007-07-02T13:54:00.003-07:002007-08-19T10:34:52.118-07:00Generate Website and View It Locally<span style="font-weight: bold;">The problem:</span><br /><br />You are using Maven to create documentation on your project. You want to use the site plug in to generate this documentation into a website. What you need is a quick way to proof your changes, seeing how they look on the website.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />This one blew me away. When you are working on your documentation you can easily view changes, just run this command:<br /><blockquote>mvn site:run</blockquote>This will get a Jetty web server going with your web site running on it. Now just go to localhost:8080 to see your site. This technique is really helpful when configuring reports, as you can quickly test them out.<br /><br />If a project is configured with the Javadoc report there are some nice uses here. you can pop up a site while working on a project and view the Javadoc. This is a useful technique when first checking out a project, so that you may better familiarize yourself with it.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-76086280846337086752007-07-02T13:54:00.001-07:002007-08-12T12:18:54.738-07:00Generate website<span style="font-weight: bold;">The problem:</span><br /><br />Keeping your project documented can interfere with the ten other roles you must fill. I'm speaking from a perspective of the small software shop were you cannot afford to have one or more paid documentation experts (or QA or project management for that matter :)<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />Maven can be a god send to a small software shop. I feel Maven often gives people the notion it is for use in big software shops. Not true. Just because large Apache Java projects are using it does not mean it is too much for a small library or application type project. Maven can create for you a full website, including reports on things such as test coverage, JavaDoc, PMD information, dependencies, email lists, etc. etc. This sounds pretty complex, eh? Well worry not it is simple, and I will show you how to generate such wonders... but in later posts. Let's KISS here. So you have a Maven project and you want a site generated, so just type the following and you will have a full site in the target folder of your project:<br /><blockquote>mvn site</blockquote>Done!robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-64765942166599393422007-07-02T13:53:00.003-07:002007-08-17T17:46:11.070-07:00Release Plugin "Dry Run"<span style="font-weight: bold;">The problem:<br /><br /></span>Running the "release:prepare" command in Maven does a number of caustic things. It will check in and tag your code in the SCM you use. It will also change the projects pom, rolling the version number up. If you have any "SNAPSHOT" dependencies it will fail.<br /><span style="font-weight: bold;"><br />The solution:</span><br /><br />Maybe you want to do a "dry run" before executing a command that could muck up your SCM and pom? By "dry run" I mean the release plug in goes through the motions, but nothing is changed in the SCM, and your pom doesn't get messed up. Here is what you do:<br /><blockquote>mvn release:prepare -DdryRun</blockquote>The "-DdryRun" tells the plug in to not fully perform the preparation. You will find this generates some temporary files in the project folder. These include:<br /><ul><li>pom.xml.next : what the projects pom looks like after the release</li><li>pom.xml.releaseBackup : what the pom looked like before</li><li>pom.xml.tag : the pom for the tagged version of project</li><li>release.properties : the information about the release of the project</li></ul>It is not likely you want to keep these files around for too long. You can remove these file by running this command:<br /><blockquote>mvn release:clean</blockquote>I recommend you use this whenever you are getting ready to release. It will save you a lot of time, because just one botched release attempt could take minutes to clean up. The dry run will take seconds to run.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-91678971774569216702007-07-02T13:53:00.001-07:002007-08-17T17:46:46.221-07:00Release plugin<span style="font-weight: bold;">The problem:</span><br /><br />Your project uses some sort of Source Control Management (SCM). Being that your project is using Maven there are considerations such as project version to take into account when tagging releases of your project. You want a simple way to "release" a version of your project. Normally you would edit the POM changing to a new release version (<a href="http://mavenize.blogspot.com/2007/06/using-snapshots-for-rapid-development.html">from snapshot</a>), then tag the release in your SCM, then change the pom version to the newest version, and finally check in the new pom. Another consideration is the dependencies you are using, you do not want to have snapshot dependencies in your "released" project.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />Maven developers quickly experienced the difficulty of rolling a version of a project. Thats why we now have the release plug in. When you are ready to do a release simply issue the command:<br /><blockquote>mvn release:prepare</blockquote>This plug in makes short work to releasing a version of your project. You must have configured the SCM section of the pom<scm>. This section is used by the release plugin to know how to interact with your SCM.<br /><br />Once you issue the command above you will be asked to give a tag name and the new version for the pom. You can also just hit enter to have the plug in use default values. Thats it, check your pom and you will see the new version. Check the source control and you will see the tag.<br /></scm>robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-28758946738444348462007-06-27T07:46:00.000-07:002007-06-27T10:03:20.630-07:00Artifactory Can Help you Manage a RepositoryI was browsing <a href="http://www.theserverside.com/">TSS</a> and found <a href="http://www.theserverside.com/tt/articles/article.tss?l=SettingUpMavenRepository">this article</a>. It's a good read for any seasoned Maven 2 developer, talking about repository theory and a piece of software called Artifactory. I like that Artifactory combines caching of external artifacts with a nice Web-UI where you can manage your repository. The article does a great job of explaining why and when to use Artifactory.<br /><br />Artifactory looks like a real helpful piece of software. I'll stick to my dead simple repository setup for now, but I am going to give it a try real soon. The caching alone makes it worth using, as I have found in the past it speeds up Maven's execution time.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-8015592983803983222007-06-25T22:43:00.000-07:002007-08-09T20:43:12.597-07:00Profiles + Dependency Management<span style="font-weight: bold;">The problem: </span><br /><br />You want to be able to easily switch between versions of dependencies in your project. This could be in the range of only one project dependency up to every dependency in you project.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />You can create profiles that each define a <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">dependency management</a> section. In each of these dependency management sections you can set the versions for dependencies in your project. Then you will invoke a profile to set the dependency (or dependencies) version(s) used in building, testing, releasing etc.<br /><br />Now why would you want to do this? Well there are a set of situations where you need your project to be able to build and release in lieu of differing version requirements. You may be building a framework that should work with Spring 1.x and Spring 2.x, or maybe Servlet spec 2.4 and 1.x. Let's look at such an example to demonstrate this technique:<br /><br /><pre><profiles><br /><profile><br /> <id>newspring</id><br /> <dependencyManagement><br /> <dependencies><br /> <dependency><br /> <groupdId>org.springframework</groupId><br /> <artifactId>spring</artifactId><br /> <version>2.1</version><br /> </dependency><br /> <dependencies><br /> </dependencyManagement><br /></profile><br /><profile><br /> <id>oldspring</id><br /> <dependencyManagement><br /> <dependencies><br /> <dependency><br /> <groupdId>org.springframework</groupId><br /> <artifactId>spring</artifactId><br /> <version>1.2.1</version><br /> </dependency><br /> <dependencies><br /> </dependencyManagement><br /></profile><br /></profiles></pre><br /><br />In the above example you can see that you could specify the "newspring" profile to use Spring version 2.1, or the profile "oldspring" to use 1.2. You can apply other profile techniques such as default profiles here. Where can you define configuration such as the above? Well normally you would put it directly into your pom.xml. Doing so allows you you to leverage the parent child relationship! You can create profiles which contain different dependency versions in dependency management sections, and inherit them by many child projects. This allows child projects to easily specify which versions of certain technologies are used (I need to create a lengthy example of this in action!).<br /><br />FYI, you likely will not use this technique in a simple Maven project, rather it will be used with some other advanced techniques.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-7785321825915451502007-06-25T22:08:00.001-07:002007-06-25T22:29:49.945-07:00Dependency Management, WTF?<span style="font-weight: bold;">The problem:</span><br /><br />You want to standardize versions of a set of dependencies used in a group of project.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />A set of projects may use a given dependency. I know that I often use both Hibernate 3.x and Spring 2.x in my projects. It can make a lot of sense to use the same versions of dependencies across multiple projects. This may be especially important when you have a set of projects that are very closely related, maybe with dependencies to one another. Enter the dependency management function of the Maven pom. I put WTF in the title because thats what I thought when I discovered this feature for myself. It really is a well thought addition to the Maven platform.<br /><br />So how do you do this? First you will want to put a dependency management section in a pom. Likely this is a parent pom which is inherited by many projects, otherwise what is the point? I MEAN DEPENDENCY MANAGEMENT IS MEANT FOR MANAGING DEPENDENCIES ACROSS MANY POMS. Sorry that was the main point you should take away from this session.<br /><br />Here is what the dependency management section will look like:<br /><br /><pre><dependencyManagement><br /> <dependencies><br /> <dependency><br /> <groupdId>org.springframework</groupId><br /> <artifactId>spring</artifactId><br /> <version>2.1</version><br /> </dependency><br /> <dependencies><br /></dependencyManagement></pre><br />So that will set the version of the shown spring artifact to 2.1. Now how will this make a difference? You will not include a version when adding this dependency in a project which has this dependency management section. You will simply add this dependency config:<br /><pre><dependency><br /> <groupdId>org.springframework</groupId><br /> <artifactId>spring</artifactId><br /></dependency></pre><br /><br />It is pretty simple, Eh? Also note that when you want to upgrade to a new version of a dependency it is as simple as changing the version in the parent pom's dependency management section. Hows that for simple management of your dependencies?robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.comtag:blogger.com,1999:blog-5450801745457300401.post-51987395065498578322007-06-25T21:48:00.000-07:002007-08-17T17:54:02.137-07:00Maven Plugin for Generating Eclipse projects (Maven + Eclipse Pt. 1)<span style="font-weight: bold;">The problem:</span><br /><br />You want to use the ubiquitous IDE, Eclipse, with your Maven project.<br /><br /><span style="font-weight: bold;">The solution:</span><br /><br />Just because you use Maven doesn't mean that you are going to jump through hoops to make it work with Eclipse; all you need to do is type "mvn eclipse:eclipse". This command will generate the .classpath and .project files that Eclipse needs so that it can understand your project.<br /><br />Once you run this command in your project boot up Eclipse and click File -> import -> General -> Existing projects into workspace -> next, now use the enabled browse button to find the project's root directory. Once you do this click OK. You should see your project in the projects window. Make sure it is selected and press the "Finish" button.<br /><br />Right now you probably see all sorts of errors. LOL. One last thing. You must create an Eclipse classpath variable that points to your local Maven repository. Click the following: "Window -> Preferences... -> Java -> Build Path -> Classpath Variables". You now shall click "new" button and create a variable with name "M2_REPO" and value being where your local Maven repo is found. Usually this is ${HOME_DIR}/.m2/repository. On my OS X machine this is "/Users/ottaway/.m2/repository". On my Windows machine it is "C:\Documents and Settings\rob\.m2\repository". Once you set this press the "OK" button.<br /><br />Your projects dependencies should now be loaded. Note that if you add new dependencies to your project you will need to run the "mvn eclipse:eclipse" command again. This will regenerate the .classpath file that contains the dependencies.robottawayhttp://www.blogger.com/profile/16898889765420671029noreply@blogger.com