maven-antrun-plugin: generate sources for protobuf

2019-07-25 21:04发布

问题:

I have the following plugin in my pom.xml, which is supposed to generate java files required for the compilation of other projects:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.2</version>
    <configuration>
        <source>${jdk.version}</source>
        <target>${jdk.version}</target>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <archive>
            <manifestFile>META-INF/MANIFEST.MF</manifestFile>
        </archive>
    </configuration>
</plugin>
<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                <tasks>
                    <mkdir dir="src-gen" />
                    <exec executable="protoc">
                        <arg value="--java_out=src-gen" />
                        <arg value="proto/ros/RosTime.proto" />
                        <arg value="proto/ros/RosHeader.proto" />
                        <arg value="proto/ros/RosPoint.proto" />
                        <arg value="proto/ros/RosPose.proto" />
                        <arg value="proto/ros/RosPoseStamped.proto" />
                        <arg value="proto/ros/RosQuaternion.proto" />
                        <arg value="proto/U.proto" />
                        <arg value="proto/S.proto" />
                        <arg value="proto/Z.proto" />
                        <arg value="proto/algorithm/A.proto" />
                        <arg value="proto/algorithm/B.proto" />
                        <arg value="proto/algorithm/C.proto" />
                        <arg value="proto/algorithm/D.proto" />
                        <arg value="proto/algorithm/E.proto" />
                        <arg value="proto/algorithm/F.proto" />
                        <arg value="proto/env/G.proto" />
                        <arg value="proto/env/H.proto" />
                        <arg value="proto/env/J.proto" />
                        <arg value="proto/env/K.proto" />
                        <arg value="proto/env/L.proto" />
                    </exec>
                </tasks>
                <sourceRoot>src-gen</sourceRoot>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

However, this does not generate anything at all, under src-gen folder. And then I keep getting errors such as :

    cannot find symbol
[ERROR] symbol:   class AMsg
[ERROR] location: class project.messages.AFormatter

and

package project.messages.ros.RosHeader does not exist
package project.messages.ros.RosPoint does not exist
package project.messages.ros.RosPose does not exist
package project.messages.ros.RosPoseStamped does not 

basically it cannot find the necessary files, naturally, and gives error. I have the 2.5.0 version installed already, and the dependency is defined correctly:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>2.5.0</version>
</dependency>

I've ran out of ideas. What is really making this not working?

EDIT: The following took my attention in the debug output of mvn install -X :

Execute:Java13CommandLauncher: Executing 'protoc' with arguments:

'--java_out=src-gen'
'proto/ros/RosTime.proto'
'proto/ros/RosHeader.proto'
'proto/ros/RosPoint.proto'
'proto/ros/RosPose.proto'
'proto/ros/RosPoseStamped.proto'
'proto/ros/RosQuaternion.proto'
 .
 .
 .
 . 
The ' characters around the executable and arguments are
not part of the command.
     [exec] ros/RosTime.proto: File not found.
     [exec] proto/ros/RosHeader.proto: Import "ros/RosTime.proto" was not found or had errors.
     [exec] proto/ros/RosHeader.proto:6:14: "project.messages.ros.RosTimeMsg" seems to be defined in "proto/ros/RosTime.proto", which is not imported by "proto/ros/RosHeader.proto".  To use it here, please add the necessary import.
  .
  .  
  .
     [INFO] --- maven-antrun-plugin:1.3:run (generate-sources) @ X.messages ---
[DEBUG] org.apache.maven.plugins:maven-antrun-plugin:jar:1.3:
[DEBUG]    org.apache.maven:maven-plugin-api:jar:2.0.4:compile
[DEBUG]    org.apache.maven:maven-project:jar:2.0.4:compile
[DEBUG]       org.apache.maven:maven-settings:jar:2.0.4:compile
[DEBUG]       org.apache.maven:maven-profile:jar:2.0.4:compile
[DEBUG]       org.apache.maven:maven-model:jar:2.0.4:compile
[DEBUG]       org.apache.maven:maven-artifact-manager:jar:2.0.4:compile
[DEBUG]          org.apache.maven:maven-repository-metadata:jar:2.0.4:compile
[DEBUG]       org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9:compile
[DEBUG]          junit:junit:jar:3.8.1:compile
[DEBUG]          classworlds:classworlds:jar:1.1-alpha-2:compile
[DEBUG]    org.apache.maven:maven-artifact:jar:2.0.4:compile
[DEBUG]    org.codehaus.plexus:plexus-utils:jar:1.5.6:compile
[DEBUG]    org.apache.ant:ant-launcher:jar:1.7.1:runtime
[DEBUG]    org.apache.ant:ant:jar:1.7.1:compile
[DEBUG] Created new class realm plugin>org.apache.maven.plugins:maven-antrun-plugin:1.3
[DEBUG] Importing foreign packages into class realm plugin>org.apache.maven.plugins:maven-antrun-plugin:1.3
[DEBUG]   Imported:  < project>runtime_shared:art.util.robot:1.0.0
[DEBUG] Populating class realm plugin>org.apache.maven.plugins:maven-antrun-plugin:1.3
[DEBUG]   Included: org.apache.maven.plugins:maven-antrun-plugin:jar:1.3
[DEBUG]   Included: junit:junit:jar:3.8.1
[DEBUG]   Included: org.codehaus.plexus:plexus-utils:jar:1.5.6
[DEBUG]   Included: org.apache.ant:ant-launcher:jar:1.7.1
[DEBUG]   Included: org.apache.ant:ant:jar:1.7.1
[DEBUG]   Excluded: org.apache.maven:maven-plugin-api:jar:2.0.4
[DEBUG]   Excluded: org.apache.maven:maven-project:jar:2.0.4
[DEBUG]   Excluded: org.apache.maven:maven-settings:jar:2.0.4
[DEBUG]   Excluded: org.apache.maven:maven-profile:jar:2.0.4
[DEBUG]   Excluded: org.apache.maven:maven-model:jar:2.0.4
[DEBUG]   Excluded: org.apache.maven:maven-artifact-manager:jar:2.0.4
[DEBUG]   Excluded: org.apache.maven:maven-repository-metadata:jar:2.0.4
[DEBUG]   Excluded: org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9
[DEBUG]   Excluded: classworlds:classworlds:jar:1.1-alpha-2
[DEBUG]   Excluded: org.apache.maven:maven-artifact:jar:2.0.4
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-antrun-plugin:1.3:run from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-antrun-plugin:1.3, parent: sun.misc.Launcher$AppClassLoader@5c647e05]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-antrun-plugin:1.3:run' with override configurator -->
[DEBUG]   (f) pluginArtifacts = [org.apache.maven.plugins:maven-antrun-plugin:maven-plugin:1.3:, junit:junit:jar:3.8.1:compile, org.codehaus.plexus:plexus-utils:jar:1.5.6:compile, org.apache.ant:ant-launcher:jar:1.7.1:runtime, org.apache.ant:ant:jar:1.7.1:compile]
[DEBUG]   (f) project = MavenProject: runtime_X:X.messages:1.0.0 @ /home/usr/workspace_runtime_X/X.messages/pom.xml
[DEBUG]   (f) sourceRoot = /home/usr/workspace_runtime_X/X.messages/src-gen
[DEBUG]   (f) tasks = 
[DEBUG] -- end configuration --

回答1:

When in doubt about files not getting created, make sure you use absolute path. In this case, ${basedir} allows us to get the absolute path to the location of the Maven base directory (location of POM):

<mkdir dir="${basedir}/src-gen" />
<exec executable="protoc">
    <arg value="--java_out=${basedir}/src-gen" />
    <arg value="--proto_path=${basedir}" /> <!-- proto_path needs to point to where the proto files are -->
    <arg value="proto/ros/RosTime.proto" />
    <!-- rest of proto files... -->
</exec>

Then, note that the <sourceRoot> parameter of the maven-antrun-plugin is deprecated:

Deprecated. Use the build-helper-maven-plugin to bind source directories

As recommended, you should use the build-helper-maven-plugin:add-source goal to add a source folder to your Maven project. Configure the folders to add with the sources parameter of that goal.


Having said that, you might have better chance using the org.xolstice.maven.plugins:protobuf-maven-plugin instead of relying on Ant tasks:

Maven Protocol Buffers Plugin uses Protocol Buffer Compiler (protoc) tool to generate Java source files from .proto (protocol buffer definition) files for the specified project.

The compile goal can be used to generate the Java source files. Placing your .proto files under src/main/proto (configurable with the protoSourceRoot parameter), the plugin will generate the Java source files inside ${project.build.directory}/generated-sources/protobuf/java (configurable with the outputDirectory parameter).

In case the protoc executable isn't in the PATH environment variable, you can set it with the protocExecutable parameter.