问题
I want to make my Maven build fail when I forget to declare serialVersionUIDs in a Serializable
class. With javac
, that's easy:
$ javac -Xlint:serial -Werror Source.java
Directly translating that to Maven doesn't work:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<compilerArgument>-Xlint:serial -Werror</compilerArgument>
</configuration>
</plugin>
The compilerArgument
is quoted, so javac
receives only one argument, containing -Xlint:serial -Werror
, instead of -Xlint:serial
and -Werror
as separate arguments. So you read the docs, and find compilerArguments
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<compilerArguments>
<Xlint:serial />
<Werror />
</compilerArguments>
</configuration>
</plugin>
This looks weird - the colon makes serial
element in the Xlint
namespace, which isn't declared anywhere - but it works... until you want to do a release:
$ mvn release:prepare
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.3.2:prepare (default-cli) on project my-project: Error reading POM: Error on line 58: The prefix "Xlint" for element "Xlint:serial" is not bound.
Apparently, the regular POM reader handles XML namespaces in another way than the one used by the release plugin.
So how do I pass javac
multiple command-line switches when some of those switches contain characters which aren't valid for plain XML elements, without breaking the release plugin?
回答1:
See http://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#compilerArgs
and http://maven.apache.org/plugins/maven-compiler-plugin/examples/pass-compiler-arguments.html
Maven 3.1 or later
<source>1.6</source>
<target>1.6</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</processors>
<compilerArgs>
<arg>-verbose</arg>
<arg>-Aeclipselink.persistencexml=src/main/resources/META-INF/persistence.xml</arg>
</compilerArgs>
or Maven 3.0 or older
<compilerArguments>
<verbose />
</compilerArguments>
<compilerArgument>-Aeclipselink.persistencexml=src/main/resources/META-INF/persistence.xml</compilerArgument>
回答2:
It seems that while spaces are escaped in compilerArgument
, the same isn't true for quotes. So, if you surround the spaces in the argument with quotes, you get two arguments:
<compilerArgument>-Xlint:serial" "-Werror</compilerArgument>
This invokes javac "-Xlint:serial" "-Werror"
rather than javac "-Xlint:serial -Werror"
.
There's nothing in the docs about this that I can find.
回答3:
I think it's a bug in maven-compiler-plugin, I submitted an issue to developers: MCOMPILER-178
回答4:
In relation to Kalpesh Soni's answer:
Note for Maven 3.1 or later according to the example from http://maven.apache.org/plugins/maven-compiler-plugin/examples/pass-compiler-arguments.html:
<compilerArgs>
<arg>-verbose</arg>
<arg>-Xlint:all,-options,-path</arg>
</compilerArgs>
The above is great unless you want to pass an additional param that requires space character. In my case it was -bootclasspath /path/to/custom/rt.jar
. In such a case you have to split this string on every space and pass every part as a new <arg />
in order not to get Fatal error compiling: invalid flag: ...
So the working example is:
<compilerArgs>
<arg>-verbose</arg>
<arg>-Xlint:all,-options,-path</arg>
<arg>-bootclasspath</arg><arg>/path/to/custom/rt.jar</arg>
</compilerArgs>
来源:https://stackoverflow.com/questions/11339056/how-do-i-pass-javac-multiple-command-line-arguments-some-of-which-include-colon