4

I know this question is not new. But it seems that there is no definite answer. This answer from 2012 states that if generated sources are placed under target/generated-sources/<tool> they will be compiled. ANTLR 4 maven plugin follows this paradigm. Per documentation, the default value of outputDirectory is: ${project.build.directory}/generated-sources/antlr4.

Now in my case I have a custom tool that generates sources. I've set its output directory to be at ${project.build.directory}/generated-sources/whatever and it didn't work. Regarding the whateverpart, I've tried to use the id of the goal that generates the sources and even tried to hijack antlr4 name. No result though.

When I try this solution that suggests using mojo build-helper-maven-plugin it compiles as expected. But according to maven guide to generating sources it should be working without any helper plugin, shouldn't it? Am I missing something?


Here is the POM (fragment) configuration that I use to generate the sources.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.4.0</version>
    <executions>
        <execution>
            <id>generate-code</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>java</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includeProjectDependencies>false</includeProjectDependencies>
        <includePluginDependencies>true</includePluginDependencies>
        <executableDependency>
            <groupId>com.company.product</groupId>
            <artifactId>CodeGenerator</artifactId>
        </executableDependency>
        <arguments>
            <argument>${basedir}/</argument>
            <argument>${project.build.directory}/generated-sources/generate-code/</argument>
        </arguments>
        <mainClass>com.company.codegeneration.CodeGenerator</mainClass>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>com.company.product</groupId>
            <artifactId>CodeGenerator</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>jar</type>
        </dependency>
    </dependencies>
</plugin>
Stelios Adamantidis
  • 1,866
  • 21
  • 36
  • Your plugin should add the source to the project It means your plugin should do it correctly like https://github.com/mojohaus/templating-maven-plugin – khmarbaise Nov 29 '19 at 16:39
  • 1
    BTW. do not use back-slashes within a pom file ...furthermore you should really create a correct plugin which can be bound to the life cycle like `generate-source` and handle that correctly. – khmarbaise Nov 29 '19 at 16:40
  • @khmarbaise to be honest, I didn't know what to do with the (back)slashes. Thanks for pointing it out. If your suggestion is creating a plugin please by all means post it as answer. I know there is already one, but as I already pointed to the poster, it's not stating explicitly "make a plugin or it won't work". – Stelios Adamantidis Nov 29 '19 at 17:35

1 Answers1

3

Your understanding is just a bit incorrect.

Nothing automatic, plugins generating source code typically handle that by adding their output directory (something like target/generated-sources/ by convention) as source directory to the POM so that it will be included later during the compile phase.

Some less well implemented plugins don't do that for you and you have to add the directory yourself, for example using the Build Helper Maven Plugin.

As the other answer noted, most plugins typically add the generated code as new source path.

Ex: See antlr4's Antlr4Mojo.java class. Here, the plugin is adding the generated classes to project source by calling addSourceRoot method in execute method.

    //  Omitted some code
  void addSourceRoot(File outputDir) {
            if (generateTestSources) {
                project.addTestCompileSourceRoot(outputDir.getPath());
            }
            else {
                project.addCompileSourceRoot(outputDir.getPath());
            }
          }


    //  Omitted some code

 @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
    //  Omitted code
        if(project!=null)

        {
            // Tell Maven that there are some new source files underneath the output
            // directory.
            addSourceRoot(this.getOutputDirectory());
        }
}
    //  Omitted some code

So, you can either do this in your custom plugin or use the build-helper-maven-plugin.

Ramu
  • 641
  • 6
  • 9
  • Hello Ramu and thanks for taking the time to answer. Though your answer raises more questions than it solves: do I need to create a plugin to make that work? Is there a way to have the same result as `project.addCompileSourceRoot(...);` call but manually added on the pom? I am trying to _understand_ not just have a _solution_ :) – Stelios Adamantidis Nov 29 '19 at 17:33
  • @SteliosAdamantidis Sorry for the confusion. When you said _I have custom tool_, I thought you were using a plugin that you have created and told you to add that code in your plugin code. If that is not the case, then you can use `build-helper-maven-plugin` which does the same thing. (i.e. Attaching the additional source roots by taking the source path(s) as parameter and then executes the `project.addCompileSourceRoot(...)` to attach all the paths passed to the plugin as ``. There is no other way to add the path directly on the pom. – Ramu Nov 29 '19 at 17:50
  • @SteliosAdamantidis In short, you don't need to create your own plugin just to add the newly generated path as source root. You can do that using `build-helper-maven-plugin`. If you are using a plugin that is developed by you, then you can add `project.addCompileSourceRoot(...)` to that plugin's execute method. You **can't** add the path without a plugin's help. – Ramu Nov 29 '19 at 17:59