The Source for Java Technology Collaboration
User: Password:



Rich Unger's Blog

December 2005 Archives


Module Suite building tips (part 4)

Posted by richunger on December 21, 2005 at 02:42 PM | Permalink | Comments (4)

Today, I'll be taking the stock Module Suite build files, and creating a nightly build process. My process does an update on the source tree, builds it, runs unit tests, publishes the result to our intranet, and labels the source tree.

My particular project uses ClearCase as the source control repository, though this should be simple enough to tweak for CVS, subversion, perforce, etc.

All these targets are just in my root build.xml.

To start, here's a high level overview of the tasks which need to be completed:

<target name="nightly-impl">
    <antcall target="clean"/>
    <antcall target="repository-update"/>
    <antcall target="build-zip"/>
    <antcall target="test-all"/>
    <antcall target="publish-build"/>
    <antcall target="label-build"/>
</target>

The 'clean' target is just inherited. 'repository-update' looks like this:

<target name="repository-update">
    <ccupdate viewpath="."
    graphical="false" 
    log="build/clearcase.log"
    overwrite="true"
    currenttime="true"
    rename="false"/>
</target>

...though, of course, that's clearcase-specific.

The 'build-zip' and 'test-all' targets are inherited as well, though I override 'build-zip' as seen in my previous entry.

Publishing to the intranet, in my case, is just a simple copy with a fancy naming scheme. The variables ${vb.release.location} and ${vb.branch.name} must be defined elsewhere.

<target name="publish-build">
    <tstamp>
        <format property="buildnumber" pattern="yyMMdd" timezone="UTC"/>
    </tstamp>
    <property name="nightly-release-dir" value="${vb.release.location}/nightly"/>
    <mkdir dir="${nightly-release-dir}"/>
    <copy file="dist/${app.name}.zip" 
          tofile="${nightly-release-dir}/V-Builder-${vb.branch.name}-${buildnumber}.zip" overwrite="yes"/>
</target>

Labelling/tagging the build is, once again, a clearcase-specific thing. The syntax for CVS, etc. would be different:

<target name="label-build">
    <tstamp>
        <format property="buildnumber" pattern="yyMMdd" timezone="UTC"/>
    </tstamp>

<property name="label-ver" value="REL-${vb.branch.name}-${buildnumber}"/> <ccmklbtype typename="${label-ver}"/> <ccmklabel viewpath="." recurse="true" typename="${label-ver}" failonerr="false"/> </target>

The last step is to provide some kind of notification/logging of the status of the nightly build. I do this by invoking ant with command-line parameters for sending the console output to some email address:

<target name="nightly">
    <exec executable="cmd" failonerror="true">
        <arg line="/c ant -logger org.apache.tools.ant.listener.MailLogger -DMailLogger.from=${vb.nightly.email.from} -DMailLogger.failure.to=${vb.nightly.email.to.failure} -DMailLogger.success.to=${vb.nightly.email.to.success} -DMailLogger.mailhost=${vb.nightly.email.mailhost} nightly-impl"/>
    </exec>
</target>

Then we just set up a cron job that runs "ant nightly" at the top of the source tree. Simple, eh?

Module Suite building tips (part 3)

Posted by richunger on December 20, 2005 at 01:32 PM | Permalink | Comments (3)

In this installment, I'll be solving 2 issues with the building of a distributable application from a NetBeans Module Suite:

  1. Including a custom conf file (instead of the default etc/netbeans.conf)
  2. Including the JDK with my distribution

First, let's take a look at my vbuilder.conf file:

# ${HOME} will be replaced by JVM user.home system property
# ${APPNAME} will be replaced by the app name specified
# in the module suite's project properties
default_userdir="${HOME}/${APPNAME}/4.0"

# options used by the launcher by default, can be overridden by explicit
# command line switches
default_options="-J-Xms24m -J-Xmx128m -J-Dnetbeans.logger.console=true"

# default location of JDK/JRE, can be overridden by using --jdkhome <dir> switch
# relative paths are relative to the root of the netbeans installation
jdkhome="jdk"

Now, I've checked this file into my module suite's nbproject/ directory. Notice that the configuration sets the default JDK to ${NETBEANS_ROOT}/jdk.

In the suite's build script, I need only override one target:

<target name="build-zip" depends="suite.build-zip" description="Builds a ZIP distribution of V-Builder.">
    <zip destfile="dist/${app.name}.zip" update="true">
        <!-- The JDK that's running this ant script -->
        <zipfileset dir="${java.home}/../" prefix="${app.name}/jdk">
            <exclude name="bin/*.exe"/>
            <exclude name="jre/bin/*.exe"/>
            <exclude name="src.zip"/>
            <exclude name="src/**"/>
            <exclude name="demo/**"/>
            <exclude name="sample/**"/>
        </zipfileset>
        <zipfileset dir="${java.home}/../" prefix="${app.name}/jdk" filemode="755">
            <include name="bin/*.exe"/>
            <include name="jre/bin/*.exe"/>
        </zipfileset>

        <!-- vbuilder.conf -->
        <zipfileset dir="nbproject" prefix="${app.name}/etc">
            <include name="${app.name}.conf"/>
        </zipfileset>
    </zip>
</target>

...and that's all there is to it. Now the zip file generated by the IDE's "Build Zip Distribution" action will contain my custom vbuilder.conf and the JDK that was used to build it.

In the next entry, I'll show you how to set up a nightly build process.

Module Suite building tips (part 2)

Posted by richunger on December 19, 2005 at 06:38 PM | Permalink | Comments (2)

I think I'm one of the first people to make a netbeans module suite with a large number of modules, so as a followup to my last entry on module suite building, I thought I'd continue putting up some of my build script hacks.

The problem I'm solving here is in having a canonical netbeans platform to build against. Up until now, I've been building against the IDE, from within the IDE. That works very well, but now I'm ready to set up my nightly build process, and I want to make sure that the nightly builds use the exact same netbeans platform that I use in development.

I start off by editing my suite's nbproject/platform.properties file:

suite.dir=${basedir}
netbeans.dest.dir=${suite.dir}/image/netbeans
harness.dir=${netbeans.dest.dir}/harness

This means that the build scripts will expect an installation of the netbeans platform (including the harness/ directory) to be in ${MySourceRoot}/image/netbeans

I've also downloaded a zip file of netbeans 5.0 and checked it into my source tree, to be unzipped automatically by my build scripts.

My first thought was just to have the ant script's "init" target unzip the file. The problem with that is that the file must be unzipped in order to provide the harness/ expected by ${harness.dir}. This is necessary to build the list of <target>s in the build file. So, the unzipping must occur before importing build-impl.xsl and building the targets.

This makes it difficult to unzip the platform conditionally. I don't want to unzip it if it's already unzipped. However, the only way to do conditionals in ant is to use the 'unless' attribute in <target>. But, I need to unzip the platform in order to build the targets!

ant-contrib to the rescue.

My suite's build.xml file looks like this:

<project name="vbuilder" basedir=".">
    <description>Builds the module suite vbuilder.</description>

    <!-- Need ant-contrib because of the  element -->
    <taskdef resource="net/sf/antcontrib/antlib.xml">
        <classpath>
            <pathelement location="${basedir}/nbproject/ant-contrib.jar"/>
        </classpath>
    </taskdef>

    <!-- This needs to come before the import of build-impl.
         The netbeans.zip must be unzipped to provide the build harness,
         _before_ creating <target>s.  Therefore, this cannot be done
         with the 'unless' attribute of <target>
    -->
    <if>
        <not>
            <available file="image/netbeans"/>
        </not>
        <then>
            <mkdir dir="image"/>
            <unzip src="netbeans.zip" dest="image"/>
        </then>
    </if>

    <import file="nbproject/build-impl.xml"/>
    ...

One last note. This will not work in 5.0 beta2, only in later development builds (it will work in 5.0 final). This is because ${netbeans.dest.dir} is a relative path.

The workaround for beta2 is to add this line to platform.properties:

zip.platform.clusters.duplicates=platform6,ide6,nb5.0,enterprise2

...giving it the list of clusters from the netbeans platform you wish to include in your application.

Crying Wolf With Keyguard

Posted by richunger on December 14, 2005 at 12:41 PM | Permalink | Comments (4)

This is going to be the most off-topic post I've done yet, but it's a UI issue, and a potentially very dangerous one, and I thought my few readers might get a kick out of this.

Yesterday, I received a call on my new cell phone from the police emergency switchboard. They said, "We have an open circuit on your cell phone. Is there an emergency?" There wasn't, and I felt suitably shamed to have wasted valuable 911 switchboard time.

So should Sanyo UI engineers.

I upgraded my 5-year old Sanyo cell phone to their newest stick (non-flip) model. I like the stick models. Just a personal preference. The important thing about stick phones is that you need keyguard. Keyguard is when you set the phone to not accept input unless you hold down one particular button for a few seconds. This prevents the exposed keypad from accidentally dialing while it's in your pocket.

Well, my new phone has keyguard. It also has a special emergency "feature" which overrides keyguard to let you dial 911 without losing those precious few seconds it takes to turn off keyguard. You can't dial anything else except 911. You can't dial 119, or 919 ... just 911. In other words, at first, no key works except 9. Then, no key works except 1. Then, again, nothing but 1 will produce a result.

Do you see where I'm going with this? If the phone is in my pocket, and ALL the buttons are mashed long enough, it is guaranteed that the phone will dial 911.

Here in the Bay Area, 911 switchboards are already undermanned. Now we have Sanyo phones tying up the phone lines with button-mashing calls.

Thanks a lot, Sanyo.





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds