Mylyn-Mantis connector 3.1.5 released

Time has come for another release of the Mylyn connector for MantisBT. I find that these released don’t arrive so often since the connector is solid and has the features that I for one need for day-to-day usage.

Nevertheless, I found the time to remove some issues which have annoyed both me and the users kind enough to report them.

Correct display of incoming changes

I’ve worked hard to correctly display incoming changes in both the task list and the popup notification used by Mylyn. The connector used to display changes from one step behind and this has annoyed me for a long time. No more.

Refer users to the wiki when needed

A lot of support issues have been generated by the fact that incorrectly configured MantisBT repositories work in the web interface, but not with Eclipse. We now suggest visiting the wiki in case an unexpected error appears when validating the repository. The link is Troubleshooting connection problems between MantisBT and Eclipse.

Interoperability

We have finally chased down the last remaining Web-Service related conflict, and we play nice when Web-Service related plugins are installed. Also, HTTP authentication works properly.

Usability

Some minor usability issues have also been fixed:

  • The query ‘maximum results’ property is now saved;
  • The ‘time spent’ is correctly formatted;
  • When creating a query for the first time, updating the repository configuration shows a progress dialog, not just a busy cursor.

Please update and report any issues found in our bugtracker or forums.

Mylyn-Mantis connector 3.1.4 released

This release of the connector brings around minor improvements and bugfixes.

One notably troublesome problem was not being able to run under IBM RAD 7.5.5, which was solved by re-organizing the Import-Package and Require-Bundle statements to please the 3.4 platform.

Yet another bug which affected non-English based MantisBT installations was fixed, and installation from the Mylyn Connector discover tool / Eclipse Marketplace was fixed.

This release also features support for the SOAP API changes from MantisBT 1.2.2.

Cutting down GWT’s verbosity with gwt-mpv-apt

I am strong believer in GWT’s potential as a client-side web development solution. Its value proposition is quite exciting: write all your web code in Java, using tools of your choice, and the GWT compiler will output highly tuned, browser-compatible JavaScript. I use it whenever possible and never look back.

Still, there are some times when I feel that GWT’s programming style is too verbose ( see Reducing GWT custom widget verbosity ) to be really productive. I obviously save a lot of time, compared to what I would need to write a comparable interface using “plain” Javascript. But that does not mean that I’m happy to spend time writing code which in “real” Java would be much simplified using reflection. As there is no reflection ( java.lang.reflect ) support in GWT, I was stuck writing verbose code for event handling and DTOs.

That’s why I was thrilled to discover the gwt-mpv-apt project, which is a Java 6 annotation processor to help generate some of the boilerplate code involved in GWT projects. The setup is rather simple:

  • Download gwt-mpv-apt.jar, put it in your project’s classpath
  • In Eclipse, go to Project Settings, Java Compiler, Annotation Processing, and hit “Enable processing specific settings”. Go to Factory path and hit “Enable project specific settings”. Select the gwt-mpv-apt.jar, hit OK.
  • For javac, use JDK6 and it will pick up the processor from your classpath automatically

To get a sense of what this can do for you, I’ll take the example of a GwtEvent which signals that a group of people arrived. The PeopleArrivedEvent should contain the count of people which arrived in this group, and their origin. In the screenshot below, the top editor shows what I wrote, and the bottom editor shows what was generated.  I collapsed the methods to make them all fit into one screen, but they are implemented.

gwt-mpv-apt has generated all the boilerplate code for us, and for an application which makes heavy use of events, this is a major time-saver.

Before going further, I must point out that this is based on an accepted Java standard – the Pluggable Annotation Processing API (JSR 269) – which is in my opinion one of the hidden gems in the Java Development Kit. The IDE support comes in for free, and as far as I know both Eclipse and NetBeans have good annotation processing support. In Eclipse, the annotation processor kicks in as soon as you save the file you’re working on and incrementally changes only the needed files. The integration with javac is also seamless – drop in the jar and it works.

Another good feature of this library is its error reporting: error markers are generated in the Eclipse editor just as they are reported to the compiler. This screenshot is an example of a wrongly named class, where the error marker is correctly placed on the class name:

The annotation processor currently has support for generating DTOs for gwt-dispatch and gwt-platform, and the savings are even more impressive. The left editor shows the code I wrote, while the right editors show the code which was generated. Even with folding enabled, I still can’t capture all the code.

I have shown how gwt-mpv-apt can help you reduce the amount of boilerplate code you write when working with GWT.  I encourage you to take it for a spin and let us know what you think about it. The project is still young, and it welcomes any contributions: feedback after usage, bug reports, testing, code contributions and spreading word are all appreciated. You can find more information at the GitHub project page, the GitHub issue tracker and the project mailing list.

Maven Recipe: Delivering applications as RPMs

In the Java world, the standard unit of delivery is the jar/war/(x)ar file. For applications which don’t fit the ‘single file’ delivery model, there is no standard alternative.  To provide a solution, I will show you how to package your application with Maven as an RPM.

As we are talking about Maven, the solution starts with finding the right plugin – in our situation the rpm-maven-plugin. We include the plugin as follows:

 <groupId>org.codehaus.mojo</groupId>
 <artifactId>rpm-maven-plugin</artifactId>
 <version>2.0.1</version>

The goal we need to execute is rpm – and it attaches itself to the package phase by default – so far so good.

The configuration that is usually done in a RPM spec file is done inside the plugin’s configuration block. First, we list some required descriptive elements:

<configuration>
  <copyright>2010, NoBody</copyright>
  <group>Development</group>
  <description>Maven Recipe: RPM Package.</description>

Now we get to the core of the RPM – listing the files to deploy. As we want to deploy our application’s classes and the ones from our dependencies, we create a mapping:

<mappings>
  <mapping>
    <directory>${app.home}/lib/</directory>
    <dependency/>
  <artifact/>
</mapping>

This is a very compact way of declaring that we want all dependencies – the dependency tag – and our primary build artifact – the artifact tag – to be deployed to the lib directory of our application.

The next step is to take the app.properties file which is checked into source control and deploy it as a sample file in the conf directory, so that we have a reference at hand when configuring the application:

<mapping>
  <directory>${app.home}/conf</directory>
  <configuration>true</configuration>
  <sources>
    <source>
      <location>${project.build.outputDirectory}/app.properties</location>
      <destination>app.sample.properties</destination>
    </source>
  </sources>
</mapping>

Using location and destination we have absolute control over what is included and where it is placed. Also note the usage of the configuration tag, which translates in to the %config RPM macro, which means that changes to the file are preserved when updating or removing RPM  ( details on the RPM %config macro ).

Last, we need to generate an empty logs directory for our application. This is done simply by declaring a mapping with no sources.

<mapping>
  <directory>${app.home}/logs</directory>
</mapping>

Right now we can build a RPM out of our application. I’ve added hibernate 3.3.2.GA as a dependency, since it brings in a few transitive dependencies.

robert@neghvar:~/workspace/rpm-package> mvn clean package
[INFO] Scanning for projects...                          
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Recipe: RPM Package                                      
[INFO]    task-segment: [clean, package]                                       
[INFO] ------------------------------------------------------------------------
.........
[INFO] Wrote: /home/robert/workspace/rpm-package/target/rpm/rpm-package/RPMS/rpm-package-0.0.1-SNAPSHOT20100520205409.noarch.rpm   
...........
[INFO] ------------------------------------------------------------------------                                                     
[INFO] BUILD SUCCESSFUL                                                                                                             
[INFO] ------------------------------------------------------------------------                                                     
[INFO] Total time: 5 seconds                                                                                                        
[INFO] Finished at: Thu May 20 23:54:11 EEST 2010                                                                                   
[INFO] Final Memory: 15M/174M                                                                                                       
[INFO] ------------------------------------------------------------------------

Let’s verify that the RPM file indeed contains all that we asked it to:

robert@neghvar:~/workspace/rpm-package> rpm -qlp /home/robert/workspace/rpm-package/target/rpm/rpm-package/RPMS/rpm-package-0.0.1-SNAPSHOT20100520205409.noarch.rpm
/opt/app/conf                                                                                                                                                      
/opt/app/conf/app.sample.properties                                                                                                                                
/opt/app/lib                                                                                                                                                       
/opt/app/lib/antlr-2.7.6.jar                                                                                                                                       
/opt/app/lib/commons-collections-3.1.jar                                                                                                                           
/opt/app/lib/dom4j-1.6.1.jar                                                                                                                                       
/opt/app/lib/hibernate-core-3.3.2.GA.jar                                                                                                                           
/opt/app/lib/jta-1.1.jar                                                                                                                                           
/opt/app/lib/rpm-package-0.0.1-SNAPSHOT.jar                                                                                                                        
/opt/app/lib/slf4j-api-1.5.8.jar                                                                                                                                   
/opt/app/lib/xml-apis-1.0.b2.jar                                                                                                                                   
/opt/app/logs

We have reached our goal of building an RPM with our applications dependencies, classes and configuration files. By using the rpm-maven-plugin we have managed to keep using Maven as our build tool interface, and also reused the information available in the POM file for declaring dependencies.

The complete source code for this article is available at http://github.com/rombert/Maven-Recipe–RPM-Package . If you have any suggestions or corrections, please comment. Or better yet, fork me.

Maven Recipe: Building an aggregate jar

Maven builds follow the “one project, one artifact” rule. This means that although it’s possible to build more than one artifact from a Maven project,  it’s not a good idea. It also means that while it’s also possible to build one artifact from multiple projects, it’s not entirely straightforward, and that’s what this post is about.

When refactoring a monolithic build into a modular one, often the downstream consumers are not prepared to consume multiple artifacts, so the build still needs to create a single jar with all the classes. This type of change is what I like to call build refactoring, similar to code refactoring. If code refactoring deals in restructuring an existing body of code, build refactoring aims to restructure an existing build.

Assuming that we have split a large project into multiple modules:

This high-complexity project used to contain two classes, but since they were unrelated we decided to split each into its own module.

When running mvn package, each module creates its individual jar:

robert@neghvar:~/workspace/aggregate-jar> mvn clean package                                                             
[INFO] Scanning for projects...  
(snip...)
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Maven Recipe: Aggregate jar ........................... SUCCESS [1.641s]
[INFO] Maven Recipe: Aggregate jar - first module ............ SUCCESS [2.066s]
[INFO] Maven Recipe: Aggregate jar - second module ........... SUCCESS [0.697s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Sat May 15 00:59:01 EEST 2010
[INFO] Final Memory: 23M/251M
[INFO] ------------------------------------------------------------------------

Inspecting the resulting jar files confirms this assertion:

robert@neghvar:~/workspace/aggregate-jar> find -name \*.jar
./aggregate-first-module/target/aggregate-first-module-1.0.0-SNAPSHOT.jar
./aggregate-second-module/target/aggregate-second-module-1.0.0-SNAPSHOT.jar

Of course, we can always use a custom shell command, or an ant file, or even the maven-antrun-plugin to combine the two jars. While easy to do correctly and even in a cross-platform manner,  the downside is that we lose the simplicity and modularity of a pure Maven build.

Following the “one project, one artifact” rule, it becomes clear that the solution is to add another project, which generates the distribution jar. We will add a new aggregate-dist module to the build, which will use the maven-assembly-plugin to combine the all resulting classes into a single jar. The module section therefore becomes

While the assembly plugin is well known and used, there are a few considerations which must be observed when aggregating the results of a multi-module build.

The distribution module should list the modules to assemble as dependencies:

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>aggregate-first-module</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>aggregate-second-module</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
 </dependencies>

The assembly plugin should be bound to the package lifecycle phase, and invoke the ‘single’ goal:

<plugin>

 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-assembly-plugin</artifactId>
 <version>2.2-beta-5</version>
 <executions>
 <execution>
 <id>package-all</id>
 <phase>package</phase>
 <goals>
 <goal>single</goal>
 </goals>
 <configuration>
 <descriptors>
 <descriptor>src/main/assembly/all-jar.xml</descriptor>
 </descriptors>
 </configuration>
 </execution>
 </executions>
 </plugin>

The assembly descriptor should include the unpacked non-transitive dependencies:


<assembly
 xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
 <id>all-jar</id>
 <formats>
 <format>jar</format> <!-- the result is a jar file -->
 </formats>

 <includeBaseDirectory>false</includeBaseDirectory> <!-- strip the module prefixes -->

 <dependencySets>
 <dependencySet>
 <unpack>true</unpack> <!-- unpack , then repack the jars -->
 <useTransitiveDependencies>false</useTransitiveDependencies> <!-- do not pull in any transitive dependencies -->
 </dependencySet>
 </dependencySets>
</assembly>

With this setup, we can invoke maven again:

robert@neghvar:~/workspace/aggregate-jar> mvn clean package                                                             
[INFO] Scanning for projects...  
(snip...)
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Maven Recipe: Aggregate jar ........................... SUCCESS [1.562s]
[INFO] Maven Recipe: Aggregate jar - first module ............ SUCCESS [1.315s]
[INFO] Maven Recipe: Aggregate jar - second module ........... SUCCESS [0.286s]
[INFO] Maven Recipe: Aggregate jar - distribution ............ SUCCESS [1.312s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Sat May 15 01:26:47 EEST 2010
[INFO] Final Memory: 23M/301M
[INFO] ------------------------------------------------------------------------

And indeed a third jar has been created

robert@neghvar:~/workspace/aggregate-jar> find -name \*.jar
./aggregate-first-module/target/aggregate-first-module-1.0.0-SNAPSHOT.jar
./aggregate-second-module/target/aggregate-second-module-1.0.0-SNAPSHOT.jar
./aggregate-dist/target/aggregate-dist-1.0.0-SNAPSHOT-all-jar.jar

We verify that it contains the two classes

robert@neghvar:~/workspace/aggregate-jar> jar tf aggregate-dist/target/aggregate-dist-1.0.0-SNAPSHOT-all-jar.jar | grep \.class
ro/lmn/maven/recipe/ClassOne.class
ro/lmn/maven/recipe/ClassTwo.class

At this point, we have achieved or goal. By creating a dedicated distribution module, we have isolated the packaging logic from the rest of the project, and used the maven-assembly-plugin to package the non-transitive dependencies, which we declared to be the modules to be packaged.

One indirect conclusion of this article is that, although Maven is convention-based and seemingly rigid ( or opinionated , to meet the buzzword quota per posting ), there are often idiomatic Maven solutions which solve unsual problems in an elegant way.

The complete source code for this article is available at http://github.com/rombert/Maven-Recipe—Aggregate-Jar . If you have any suggestions or corrections, please comment. Or better yet, fork me.

Mylyn-Mantis connector 3.1.2 released

A few bugs sneaked in the 3.1.1 release – which should’ve been named 3.2.0 due to its new features –  so 3.1.2  a small bugfix and stability release is now out.

Noteworthy fixes:

  1. All repository dates were incorrectly parsed . This also had the unpleasant side effect of always considering the tasks stale, which slowed operations a lot.
  2. We now properly retrieve and set the ‘assigned’ status for bugs. This is important for both non-English installations and for projects using custom statuses.

Mylyn-Mantis connector 3.1.1 released

This version is hot on the heels of Mantis 1.2.0 , therefore we build on the latest SOAP features added in that release.

Retrieve tasks using built-in filters

Up till now, retrieving tasks was only possible if you defined filters using the web interface. We now take advantage of recent bug fixes in MantisBT to retrieve the latest project tasks, without defining a project filter.

Due date integration

We now recognize and display the due date field if the repository supports it. Not only that, but the Mantis and Mylyn due dates are kept in sync. Note the due icon and the due date overlay

Basic time tracking integration

It is now possible to add time tracking information, but only if a comment text is added.

The time tracking information for an issue is also presented.

It is not yet possible to see time tracking information for each individual comment or to enter the time tracking in a more friendly format, but I plan to add these in the future.

Other improvements

  1. The People part has been tweaked to allow an assignee when creating a new issue and to allow un-assignment of an issue.
  2. The task editor page now has a submit button at the top and has the private section integrated into the Mantis page, instead of a separate one.
  3. An annoying bug where the plugin would install but fail at startup for older versions of Mylyn has been fixed.

For comments, bugs and support requests, our bug tracker and forums await you.

Mylyn-Mantis connector 3.1.0 released

The Mylyn-Mantis connector 3.1.0 brings new features and stability improvements. The highlight of this release is building on Mylyn’s  web services support to bring a more predictable model of interaction with the Mantis repositories.

Credentials dialog

We now build on the support offered by Mylyn to display a credentials dialog when access is denied for a SOAP operation.

mylyn-mantis-credential-prompt

Improved sub-projects display

Sub-projects are now clearly displayed in the new query page.

mylyn-mantis-subprojects

View state is editable

Up till now the view state was present, but hidden. This release changes it to be visible and editable.

Gracefully handle large number of users

The MantisBT SOAP API does not handle large numbers of users well, and public installations such as the official MantisBT tracker have in excess of 15,000 users. We now populate the users list with the developers and gradually add any users found as issue reporters or note authors when retrieving data.

Resynchronise only when necessary

Up till now, all repository configuration changes happening inside Eclipse triggered a repository configuration refresh. This included changes which did not really affect the repository state, such as recording the last synchronisation timestamp. From now on we re-create the repository state only when a relevant property has changed.

As always, our bug tracker and forums await you.

Mylyn-Mantis connector 3.0.6 released

UI improvements

The Steps to reproduce and Additional info fields are now collapsed if empty. This helps increase the information density when first opening the task editor.

rich-text-collapsed-by-default

Better support for internationalised Mantis installations

Until this release the connector was reading the task status as a string and looking for the harcoded default values. This broke both internationalised Mantis installations and those with custom workflows.

Now we do the right thing and compare the task status priority with the one defined in the Mantis installation, which means we behave exactly as the web interface does.

Mylyn-Mantis Connector 3.0.5 released

Custom field support

The headline for this release is custom fields are now supported. The fields are enabled by default and usable for both new task submissions and editing existing tasks. I’ve also enabled the ETA field to be a drop-down list.

mylyn-mantis-custom-fields

Filtered trees for project selection

Project selection for the new task wizard and new query wizard now use the more elegant filtered trees provided by the Mylyn project.

mylyn-mantis-new-task-page

mantis-new-query

Increased responsiveness

The new pages should feel much faster than the old ones since reviewing them has uncovered some unfounded assumptions which were costly performance-wise.

Minor fixes

I’ve also taken care of a few minor annoyances:

  1. Replying to comments now properly quotes the origin, instead of (null);
  2. It is now possible to attach more than one screenshot, and the user-submited names are respected;
  3. Mantis installations with more exotic access threshold  values don’t cause task retrieval failures;
  4. Repository configuration updates now have a more predictable progress rate;
  5. Bundle dependencies are now more carefully set, to assist integrators.

As always, our bug tracker and forums await you.