Maven only generates Antlr-sources in default package
Asked Answered
C

2

12

I'll start with my pom.xml:

<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">
<modelVersion>4.0.0</modelVersion>

<groupId>HPK</groupId>
<artifactId>WRB</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>WRB</name>
<url>http://maven.apache.org</url>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.antlr</groupId>
        <artifactId>antlr4</artifactId>
        <version>4.5.3</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-clean-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <id>auto-clean</id>
                    <phase>initialize</phase>
                    <goals>
                        <goal>clean</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-maven-plugin</artifactId>
            <version>4.3</version>
            <executions>
                <execution>
                    <configuration>
                        <arguments>
                            <argument>-visitor</argument>
                            <argument>-package</argument>
                            <argument>wrb.grammar</argument>
                        </arguments>
                    </configuration>
                    <id>antlr</id>
                    <goals>
                        <goal>antlr4</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <pluginManagement>
        <plugins>
            <!--This plugin's configuration is used to store Eclipse m2e settings 
                only. It has no influence on the Maven build itself. -->
            <plugin>
                <groupId>org.eclipse.m2e</groupId>
                <artifactId>lifecycle-mapping</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <lifecycleMappingMetadata>
                        <pluginExecutions>
                            <pluginExecution>
                                <pluginExecutionFilter>
                                    <groupId>
                                        org.apache.maven.plugins
                                    </groupId>
                                    <artifactId>
                                        maven-clean-plugin
                                    </artifactId>
                                    <versionRange>
                                        [3.0.0,)
                                    </versionRange>
                                    <goals>
                                        <goal>clean</goal>
                                    </goals>
                                </pluginExecutionFilter>
                                <action>
                                    <ignore></ignore>
                                </action>
                            </pluginExecution>
                        </pluginExecutions>
                    </lifecycleMappingMetadata>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

When I run maven install on this project, maven should generate the sources from the antlr4 plugin within the wrb.grammar package, but it doesn't. It does everything, but put the sources into those directories, it simply puts them in what it calls the "default-package", which is just the root of antlr/generated-sources.

If I use the Antlr4IDE-plugin by right clicking the grammar and selecting it under run as, the sources are generated in the right directory.

Another person I'm working with on this small project has no problem using maven-install. Besides our operating systems and eclipse versions, everything is the same.

I'm using Eclipse Oxygen on MacOS.

What am I doing wrong that the maven-plugin doesn't generate my desired directory?

Casa answered 17/10, 2017 at 19:52 Comment(4)
Where exactly did you place your grammar files? According to the plugin docs you need put them in the same directory hierarchy that you expect the resulting source files to be in. So your grammar should be in src/main/antlr4/wrb.grammar. I do not think that you need the -package argument.Buttaro
I made a mistake with the path: it should be src/main/antlr4/wrb/grammarButtaro
@ChristophBöhme Thank you, that did indeed place any generated files into that package. Still wondering why there is the option to call antlr with a -package-option when it does not work as expected in maven.Casa
Great that this worked. I turned my comment into an actual answer and also added some details on what the -package option actually does. Hope, this helps.Buttaro
T
9

I have checked the sources of antlr4 version 4.3. The -package parameter is only used by the code generator templates but not anywhere in the actual tool source code (seeGithub search results for genPackage). So it cannot have an effect on the location of the output files.

Instead, the location of each output file is determined based on the location of the corresponding input file (see here and here in the sources). This is fits with the explanation in the maven plugin docs:

If your grammar is intended to be part of a package called org.foo.bar then you would place it in the directory src/main/antlr4/org/foo/bar. The plugin will then produce .java and .tokens files in the output directory target/generated-sources/antlr4/org/foo/bar When the Java files are compiled they will be in the correct location for the Javac compiler without any special configuration. The generated java files are automatically submitted for compilation by the plugin.

Additionally, when using the antlr4-maven-plugin it is not necessary to specify the -package option. As the plugin derives the value of the -package paramter from the input file path and automatically adds it to the antlr invocation (see here in the sources). That is probably also the reason why -pacakge is not directly available as a configuration parameter in the maven plugin.

Solution

In order to have the generated files placed in a directory structure that matches your package names, you need to use the same structure for the input files.

Essentially, all you need to do is to put your grammar files in src/main/antlr4/wrb/grammar, remove the -package parameter from the configuration and it everything work as expected.

By the way: instead of writing

<arguments>
   <argument>-visitor</argument>
</arguments>

you could simply write

<visitor>true</visitor>

since this parameter is directly understood by the antlr4-maven-plugin.

Tica answered 25/10, 2017 at 19:28 Comment(2)
For that to work I also needed <sourceDirectory>${basedir}/src/main/java</sourceDirectory> in the plugin configuration.Alfilaria
I did not need the source directory in the plugin config. but it is years later. still this is the only correct answer to the issue I found. Thank You!!! BTW this fixed my vscode issues not finding the generated classes.Cloots
T
0

As @ChristophBöhme wrote in the comments of your question, you have to place the grammar file in exactly the same package as you want your generated sources to appear. It has nothing to do with your pom.xml file actually.

ANTLR tries to figure out the package name by looking at the folder tree, so if you have a folder called com containing a folder called example containing a folder called hello_world, that is going to form the package com.example.hello_world and it will make exactly the same folder structure and package in the output folder.

So if your package is called com.example.hello_world, then your directory structure has to look like this, assuming that your grammar files are located in src/main/antlr4:

hello_world (root project folder)
|
--src
  |
  -- main
   |
   -- antlr4 (up to here, these are "verbatim" folders)
    |
    -- com.example.hello_world (this is a package, to create it you can make a "source folder" in Eclipse)
     |
     -- YourGrammar.g4
|
-- target (autogenerated)
 |
 -- generated_sources
  |
  -- antlr4
   |
   -- com.example.hello_world
    |
    -- ...All ANTLR-generated files...
  
Terminus answered 14/9, 2023 at 10:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.