0

Background: I had a maven war project migrated from WildFly 10.1.0.Final Java EE7 Full & Web Distribution to Payara Server 164 Full. The pom.xml was set to specifically satisfy WildFly environment. As a result, some of the <provided> scoped dependencies became problematic after migration because Payara did not have correct implementations for them. By changing some of the dependency scopes to <compile>, I fixed the problems. But it seemed not very smart to try out each of the dependencies to see if one was provided by the container or not.

Question: How can I know what dependencies are supported by a particular container?

For example, there are many versions of Servlet API. How can I know if version 4.0.0-b01 is supported by GlassFish 3.1.2.2?

I want to be able to do it in an appropriate way. E.g. reading from the documentations, using an official toolkit, etc. By the way, I searched in Payara's documentation. But I didn't find a list of supported dependencies and versions.

William
  • 151
  • 11

2 Answers2

0

Alright, I eventually found out a nicer way to do this. I was inspired by this answer, although, it was not directly related to my question.

Short answer: Go to Java EE version history on Wikipedia. There is a full list of implementations of all the APIs that each Java EE container version implements.

Full answer:

Java EE containers are implementations of Java EE APIs. It means that Java EE projects do not need to contain all the implementation libraries of the dependencies being used. Instead, they need only API libraries such as servlet-api : 3.1.0. However, if any of the API version is "too new" or "too old", and the non-implemented abstract methods are called, an AbstractMethodError will be thrown.

Here is an example of reproducing this error:

On a Java EE 7 container (GlassFish 4) with jdk 1.8, use servlet-api : 4.0.0-b02 as your Servlet API (which contains abstract methods with default implementations). Create a ServletFilter without implementing init and destroy methods. Deploy and start the server. an AbstractMethodError will appear during startup.

The reason for this is that servlet-api : 4.0.0-b02 is supposed to be implemented in Java EE 8. Java EE 7 is associated with jdk 1.7 which does not support default interface method. With servlet-api : 3.1.0 (which is implemented by Java EE 7), init and destroy methods must be implemented in the project. Whereas, when using servlet-api : 4.0.0-b02, it is possible to not implement them. That is where problems occur.

In conclusion, it is generally not a good idea to use different versions between Java EE APIs and their implementations. Oracle provides specifications for different versions of Java EE APIs as an official introduction. It should be checked when building project dependencies.

Community
  • 1
  • 1
William
  • 151
  • 11
  • So, this answer is not about "best practice". It tells you what is possible to do with a Java EE container, how it responses and why it responses that way. – William Mar 02 '17 at 22:49
0

To use them directly is not a very smart idea.

If you need web profile, just use:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

If you need full profile, slightly change it to:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

And you're done. Everything present in the project from now on that comes from this set of dependencies is present in the application servers.

This is actually the correct way to do it. Your way is wrong and whoever told you to work with Java EE like this deserves punishment.