Maven: Java classes don't compile after Ant task

My project generates source code using the Rats! parser generator. Rats! doesn't have a Maven plugin that I'm aware of, so I'm trying to build the parser using an Ant Java task, like so:

 <plugin>
   <artifactId>maven-antrun-plugin</artifactId>
   <executions>
     <execution>
       <phase>generate-sources</phase>
       <configuration>
         <tasks>
           <mkdir dir="${project.build.directory}/generated-sources/main/java/" />
           <java classpath="lib/xtc.jar" classname="xtc.parser.Rats">
             <arg line="-in ${project.build.sourceDirectory}" />
             <arg line="-out ${project.build.directory}/generated-sources/main/java/" />
             <arg path="${project.build.sourceDirectory}/Dot.rats" />
           </java>
         </tasks>
         <sourceRoot>
           ${project.build.directory}/generated-sources/main/java
         </sourceRoot>
       </configuration>
       <goals>
         <goal>run</goal>
       </goals>
     </execution>
   </executions>
 </plugin>

The details of what Rats! does aren't important: the end result is that the above generates Dot.java and places it in target/generated-sources/main/java . It works fine.

The problem is that, with this plugin element in my pom.xml , none of the Java files in the project get compiled.

I generated a project using " mvn archetype:create -DgroupId=foo -DartifactId=bar " and added the file src/main/java/Dot.rats :

module Dot;

public void Dot = "." !_ ; 

(This is a grammar that accepts only files with a single dot.)

If I run " mvn compile " without the plugin element, I get:

$ mvn compile
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building bar
[INFO]    task-segment: [compile]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to
/home/chris/src/tests/maven/project1/bar/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Wed Jul 01 18:57:08 EDT 2009
[INFO] Final Memory: 6M/67M
[INFO] ------------------------------------------------------------------------

Where the one Java file being compiled is src/main/java/foo/App.java , a Java class created by the archetype (ie, not a generated source file).

If I do " mvn clean " then add the plugin element invoking Rats!, I get:

$ mvn compile
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building bar
[INFO]    task-segment: [compile]
[INFO] ------------------------------------------------------------------------
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
   [mkdir] Created dir:
/home/chris/src/tests/maven/project1/bar/target/generated-sources/main/java
Rats! Parser Generator, v. 1.14.2, (C) 2004-2008 Robert Grimm
Processing /home/chris/src/tests/maven/project1/bar/src/main/java/Dot.rats ...

Ie, Maven is running Rats! (which is not failing, AFAICT) but not compiling any Java classes, not even the pre-existing class App.java . After the run, I have target/generated-sources/main/java/Dot.java but no target/classes .

I've tried other kinds of Ant tasks and they don't interfere with Java compilation. For example, if I replace the task element above with an echo task

<tasks>
  <mkdir dir="${project.build.directory}/generated-sources/main/java/" />
  <echo file="${project.build.directory}/generated-sources/main/java/Dot.java">
     public class Dot { }
  </echo>
</tasks>

I get

$ mvn compile
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building bar
[INFO]    task-segment: [compile]
[INFO] ------------------------------------------------------------------------
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
[INFO] Executed tasks
[INFO] Registering compile source root
/home/chris/src/tests/maven/project1/bar/target/generated-sources/main/java
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 2 source files to
/home/chris/src/tests/maven/project1/bar/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Wed Jul 01 19:03:34 EDT 2009
[INFO] Final Memory: 7M/79M
[INFO] ------------------------------------------------------------------------

Obviously there's something I'm not understanding about how Maven executes the java task. Is there something simple that I'm doing wrong? Is there an alternative way to accomplish this task that I should try (perhaps a more "Maven-native" way)?

[UPDATE] Funny story. I tried replacing the Ant task with a Maven plugin, by writing a RatsMojo class that invokes xtc.parser.Rats directly and replacing the plugin element above with

  <plugin>
    <groupId>edu.nyu.xtc</groupId>
    <artifactId>maven-xtc-plugin</artifactId>
    <executions>
      <execution>
        <phase>generate-sources</phase>
        <goals>
          <goal>rats</goal>
        </goals>
        <configuration>
          <inputDirectory>${project.build.sourceDirectory}</inputDirectory>
          <outputDirectory> ${project.build.directory}/generated-sources/main/java</outputDirectory>
          <grammarFile>${project.build.sourceDirectory}/Dot.rats</grammarFile>
        </configuration>
      </execution>
    </executions>
  </plugin>

It does the exact same thing: it runs Rats! then terminates without compiling any of the Java files in the project.


The problem seems to be that Rats! calls System.exit() (or similar), terminating the JVM. I would have thought that Ant would wrap this (the java task is copied over from a build.xml and it doesn't terminate the Ant build), but the following works by forcing the Rats! process into a separate JVM:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.1</version>
  <executions>
    <execution>
      <phase>generate-sources</phase>
      <goals>
        <goal>exec</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <executable>java</executable>
    <arguments>
      <argument>-classpath</argument>
      <argument>${basedir}/lib/xtc.jar</argument>
      <argument>xtc.parser.Rats</argument>
      <argument>-in</argument>
      <argument>${project.build.sourceDirectory}</argument> 
      <argument>-out</argument>
      <argument>${project.build.directory}/generated-sources/main/java/</argument>
      <argument>${project.build.sourceDirectory}/Dot.rats</argument>
    </arguments>
  </configuration>
</plugin>

or, just add fork="true" to the java task in the antrun plugin.


You need to add the new directory to the maven source directories. It can be done using the buildhelper-maven-plugin. Add this to your pom:

  <build>
   <plugins>
     <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>add-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>${project.build.directory}/generated-sources/main/java/</source>
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
链接地址: http://www.djcxy.com/p/60658.html

上一篇: 如何以编程方式从pom.xml执行特定的插件/ Mojo?

下一篇: Maven:Java类不会在Ant任务之后编译