Archive

Archive for the ‘Deldorado’ Category

GWT MVP: supporting legacy URL tokens

January 21st, 2011 No comments

Recently I started to migrate a GWT application to MVP, in order to learn it, and also to enjoy the promised advantages.
For now I decided to use the MVP framework that comes with GWT 2.1. Migration itself was relatively easy, but the framework dictates how the token is structured – and it is quite simple:

PLACEPREFIX + “:” + PARAMS

The colon is hardcoded in the AbstractPlaceHistoryMapper class, but my previous implementation uses slash (and a slightly different approach to select the view).
The application is integrated with few other systems via URLs, and naturally I need to support my original syntax, in addition to the one required by the framework.
The simplest way seems to be, trapping the occurrences of original syntax, and translate it into the new one.
Fortunately, it is quite simple. The class PlaceHistoryMapper (from GWT) works with history strictly via Historian interface, with a default implementation that uses History api. So, I derived my own historian from that implementation and reimplemented it accordingly:

MyHistorian.java

public class MyHistorian extends PlaceHistoryHandler.DefaultHistorian {
  public String getToken() {
    String token = super.getToken();
    if (token == null) {
      return null;
    }
    if (token.startsWith("oldprefix/")) {
      token = "NewPlacePrefix:" + token.substring(10);
    }
    return token;
  }
}

As you see, the implementation is really simple. In many cases, the translation logic will be far more complex, but this shows the idea.
Now we also need to make GWT use our implementation instead of the default one. This can be achieved via GWT’s Deferred Binding, because PlaceHistoryHandler creates historians with GWT.create() call.

MyApp.gwt.xml

This is a fragment you should add to your .gwt.xml file:

...
    <replace-with class="net.kozelka.myapp.client.MyHistorian">
      <when-type-is class="com.google.gwt.place.shared.PlaceHistoryHandler.DefaultHistorian"/>
    </replace-with>
...

Note that this approach works for me with GWT 2.1.1 – I did not check any previous versions.
If you have any ideas how to do this in a better way, please share it here.

Further hints

  • keep the translation logic in a separate class
  • to get feedback on bad urls:
    1. create also MyDebugHistorian which makes something annoying (like Window.alert) when legacy syntax is detected
    2. bind it in your MyAppDebug.gwt.xml module descriptor, instead of the “silent” implementation
  • use some logging mechanism – to record uses of old syntax even in production code

References

Categories: Deldorado Tags: , ,

Ubuntu Places menu: weird behavior of “Home” place

January 5th, 2011 3 comments

Recently I played with several multimedia tools – cutting and editing movies, transforming them to diferent codecs etc. – and during that activity, something was broken in my Ubuntu user account: when I try to open Home folder from the Ubuntu’s “Places” menu, it causes that gnome-mplayer is executed instead of the default nautilus.

Here is what I do:

… and here is what happens:

You see ? There is gnome-mplayer scanning the given folder, which makes me believe that gnome-mplayer installed itself somewhere in my user settings instead of nautilus. Yes, it must be user-wide, not system wide – because other user accounts on the computer do not suffer this way.

Note: thanks to Miloš Svašek for helping me to resolve WordPress issues with images.

Categories: Deldorado Tags: ,

mc unzip problem on ubuntu karmic

November 25th, 2009 10 comments

Ubuntu 9.10 (Karmic Koala) has a little issue with Midnight Commander – it does not browse into zipped files, and shows empty contents instead. After searching the web I found out that the problem can be solved by setting property “op_has_zipinfo” to “1″ in file “/usr/share/mc/extfs/uzip”. For the truly lazy people I prepared this little commandline fixing that (no need to open the editor):

sudo sed '/op_has_zipinfo/{s:0:1:}' /usr/share/mc/extfs/uzip >x && sudo chmod 755 x && sudo mv x /usr/share/mc/extfs/uzip

Enjoy!

How to build a ZIP output artifact in Maven

October 22nd, 2009 2 comments

It’s quite a common situation that you have a bunch of files, most or all of them committed in svn, and need to make a release of this so that it can be reused with the Maven’s dependency mechanism.

There are several ways how to accomplish that:

  • use maven-assembly-plugin
  • use maven-antrun-plugin to build and build-helper-maven-plugin to attach
  • create custom plugin that handles both packaging and attaching

Each of them has its advantages in some situations, but my favorite is the second option for most cases.

Real life example – artifact with various svn output files

In some of my projects, I need to check that the code works properly with xml output files from Subversion. I could easily put such files among test resources, but the it would be there many times, and I would always have to check if it is “representative” enough etc.

So I decided to create a module, which will create the data during its build (see the maven-antrun-plugin).

These data are packaged into a zip file which is then marked as output artifact with type “zip” (see the build-helper-maven-plugin).

Look at this pom excerpt  (complete pom.xml is available here):

<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/xsd/maven-4.0.0.xsd">
  <groupId>net.sf.buildbox.testdata</groupId>
  <artifactId>svn-mvn-testdata</artifactId>
  <version>1-SNAPSHOT</version>
  <packaging>pom</packaging>
...
  <build>
    <outputDirectory>target/output</outputDirectory>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.3</version>
        <executions>
          <execution>
... phase=package, goal=run
            <configuration>
              <tasks>
                <mkdir dir="${project.build.outputDirectory}"/>
                <exec executable="svn" failonerror="true" dir="${project.build.outputDirectory}" taskname="svn-checkout">
...
                </exec>
...
                <zip destfile="${project.build.directory}/${project.build.finalName}.zip">
...
                </zip>
              </tasks>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.2</version>
        <executions>
... phase=package, goal=attach-artifact
            <configuration>
              <artifacts>
                <artifact>
                  <file>${project.build.directory}/${project.build.finalName}.zip</file>
                  <type>zip</type>
                </artifact>
              </artifacts>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

What are the advantages over other mentioned alternatives ?

  • extensibility – the “generator” part is straightforward, so, as long as ant is enough for us it costs just a few lines of ant code
  • compactness – we could reach similar result with several invocations of exec-maven-plugin for preparing data, plus maven-assembly-plugin to pack and attach it, but that would be far far more verbose and harder to maintain

Just for completenes, it’s good to say when using the other approaches is more relevant:

  • custom maven plugin – when the algorithm for generating data is too complex to be written in ant, or needs other sources that are not reachable from antrun, like dependencies
  • maven-assembly-plugin – when we need to control file permissions in tgz/gz packages while running the build on windows

Do you have experience in this area ? Then please post your comments…

Categories: Deldorado Tags: ,

Generating temporary files in junit tests

July 6th, 2009 8 comments

It is often useful to create some temporary files inside a unit test. Basically it is not a problem, because junit does not limit you in such thing; you might simply use a “current” directory to store such files, and it usually works. However, different frameworks invoking JUnit use different “current” directories, which makes it difficult to:

  • locate the temporary files for debugging purposes
  • remove them between test re-executions
  • reference static (committed) files using a relative path

I personally always use at least two such frameworks – Maven and an IDE – and I would really like to see the data always at the same place, and reference committed files using always the same relative path.
Besides that, I require that any intermediate data in my Maven modules are generated under the “target” subdirectory (or, more precisely, under ${project.build.directory}), because

  • this gives me the comfort of cleaning them as part of “mvn clean test” command without other manual specification of directories to erase
  • it does not bloat module directory structure with version-uncontrolled files.

To accomplish this, we cannot use the “current” directory; instead, we need to compute one that is always the same, and use in later in the unit test.

So it seems to be neccessary to write a method that somehow computes that “stable” directory:

public static File computeTestDataRoot()

How can it be implemented ? The key is that they execute tests from compiled classes stored in a directory, not in a jar file. We can therefore use a resource laying among these tests – which can even be one of test classes (there is always at least one, the one for which we need it), and we use it to locate root of the test classes. In Maven, it is by default “target/test-classes”. To extend this nice convention, we will make the method return “target/test-data”, a non-existent directory which can be used by tests to generate their stuff.

public static File computeTestDataRoot(Class anyTestClass) {
  final String clsUri = anyTestClass.getName().replace('.','/') + ".class";
  final URL url = anyTestClass.getClassLoader().getResource(clsUri);
  final String clsPath = url.getPath();
  final File root = new File(clsPath.substring(0, clsPath.length() - clsUri.length()));
  final File clsFile = new File(root, clsUri);
  return new File(root.getParentFile(), "test-data");
}

Note that we need to pass an argument to our method – the calling test class. It is a little price for getting consistent test data directory – and probably unavoidable.

Categories: Deldorado Tags: , ,

When is it best to do cleanup in tests ?

July 4th, 2009 No comments

With “true” unit tests, having no requirements on shared external resources, this is not an issue.

But in reality, we often need (integration) tests that do need such resources – database, jms, other servers or just files located somewhere.

In my opinion, the cleanup in all unit tests should happen before the test itself. It has a simple reason – whatever wrong happens, next time the test can be executed without need for any annoying manual intervention.

What are the wrong things that may happen ? Here are some:

  • test fails
  • the process is killed – potentially even related to the test execution
  • the host computer is turned off

The first one can be handled by the testing framework. JUnit and similar ones provide support for setUp / teardown method that should do the right things before and after each test or testsuite.

While this concept is very good, especially for isolating the initialization and cleanup code from the test logic, it – by itself – doesn’t work at all for the latter scenarios.

So, it is always much safer to assume that we won’t get the chance to cleanup afterwards.

My preferred techniques to minimize need for manual intervention are:

  • in the setUp part, prepare all resources to the state required by the test
  • if it is too complex, at least check if they are in the required state; fail with indicative messages otherwise
  • do no init/cleanup stuff within the test method itself
  • do no cleanup in the teardown part – just to avoid temtation to rely on its “proper” function.

One little bonus of not doing cleanup at the end is, that we can easily check the final state of affected resources just by running the single test, with no modification or debugger setup needed.

Categories: Deldorado Tags: ,

bbx:1.0.0-alpha-5 released – BuildoZER, colorado and the others

July 3rd, 2009 No comments

The cross-platform development tool suite “bbx”, has been recently released in version 1.0.0-alpha-5.
It contains several development-oriented tools, supporting especially Maven builds:

  • BuildoZER (zer) – a tool to perform transitive builds of Maven modules
  • colorado – simple log output colorizer (Linux only for now)
  • zcd – to navigate through directories by module name (artifactId from pom.xml)
  • bbx – an extensible ant frontend with argument parsing, pom-based dependency support and more

It is still an alpha-quality release, but the tools are already very handy.

Categories: Deldorado Tags: ,

How to force explicit version specification

January 30th, 2009 6 comments
It is often necessary to reproduce older builds. Either because you need to branch it and make a small bugfix, or to perform sanity check of your constantly evolving build infrastructure.

Then you often discover that Maven’s cool feature, to automagically use LATEST version of plugins by default, is not that cool… new versions may be incompatible with your specific usecase, or broken completely, etc etc (I suffered this experience with maven-war-plugin version 2.1-alpha-2 as I reported in [#MWAR-181]).

Yes, you can work hard and define a corporate pom that presets version of all plugins you use. That’s good, but who will remember to do that when a new plugin will be added to build ? Most people won’t.

Fortunately, there is a way to keep you reminded: forbid download of “*metadata.xml” files and that’s it. Maven uses this file to determine list of available versions, whenever you use a non-specific version like RELEASE or LATEST, which is the case of plugin artifacts. Without such metadata, maven fails,saying that it cannot find any version – so you immediately know that your build would be irreproducible otherwise and that it is time to extend your corporate pom.

On Apache server, you can accomplish that using mod_rewrite – just add something like this to httpd.conf:

...
RewriteEngine on

# strict repo:
RewriteRule ^/maven2-strict/.*metadata\.xml$ - [G,L]
RewriteRule ^/maven2-strict/(.*) http://my.physical.repo:8081/nexus/content/groups/public/$1    [P,L]
...

and, of course, use this in your settings.xml:

...
 <mirror>
   <id>internalRepository</id>
   <mirrorOf>*</mirrorOf>
   <name>inhouse aggregated repo</name>
   <url>http://my.intranet.server/maven2-strict</url>
 </mirror>
...

Update:

As Brian Fox from Sonatype noted, there are better alternatives to reach reproducibility:

  • Nexus users can use directly its own administration interface to setup the redirect
  • even better is, to use maven-enforcer-plugin with its requirePluginVersions rule; it has no impact on using commandline mojos with abbreviations

Read comments for more details.

Categories: Deldorado Tags: , ,

bash script aware of its location for various types of invocation

November 29th, 2008 No comments

When writing a bash script launching a tool used directly on commandline, it is often convenient for the user to have various ways of invocation.
It is not a problem with trivial scripts, but those who need to access files with known location relative to the script, there are little troubles.
First, the script needs to determine its own absolute location on filesystem – because the user can “stay” in any directory. The user can also invoke it directly, using relative or absolute path; and finally, user can invoke a symlink pointing to it, again using relative or absolute path.
Following snippet shows how to handle such cases:


#!/bin/bash
D=${0%/*}
F=$( find $0 -printf %l )
if [ -z "$F" ]; then
   # it is not symlink
   case "$0" in
   /*) F=$0;;
   *) F=$PWD/$0
   esac
else
   # it is symlink
   case "$F" in
   /*);;
   *) F="$D/$F";;
   esac
fi
# now F=absolute path here
F=${F//\/\.\///}
D="${F%/*}"
# now F contains the script's pathname,
# D contains its containing directory
Categories: Deldorado Tags: ,

buildbox@googlecode

January 22nd, 2008 No comments

In addition to the buildbox project at sourceforge, I just created parallel one at a http://buildbox.googlecode.com. While SourceForge provides a lot of useful options and services, like shell access, web site with storage etc., their wiki service is rarely functional and I had no more time to fight it. Plus the issue tracker at SourceForge is a crappy thing too, so I decided to give a chance to Google’s hosting service, currently only for wiki and issue-tracking purposes.

Categories: Deldorado Tags: