20 12 2006

If you find that you get a invalidĀ  header field with a Maven 2 pacakaged war or jar then you are probably using and old version of the maven-archiver plugin that cant cope with pom descriptions containing line breaks.

This may be in the war, but it could also be any of the jars (including 3rd party jars) included in theĀ  war.
There is a simple solution, remove the .m2/repository/org/apache folder and let mvn pull uptodate versions from the remote repositories.

Dec 18, 2006 8:35:44 PM org.apache.catalina.core.StandardContext
start SEVERE: Error in dependencyCheck
java.io.IOException: invalid header field
at java.util.jar.Attributes.read(Attributes.java:389)
at java.util.jar.Manifest.read(Manifest.java:167)
at java.util.jar.JarInputStream.(JarInputStream.java:66)
at java.util.jar.JarInputStream.(JarInputStream.java:43)
at org.apache.catalina.util.ExtensionValidator.getManifest(ExtensionValidator.java:372)
at org.apache.catalina.util.ExtensionValidator.validateApplication(ExtensionValidator.java:183)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4035)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:809)
at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:698)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:472)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1122)


Where Maven 2 parent resolution breaks.

17 12 2006

There is a subtlety in the way in which maven 2 parent resolution breaks. If you have a project that has a parent that needs to be built, the dependency tree does not take into account parent poms when performing the build. You have to explicitly list the parent as a module to make it build and be part of the tree.

We’ll thats not exactly true, what actually happens or appears to happen, is that if the pom in question is not in the local repository and has a relative path stated, it is added to the dependency tree without a version… and things resolve to it, then when it is built it goes into the cache without a version, so that when other projects try and get it out the cache, they cant… resulting in a project that doesn’t exist locally (because it has come out the cache) and cant be cloned (because the version doesn’t match) and so it doesn’t exist (sort of catch 22). The solution appers to be to put then parent poms into the module dependency tree, then they get built first and put into the local repository with a version, and appear in the cache correctly…. or at least thats what appears to work… very confusing.

Dependency Resolution

15 12 2006

Maven 2 dependency resolution is a wonderful thing, but its not quite there in 2 when you have multiple classloaders and dont necessarily want the transitive dependencies to flow through. In sakai in Maven 1 we defined everything explicitly, but in maven 2 I find that jars in the shared classloader creep into the components packaging and and webapp packaging. The only way to stop this is to make the jar provided, but if that is done the dependency does not flow, so you cant make a dependency transitive up to a war file and then not pack it. Its all or nothing, provided or not and packed.

The solution, as in maven 1 appears to be explicit which eliminates one of the nicest features of maven 2…. however there is a sting in the tail to all of this. There are many 3rd party components that we use in sakai, that we bundle into wars. These have transitive dependencies that we are already providing for in shared, hence the only way to prevent packing is to explicitly re scope the dependency as provided… bloating the pom and increasing the overhead… just the thing maven 2 was supposed to help with. Looking at the maven jira, much of this will be fixed in 2.2 .

Maven Ant Plugin

13 12 2006

Although the docs are a bit thin, the maven-ant-plugin works well for Maven 2 so you can port maven.xml into this form in some instances.

The following will run in the package phase of at build just before the war is packaged up. (from sakai sections tool)

The variable names are maven variables not ant names, there is a bit of confusion about this.


<delete dir="${project.build.directory}/${project.build.finalName}/common" />
<delete dir="${project.build.directory}/${project.build.finalName}/sakai" />
<delete dir="${project.build.directory}/${project.build.finalName}/standalone" />
<echo message="Copying common resources into webapp"/>
<copy todir="${project.build.directory}/${project.build.finalName}" overwrite="true" >
<fileset dir="${basedir}/src/webapp/common" />
<echo message="Copying sakai dependent resources into webapp"/>
<copy todir="${project.build.directory}/${project.build.finalName}" overwrite="true">
<fileset dir="${basedir}/src/webapp/sakai/">
<include name="**/*"/>

Maven2 more….. building

11 12 2006

I’ve now got it all building including osp, sam, sections, gradebook (after a break going to the Mall, went into the Apple store, looked and looked and looked, but walked out empty handed…. maybe nothing is quite as tempting as it used to be, but I did see some iPod games, I wonder when Apple will release the dev kit… if ever) sorry… yes its building now. Next problem is which deployer to use.

Most of the Tomcat deployers try to be to cleaver and integrate with the running tomcat runner, when all we really want is something on the filesystem. I’ve had a long hard look at Cargo for maven2, but it doesnt work… cargo:package and cargo:install don’t work and I don’t really want to have a deploy to a running tomcat so cargo:start is out of the question.

The pluto deployer looks promising, and the existing plugin that I have already does unpack, so there is a chance that either of these will do.

Naturally there is some confusion with deploy to a repository (which part of M2 ontology) and deploy to tomcat.

Atlanta is really quite now, no more Poker BOF’s, Aerodynamics BOF’s from the 49th floor…..

there is a confluence page tracking this, where I will upload the poms, pending getting commit. (http://bugs.sakaiproject.org/confluence/display/~ianeboston/Maven2+Migration+Work)

Maven2 Sakai .. more

10 12 2006

So I now have a set of poms for all apart from OSP that verify and go through the build. The XSLT approach has been augmented by scripts and manual editing to manipulate the poms into a structure that builds.

The Sakai build exposes some bugs in maven that have cause me to have to change the structure of the way in which we define dependent or parent projects. M2 will not reliably chain many masters together, so the extend constructs found in gradebook, sections, osp and some jsf tools have to be recast. The mechanism that appears to work is to make all projects have a parent of the master/pom.xml and then pull the other dependencies through as dependent poms, this works and gives good control (as well as allowing multiple extends)

The next issues that hits us is that m2 has transient dependencies, all of which get packed unless marked as provided, and that includes the transients. So you have to mark all jars as provided that are provided even in the impl poms otherwise they will pull shared or common jars into component and webapp builds wich is wrong. Since we are comming from M1, where re definend everything the solution here is to make everything provided and use the explicit pack at the last stage (which leads back to the shared and common issues before)

The other real killer that happens here is that M2 will inspect transient deps from standard poms, for example struts has a burred dep on jdbc_stdext, which we dont use has we are in a hibernate world… we use a h2.1.8 version of this, I dont know exactly why this is, but the solution I have used is to modify the struts pom in the local repository to depend on the correct one. Struts is used in samigo and since that is heavilly hibernate this looks like the safe thing to do.

Another thing that is different about M2 is that it hides the deps that appear in the classpath without you knowing it. For instance the xercese dependencies appeared without you knowing it in M1. In M2 you have to define them (as provided), so there are a number of poms (5-10) that have had these deps added manually when the compile fails.


Since we have used our own repository, I am finding that I need to manually build the local repository for maven2 as deps cant be found. This will need to be propagated to somewhere central and hosted by sakai.

Inspite of all that, M2 is much nicer to work with. For those interested, I am keeping the plugin development at https://source.sakaiproject.org/contrib/tfd/trunk/maven

Maven 2 Continues….

6 12 2006

So, During listening to the “reassurances” of the Blackboard atourney that the wouldn’t issue writs against opensource before tea time……:)… I tried to do a bit of innovation. The maven 2 conversion for the build structure is starting to work. One thing that I notice is that the dependency definition is much more precise in maven2 which is generating missing deps in some of the projects (xercese et al).

The other thing, on my slow G4, that is nice, is mvn2 is *much* faster!