I've used a Maven archetype (webapp-javaee6
) to create a new Java EE 6 project but don't understand why certain things are put inside the build
element of the POM. To be specific I don't understand why the javaee-endorsed-api.jar
is copied over to the endorsed directory. According to the answer to this question, this is needed for compilation but my project compiles fine when I remove the related plugin
element under build
.
Since javax:javaee-web-api
is already provided as a dependency in the POM, can this not be used for compiling?
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>6.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[Found in issue MARCHETYPES-35 via looking at the source of the webapp-javaee6 archetype]
Background
The package javax.annotation from JSR 250: Common Annotations is present not only in Java EE but also in the JDK.
Versions used
JDK 6: Common Annotations 1.0
Java EE 6: Common Annotations 1.1
JDK 7: Common Annotations 1.1
Java EE 7: Common Annotations 1.2
Problem
When compiling a Java EE project, the annotations from the JDK take precedence over the annotations from the javaee-web-api jar. When an annotation from the javaee-web-api defines a new element, the compiler might not see it and fail with an error.
For example
When a Java EE 6 project uses @Resource(lookup = "...")
and is compiled with JDK 6, it would usually fail.
Common Annotations 1.1 introduces the new element Resource.lookup(). But normally the compiler would only sees the Resource annotation from JDK 6 which uses Common Annotations 1.0 without this element.
Solution
Was to use the <endorseddirs>
compiler argument as you describe. To force the compiler to use the correct version of the annotations.
JAVA EE 7
As I understand the changelog for Common Annotations 1.2 for Java EE 7, there are no new elements on annotations. So in practice there's probably no such problem with Java EE 7 and JDK 7.
It should compile, because there is also a dependency to this artifact:
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Maven manual page describes provided as follows:
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
So in my opinion copying this dependency has no impact on compiling.
However archetype's author wanted for some reason to copy Java EE 6 API package to endorsed directory. This might be helpful if you decide to start Jetty server and do some testing in "Test Phase" (for example with JUnit).
If you're not using it - just remove it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With