Update sites in the P2 era

Lately I have built several update sites during Eclipse development – e.g. for the last release of the Debug Visualisation plugin, or some related to VIATRA2 based articles (maybe more details later). They have all one thing in common: they were not created using Update site projects.

In my experience since P2 came as a provisining platform the Update site projects were not the best available solutions: at first (in Ganymede) they did not produce everything P2 needed, while produced legacy information, that triggered a backward compatible mode in the provisining platform (officially the old Update managers site.xml should not be used). Even worse, I experienced some serious errors, when trying to add a new version of the already added plug-ins to the already built update site – in most cases the category definitions were removed (as in Galileo by default all features without category are hidden, this problem is quite serious).

On the other hand, not too long ago classic update sites were also needed to provide update sites for both the Update manager and P2. Today the Update Manager compatibility is not as crucial, as all Eclipse versions supported by eclipse.org use P2, so it is better to use some dedicated P2-based mechanism for Update site creation.

This mechanism is present since Eclipse 3.4 (at least from the command line, as documented in the Eclipse wiki), but is a bit hard to use. Recently I found a somewhat hidden option in the GUI, that provides the P2 metadata generation functionality – just as needed.

To use this, at least one (or possibly more) features are needed – the features are the minimum installable units. When the features are ready and the related plug-ins are attached, the Export wizard has to be invoked with the Deployable Features wizard from the Plug-in Development category.

The deployable features and the destination should be selected as needed (in my experience the directory export makes possible the easiest update site deployment, while the zipped archive allows the easiest direct transport – e.g. for dropins).

The export deployable features wizard in action
Export deployable features wizard

The P2-related magic should be initiated on the Options page: if the Generate metadata repository option is selected, as in the screenshot, during the export all metadata needed by P2 is generated.

For categorization of the repository a specific xml-file should be created: by creating a Category Definition from the New… wizard a simple form-based editor can be used to define categories for the installer, that can also be selected using the Export wizard.

Some additional tips and tricks related to the deployment:

  • To update existing P2-based update sites, simply point the export destination to the already existing update site. This updates the existing update site – I only tried this using the directory-based output.
  • To avoid runtime issues, make sure that the exported plug-in projects use the needed Java version compatibility in the project settings (e.g. if the manifest requires Java 1.5, make sure the project gets compiled in Java 1.5 compatibility mode), as the plug-ins are recompiled using these settings. I managed to get a Java 1.5 compatible project compiled with Java 1.6 compliance settings – the plug-ins even got installed, but did not work in the target computer, instead a hard to debug runtime exception is thrown.
  • It is possible to add source boundles by selecting the appropriate checkbox. On the other hand I couldn’t find a way to set the display name of the generated source bundles, and they are shown with the same name as the non-source plug-in, making it hard to distinguish between them during runtime. If you know the solution, please let me know.

In general, this export mechanism works well, without any major issues, I tested in repeatedly with several update sites. Unless for some reason Update manager compatibility is needed, I don’t recommend using Update site projects anymore – simply export your features to deploy.

What does the Eclipse of a Summer god mean a developer?

A month ago the Eclipse 3.6 shipped – again on time.

This is another evolutionary release – most components are binary compatible with the older ones, so the time of the migration was roughly equal to the download. All old favorites, such as Mylyn, EMF, etc. are updated, a lot of features were added, that makes development much easier. Some new components are also added, making a strong basis of the Eclipse eco-system.

The release features several improvements to the update mechanism, thus providing a whole new level of support for installing 3rd party plug-ins. These methods are based on the brand-new P2 provisioning API: the Modeling, Subversive or Mylyn Connector Discovery functions allows installing very specific plug-ins (making it easier to search for them), while the Eclipse Marketplace Client allows installing a wide selection of plug-ins (and this list keeps growing).

The Eclipse Marketplace Client allowing the installation of the Debug Visualisation plug-in
The Eclipse Marketplace Client in action

This solution is great, because I don’t have to remember/google for the various update site urls, and then manually select the features – if I don’t want to. If for whatever reason I need the specific knowledge, the “old” P2 user interface is still available.

A minor, but welcome addition is to the P2 interface the reliable cache clearing mechanism. It comes in handy when testing a new update site.

The Helios release is full of other gems, such as the graduated Xtext 1.0 with its new builder support, or the enhanced Variables and Breakpoints views in the Debug perspective.

My other favorite feature is the enhanced Cocoa-64 bit support for OSX – its performance/resource consumption is greatly improved, while the Dock icon overlays are also helpful (e.g. I can monitor the status a long-running task, while using another application).

Short text overlay over the dock icon

Alltogether, the new release contains quite a few enhancements, that help the developers to provide better software using the framework, while maintaining the compatibility with older releases, thus making the switch easy (and possibly cheap) to do. I can hardly await the next (Indigo) release, and I’m looking forward to the new ideas of the e4 project.

Here it is: Debug Visualisation 0.8.0

After several months of (more or less) active development we are proud to introduce our latest and greatest release of the Debug Visualisation Eclipse plug-in.

The changes are three-folds in this release: first, a view model is defined for the visualisation. This one is only interesting for us, developers, as it enables us to store calculated data together with the referenced variable or value, making it easier to produce new features in later releases.

The other changes are more visible: we integrated our approach with the debug platform: it is possible to add variables to the visualisation by using the context menu of the Variables View. For similar reasons, our custom filter implementation was replaced with the platform-defined logical structures. This means, more specific filters are available, and it is possible (at least for Java) for the user to define more in the corresponding Eclipse preferences page (Java/Debug/Logical Structures).

These stuctures provide a way to removed some (possibly) irrelevant variables from the visualisation, as it is possible to define on a per-type basis the relevant structure (and it is also possible to define multiple structures for the same type, allowing the user to choose between them).

These structures can be selected from the context menu of the values in the Visualisation view. Such a possible selection is depicted on the following screenshot:

In the context menu it is possible to select both the Raw structure and the Array structure.
Logical structure selection for an ArrayList

Warning: the logical structure selection is (and possibly will) not synchronized with the variables view.

Finally, some internal changes were made to ensure, the plug-in is easier to use, such as the ability to define custom orderings for some layouts.

For a list of all fixed issues visit our issue tracker.

The new release can be downloaded from our update site right now (http://eclipse.cubussapiens.hu), and hopefully shortly also from the Eclipse Marketplace.

Update: Detailed project information is available from our Google Code project page.

Update2: The new release is available (and installable) from the Eclipse Marketplace.

Enabling documentation comments in LPG parsers

Sometimes I fell, using LPG parsers is like balancing between the fine line of total madness and fine, easy results. The results are (often) fine, as the generator produces a good enough parser, with error recovery mechanisms and similar (I don’t want to compare it with other generators), but sometimes the lack of documentation can be prohibiting.

A problem I wanted to use documentation comments and multiline comments in a Java-like syntax (so /* comment */ describes a comment, while /** comment */ describes a documentation comment). I tried to find either examples or documentation about the solution to this problem, but couldn’t find any (at least until recently).

The solution consists of two parts: the lexer should be capable of differentiating between the two comment types (it should be able to emit the corresponding tokens), and then either the parser or the resolver should be able to read the comments.

Lexing issues

The first problem is hard, as we have to create the rules describing the comment tokens in a constructive way: there is no inversion, and it is better if the two rules are non-conflicting. The basic solution works like the following: a multiline comment starts with two characters, '/' and '*', followed by a not-star character, then followed as a series of character series not consisting of the ending '*''/' tag.

So far it sounds easy, but the grammar language of the LPG generator does not support inverse. Luckily we have a finite alphabet, so the number of two character long series are also finite, which means, it is possible to write the previously mentioned system in a constructive way:

doc ::= '/' '*' '*' CommentBody Stars '/'
mlc ::= '/' '*' NotStar CommentBody Stars '/'
CommentBody$$CommentBody ::= CommentBody Stars NotSlashOrStar |
CommentBody '/' | CommentBody NotSlashOrStar |
Stars NotSlashOrStar | '/' | NotSlashOrStar

NotSlashOrStar ::= letter | digit | whiteChar | AfterASCII |
'+' | '-' | '(' | ')' | '"' | '!' | '@' | '`' | '~' | '.' |
'%' | '&' | '^' | ':' | ';' | "'" | '\' | '|' | '{' | '}' |
'[' | ']' | '?' | ',' | '<' | '>' | '=' | '#' | '$' | '_'

Yes, quite hard to write, and even harder to understand first, but at least it is working.

Parsing the comments

After the lexer understands the comments, the parser needs also to be aware of them. A (seemingly) easy way to handle this is the following: the multiline comment is exported in the lexer as a comment token, while the documentation comment is exported as a simple token. After this the parser could include references to documentation comments and handled similary to all other tokens.

On the other hand, the approach has a serious drawback: the documentation comment is not a comment, so it cannot be placed anywhere, as it is limited by the grammar language. At first this looks not a too big problem, but there could be several problems: first, if you are enhancing an existing language, this could break some texts – possibly created by other users – and the default error message is hard to understand. The second problem is the following: the system disallows having long lines of stars at the beginning of the simple multiline comments, as in the following snippet:

/*********************
*                    *
*  Comment in a box  *
*********************/

Why: the comments are not started with two or more star characters, so this block is interpreted as a block comment.

If these problems cannot be ignored, both the comments and documentation comments shall be marked as comment tokens, that are swallowed by the lexer, the parser does see any comment tokens (as it should be). The drawback of this approach is that the position of the documentation comments cannot be controlled in the parser – so the handling has to ignore the documentation comments at invalid locations.

A final step is needed to read these documentation comments: they have to be read, but they are not present in the AST – at least directly. On the other hand, following the tip from the presentation the EclipseCon 2009 Tutorial: “PIMP Your Eclipse: Building an IDE using IMP” preceding adjuncts of an AST node can be read. This terminology was not clear for me, and the missing Javadoc was neither helpful, so this tutorial was a great help.

To tell the truth, I am interested in the correct meaning of the definition used in LPG for adjuncts, but as much I know, the comment tokens are included in it – in their raw form. This raw form means, every character, including whitespaces, starting and ending characters are included, so they might need another parsing step with a different grammar.

But for a short handling, the following code can be used to read the first documentation comment before an element:

public String parseDocComments(ASTNode node) {
  IToken[] adjuncts = node.getPrecedingAdjuncts();
  for (IToken adjunct : adjuncts) {
    String adjString = adjunct.toString();
    if (adjString.startsWith("/**")) {
      return adjString;
    }
  }
  return null;
}

 

Conclusion

To allow the use of documentation comments can be quite a bit of challange, especially getting the syntax right, without any conflict between rules, but it is certainly possible.

On the other hand, the language of documentation comments has to be defined again, where even the lexer could not be reused from the original grammar, as it uses different terminal rules (e.g. the documentation comment shall not be a comment token in this language). Even worse, having two different grammars makes it harder to provide correct coding help from the IDE (e.g. content assist, source coloring, etc.). These ways need further experimenting with the tools, but at least the solution is working right now.

Short story of the day

Never, I mean never write code like this:

boolean isRel1 = false, isRel2 = false;
if((isRel1 = element1 instanceof IRelation)
|| (isRel2 = element2 instanceof IRelation)){
...
}

Especially do not use such code in comparators. If not at first try, than later it will mess up things badly, as you rely on the variable, that will not be set because of the evaluation optimization.

This fact cost me three or four hours today…

A better solution (for those who look for usable code snippets):

boolean isRel1 = element1 instanceof IRelation;
boolean isRel2 = element2 instanceof IRelation;
if(isRel1 || isRel2) {
...
}