writing a maven plugin with a (swing) gui interface

Writing a maven plugin can be daunting. Not that it is particularly hard, it is just that you might need to experiment quite a bit to once you do something which is not documented (which -small rant- is quite quickly as the maven documentation is notoriously scarce).

As part of the equanda project (which is far from being ready to undergo public scrutiny), I wanted to write a plugin to start a gui translation tool.

As I did this, I discovered two things.

  • maven plugins are always called for all subprojects, even if the plugin is only declared in one of the subprojects. So you sometimes need a configuration setting just to enable the plugin on specific subprojects only.
  • To start a gui, you need some special measures or the screen has likely disappeared before you had a chance to see it.

For this last item, you need to specifically wait until the user has closed the screen before continuing. Fortunately, java provides all the synchronization tools you need.

Basically you pass an object to the code which builds the screen, just to allow the synchronization. You then have to “wait” for this object (in a synchronized block). To assure all possible errors are caught and execution continues when an eror occurs, you also need to catch the uncaught exceptions.

final Object waitFor = new Object();
        Thread.currentThread().setUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler()
        {
            public void uncaughtException( Thread thread, Throwable throwable )
            {
                SaveException.saveException( throwable, "during equanda:translate" );
                synchronized ( waitFor )
                {
                    waitFor.notifyAll();
                }
            }
        } );


<code>        try

        {
            new DoYourGuiThing( new MavenConfiguration(), waitFor );
        }
        catch ( Exception ex )
        {
            SaveException.saveException( ex, "problems while editing translations" );
            synchronized ( waitFor )
            {
                waitFor.notifyAll();
            }
            throw new MojoExecutionException( "problems while editing translations", ex );
        }
        synchronized ( waitFor )
        {
            try { waitFor.wait(); } catch ( InterruptedException ex ) {/*ignore*/}
        }

Then in the “DoYourGuiThing” class, when exiting, you need to call “notifyAll()” on the passed “waitFor” object again (as in the example above, this needs to be in a synchronized block, or an exception will be raised.

Leave a Reply

Your email address will not be published. Required fields are marked *

question razz sad evil exclaim smile redface biggrin surprised eek confused cool lol mad twisted rolleyes wink idea arrow neutral cry mrgreen

*