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