Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New Maven project using archetypes: why is javaee-endorsed-api.jar being copied in POM?

Tags:

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>
like image 476
kindkonti Avatar asked Feb 14 '12 16:02

kindkonti


2 Answers

[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.

like image 67
Arend v. Reinersdorff Avatar answered Sep 20 '22 15:09

Arend v. Reinersdorff


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.

like image 38
Sebastian Łaskawiec Avatar answered Sep 24 '22 15:09

Sebastian Łaskawiec