J2EE Server Capabilities API proposal

Version: 0.4



This paper proposes solution for Issue #7 - missing capabilities API for server. The solution is to not store JEE specification version in project but instead store list of server capabilities in project where capability more or less maps to an official specification which server implements and supports. Such a change would give IDE more concrete information about what technologies should be enabled on such a project and which other server could be alternatively used for project deployment.

VK: will the list of capabilities associated with a project be 'what could be used in this project' OR 'what is used in this project'? The later is kind of hard to develop and maintain, especially as the features of a spec have become easier to use without using a wizard.


Define in J2EE Server module (or perhaps somewhere else?) API for describing Capabilities and their versions:

Version {
    String id; // "3.0"
    String jsr; // "315" (optional)

Capability {
    String id; // "servlet"
    String displayName; // "Java Servlet API"

CapabilityVersion {
    Spec spec;
    Version version;

VK: do you mean CapabilityVersion { Capability capability; Version version; } above?

and provide static constants for all specifications which are part of J2EE 4, 5, and 6 and J2SE:

CapabilityVersion SERVLET_3 = <tt>servlet, Java Servlet API}, {3.0, 315</tt>;
CapabilityVersion SERVLET_25 = <tt>servlet, Java Servlet API}, {2.5, 123</tt>;

Define a Profile which is list of capabilities:

Profile {
    CapabilityVersion capabilityVersions[];

and provide static constants for following profiles: J2EE1.4, J2EE5, J2EE6 and J2EE6 Web Profile.

PH: Perhaps Version should be composed of major, minor, micro, update and jsr elements.

VK: how will this api handle things like ejb-lite... which is a subset of the full ejb spec... do we need to get down into the chapter and section level of the spec to call out support?

PH: Profile should have a display name as well.

PH: Can one server support multiple profiles? If one profile is subset of other profile should we return all of them or just the profile defining superset? We should also think about the evolution of this API.

MK: For Maven projects capabilities basically mean having the right dependencies on classpath of the project. We sort of do it already, the ultimate challenge is to find the appropriate API spec jars in maven repositories.

MK: A lot of UI generators currently assume a complete app server on project classpath, which is not true for maven porjects, I've created an api for adding a container classpath items from the generators - see org.netbeans.modules.j2ee.core.api.support.classpath.ContainerClassPathModifier Applies to Capabilities as well I guess. Or the given UI will have to warn the user that a capability is being added..

Server plugin side

Each server plugin would have to return instance of Profile basically listing capabilities it has (that is specifications it implements and supports). Realistically I can imagine that none of the servers would use above J2EE constants as servers usually supports more specifications (or less).

VK: mixed servers might have that problem....

J2EE Server should have an SPI allowing server providers to specify capabilities of their server declaratively in module layer.

NetBeans project side

To recapitulate current state: NetBeans J2EE/Web project is server driven. That is whatever libraries (implemented specifications) a server consist of they are placed on project's classpath and user develops project against these jars. The biggest advantage of this approach is that user does not have to manually configure which specification and in which versions they intend to develop against - server provides answers to those questions. The only relevant information project carries (apart from server instance name) is J2EE specification version.

This proposal suggests to enhance this state and to store in project an instance of Profile instead of J2EE specification version. History showed that J2EE specification version is of too course granularity and is not sufficient - JBoss is not J2EE5 server but supports EJB; Tomcat is missing persistence manager; etc. If server's profile is stored in project during project creation then project has much more precise information about supported specifications and individual IDE modules can query this information, eg. is EJB3.0 supported? is JPA2.0 supported? etc.

VK: It seems like many of these queries can be resolved by looking at the classpath for the project.

Implications of this proposal are:

  • Server ans Settings wizard panel - add a button to show separate dialog to list capabilities in server profile and allow user to disable some of the them; for example server may support both EJB and EJB-Lite but user knows they want to use EJB-Lite only. Basically whatever is selected in this profile's customizer will consequently enable/disable features IDE will offer on the project. Customized list will be stored in project metadata.

VK: it seems like this will lead to many more 'if-else if-else' blocks in the code... is that what we want?

PH: Perhaps Capability should have static factory method to create it from ant property value and other method to convert it to such value.

  • project customizer will have similar dialog (or a button to show dialog) which lists server capabilities project requires and capabilities available in server. Dialog will be used to resolve potential problems when server is changed - server can be changed but if some previously set capability is not available user is warn but they still can decide to continue and remove that capability from list of required ones.
  • broken/missing server dialog - similarly as in above mentioned project customizer the broken server dialog will list all available servers and warn users if some capabilities are not implemented by that server and that proceeding with such a server will remove that capability from required ones and will disable related support from IDE and may cause compilation failures if there is already an existing code depending on that capability
  • tools checking whether project is of a J2EE specification version must be changed to test presence of concrete capability (WS, JPA); for backward compatibility methods testing whether a project is J2EE5 project (or 6 or 1.4) can still be provided

PH: My feeling is that we will figure out compatibility methods (1.4, 5) are inevitable.

Note that disabling a capability will:

  • disable features provided by IDE for that capability, eg. disabling WS will stop WS related wizards on a project

PH: WS were improved recently, but there could be a lot of hacky code.

  • removes capability API from project's compilation classpath, eg. disabling JSF will remove JSF API jars

PH: This is important part. getToolClassPath and getToolProperty do not establish a good API. Maybe we should think of some interface contract through lookup. Not sure.

More notes:

  • term Capability is used instead of Specification so that API is not restricted just to official specification and server can use this API to communicate its other capabilities, for example EJB 3.1 Lite is not a specification of its own rather it is a subset of full EJB 3.1 specification; server which want to be compliant with JEE Web Profile must have EJB 3.1 Lite capability
  • the only reason for storing capabilities in a project (instead of always fetching them from a server associated with the project) is to handle cases where server is missing and user needs to associate the project with an appropriate server

Open issues

  • is it possible to implement that disabling a specification alters list of jars added to project's classpath? It probably depends on how server internally packages API JARs - if they are not individual JARs then it is impossible
  • Re. issue 79943 - I would argue that the issue itself is low level detail in server implementation which is not possible to prevent in the IDE.

Other proposals

JEESpecificationAPI should be looked at - it introduces a concept of JEEFeature. Right now it seems to me that all this is already covered by CapabilitiesVersion but maybe something like that is needed to cover optional parts of specification? Do we have a usecase?

Implementation Plan

As several modules will depend on implementation of this proposal it should be implemented in two stages:

  1. quickly give other module writers something to use
  2. once this proposal is fully implemented rewire temporary API module writers were using to real implementation

How does it work today:

Current practice is to store JEE specification version (eg. "1.5", "1.4", ...) in project.properties and later refer to it either via reading the property directly or via project implementations like EarImplementation.getJ2eePlatformVersion (which read the value from project properties). For example in EJB module the value is used in manner: if specVersion is equal 1.5 then generate EJB 3.0 code (that is EJB3 is available since JEE5).

Short term solution could be:

  • add 'JEE 1.6' and 'JEE 1.6 Web Profile' constants
  • Web/JEE project wizards (and GlassFish server plugin) enhanced to offer 1.6 and 1.6 Web
  • J2EE Server module (or possibly somewhere else) defines public final class with methods like isEJB21Supported(Project), isEJB30Supported(Project), isEJB31Supported(Project), isEJB31LiteSupported(Project), etc. These methods can be introduced on as needed basis. (alternatively each module could defined these methods locally)
  • short term: methods isXXXSupported are implemented to retrieve JEE spec version from project and return answer based on that
  • all modules should stop using JEE Spec version and use isXXXSupported methods instead
  • long term: methods isXXXSupported are implemented to use J2EE Capabilities API to answer the question (this can be implemented either by calling directly to an app server associated with the project or (preferably) by reading supported spec version directly from project meta data)
  • once this is implemented deprecate everything related to JEE spec version but keep somewhere a method which for given list of specifications says whether it is JEE 1.5 or 6 or 1.4.
Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo