Fork me on GitHub

n. Slang a rough lawless young Kuali developer.
[perhaps variant of Houlihan, Irish surname]
kualiganism n

Blog of an rSmart Java Developer. Full of code examples, solutions, best practices, et al.

Tuesday, February 28, 2012

KFS Overlay Reference Implementation on GitHub

As a follow-up to the Mavenized KFS Distribution Available on GitHub post, this is a real world solution on setting up an overlay. It is also a good example of how you would structure your project to do so. I intended this for download, so that people can have a glimpse of a reference implementation example of a KFS overlay.

The Project

First, you can find the KFS Overlay Reference Implementation on GitHub.

The POM

Let's break down the POM a little bit. We'll start at the boilerplate.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.kuali.pom</groupId>
    <artifactId>kfs-public</artifactId>
    <version>0.0.1</version>
  </parent>
  <groupId>com.rsmart.kuali</groupId>
  <artifactId>kfs</artifactId>
  <packaging>pom</packaging>
  <name>rsmart-kfs</name>
  <inceptionYear>2012</inceptionYear>
  <version>0.0.1-SNAPSHOT</version>
  <description></description>
  <url>https://github.com/r351574nc3/kfs-overlay-reference/</url>

This overlay is using the kfs-public POM as mentioned in an earlier post. The reason is that this is not a Kuali-Foundation project.
<groupId>com.rsmart.kuali</groupId>
  <artifactId>kfs</artifactId>
  <packaging>pom</packaging>
  <name>rsmart-kfs</name>

I have put this in the com.rsmart.kuali group, so I do not want this deploying artifacts to nexus or cloudfront for the kuali foundation. Using the kfs-public POM let's me override all that stuff and not have to deal with it.

Next, I have created some standard modules that the Kuali Foundation regards as essential to your project.
<modules>
    <module>config</module>
    <module>web</module>
  </modules>

One is the config module. KFS uses this for external configuration. Peeking inside its POM, we see
<properties>
    <kfs.external.package.phase>package</kfs.external.package.phase>
  </properties>

  <build>
    <filters>
      <filter>${user.home}/kfs-build.properties</filter>
      <filter>${env.filter}</filter>
      <filter>${filter.directory}/b2b.properties</filter>
      <filter>${filter.directory}/build.properties</filter>
      <filter>${filter.directory}/build-foundation.properties</filter>
      <filter>${filter.directory}/database.properties</filter>
      <filter>${filter.directory}/logging.properties</filter>
      <filter>${filter.directory}/rice.properties</filter>
    </filters>
  </build>

  <profiles>
    <profile>
      <id>distribute</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <build>
        <plugins>              
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

There are filters setup for the standard KFS filters which are used to build the configuration.properties and the external configuration directory. Notice also that the distribute profile makes use of our assembly plugin configured in the kfs-common POM.

The web module is also essential because this is what eventually creates our WAR file. You may have already noticed the the POMs I have show so far have <packaging>pom</packaging> set. Obviously, those are not creating any WAR artifacts. The pattern/convention set by the Kuali Foundation is that there is a web module that does that for you. You can see in the web POM I created, that a great deal is going on here. The maven POM is a declarative DSL, so stuff is not described in any order, just organized and grouped together. To explain what is happening, I may jump around a little.

First, I want to point out the the dependencies
<dependencies>
    <dependency>
      <groupId>${kfs.maven.groupId}</groupId>
      <artifactId>kfs-web</artifactId>
      <version>${kfs.maven.version}</version>  
      <type>tar.bz2</type>
      <classifier>src</classifier>
    </dependency>
    <dependency>
      <groupId>${kfs.maven.groupId}</groupId>
      <artifactId>kfs-web</artifactId>
      <version>${kfs.maven.version}</version>  
      <type>war</type>
    </dependency>
  </dependencies> 

Of course, there is the normal war dependency for the overlay. There is also a sources dependency. o_0!? You may have already noticed the section on filters. It has to filter in properties set in these files. For simplicity, I have excluded those file from the overlay project. Why should I need them? They're not part of my project. They're in another project. It makes sense that these are dependencies, right? That is what I have done. The sources .tar.bz2 is where the filters are unpacked from. This needs to only happen once. This is an overlay project after all. There is no need to keep unpacking the dependencies unless they change which is not likely. Therefore, there is a specific phase (that can be overridden) which specifies when this happens
<properties>
    <kfs.web.unpack.phase>generate-sources</kfs.web.unpack.phase>
  </properties>

Where is the Overlay!?

The only clue we have is the war plugin in this POM
<plugin>
        <artifactId>maven-war-plugin</artifactId>
      </plugin>

So where is it happening then? It is in the kfs-public POM along with everything else that is needed for a project that is the child of the main kfs-parent. Part of this is to make overlays a lot more easier. Basically, the plugins are already setup for you. You can just create an overlay project with minimal modification to your POMs.

Conclusion

Try it out. If there's anything you would change, please email me or get in contact with me. I really enjoy collaborating with people and sharing ideas.

No comments:

Post a Comment