Setting up Eclipse and Maven is getting easier, but some cases require a bit more search and work. As I was experimenting with the ANTLR Maven plugin, I found the default behaviour to be pretty much useless: Eclipse knew nothing about the grammar files or the generated classes, so the rest would not compile; even after adding the relevant source folders I still had to run explicit Maven commands after modifying the grammar files and refresh the workspace…
I eventually found a better way, which I document here.
There is an antlr3-maven-archetype, which I started from. However, for the purpose of clarity, I will start from scratch here.
Installing m2e
The Maven plugin for Eclipse is called m2e (m2eclipse is an obsolete version), and is available in the default Eclipse Marketplace. However, the current version (1.0 at the time of writing) does not handle the life cycle of some common Maven plugins very well. In particular, it does not know where to put the generation of classes from grammar files into the Eclipse life cycle.
The 1.1 milestone does it much better, so I suggest to install it. The location is http://download.eclipse.org/technology/m2e/milestones/1.1, which can be used for the “Install New Software” function.
Creating a project with ANTLR
Create a new Maven Project, and skip the archetype selection (i.e. use simple project). As I said above, I could use the ANTLR v3 archetype, but chose not to.
Optional: set the target option
By default Maven uses compiler source and target version 1.5. On Mac
OS X Lion, there is no JDK 1.5 (only 1.6), so I always update pom.xml
to set the source
and target
configuration options to something
meaningful:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Add ANTLR plugin
I create a property for the ANTLR version, as I will need for both the ANTLR plugin and the jar:
1 2 3 |
|
Then I add the plugin declaration
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Finally I add the dependency to the ANTLR runtime:
1 2 3 4 5 6 7 |
|
At this stage, Eclipse is upset because the lifecycle configuration
org.antlr:antlr3-maven-plugin:3.4:antlr
is not covered. But as we’re
using m2e 1.1, we can look for the appropriate connector in the m2e
Marketplace. There should be only one: antlr by Sonatype, which should
be installed.
Packaging the ANTLR runtime with the code
This is something that the original ANTLR v3 Maven archetype suggests: to include the ANTLR runtime into the generated jar.
Using the Maven Assembly Plugin, it is possible to declare what goes into the generated jar. As it is self-contained, it is also possible to declare a main class (not done below as I did not have a main class yet):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Tuning the Eclipse project
Now, the ANTLR plugin can process code under
src/main/antlr3
, so we can create this folder, and add it as source
folder in the Eclipse project properties. Creating or updating a
grammar file in Eclipse will also create or update
The ANTLR connector also added the target/generated-sources/antlr3
directory as another source folder, but it will disappear when
executing the Maven/Update Project Configuration action, so it is best
to add it manually. You can then change the properties for this folder
to check ‘Locked’ (to avoid accidental edition) and ‘Derived’ (to hide
the content from the “Open Resource” command).
Note that the plugin is unable to follow the @header
directive
properly (that is, it will copy the directory structure of the grammar
file, instead of following the directory structure implied by the
@header
directive), so the grammar files must use the same directory
structure as the Java package intended for the generated classes. In
other words, if you want your generated classes to have the package
org.something
, you both need to put the grammar files under
src/main/antlr3/org/something
, and use the @header package
directive to set the package of the generated classes.
It is also unable to handle grammar files directly under
src/main/antlr3
. If you try, it will generate this error: “error(7):
cannot find or open file: null/NestedNameList.g” when running the
process-sources
goal. Running this goal is also the only way to get
the error message if something is wrong with the grammar file (unless
you install an ANTLR Eclipse plugin, which I didn’t try).
Small gotcha: I found that with the current version of plugins, connectors and so on, Eclipse does not detect changes to generated classes directly: it is always one change behind, especially when there are errors.
If you made a mistake in the grammar file that causes the generated classes not to compile anymore, you would have to change the grammar file twice for the error markers to go away; the first time, Eclipse will correctly report that the errors in the classes are gone, but the project error markers will stay; the second change (even if you changed nothing, just add a character, delete it, and save), and the error markers will finally disappear.
This is more annoying than really a serious problem, and in any case the files are always properly generated, so if there is no error, all files are kept up-to-date.
Automating the above steps
If you include the build-helper-maven-plugin
plugin in your
pom.xml
, then it is possible to automatically add the relevant
source folders to Eclipse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
To use it, another connector is necessary, but it is found directly in the m2e Marketplace.
Once in the pom.xml
, just importing the project into Eclipse will
create the relevant source folders automatically. However the ‘Locked’
and ‘Derived’ flags on the target/generated-sources/antlr3
folder
are stored in the workspace .metadata
, so these flags have to be set
manually for each workspace.
The easier way
If all the above seems tedious, it is because it is. The
antlr3-maven-archetype
will generate much of it, but not for
instance the additional source folders.
I have the kind of laziness that causes me to spend hours trying to save a few minutes later on, so I created my own archetype, a trivial little thing whose only purpose is to get the basic setup in place quickly.
It does not really do much, and perhaps should best seen as a template, which is why the best use is to download it, adjust it to your own need, then install it locally.
Hope this helps.