ServerCapabilities
Modernized Server capability determination and usage
The current architecture used to determine what can and will be supported by a server implementation is very coarse-grained.
The early implementation of this capability query was used in the J2EE 1.4 time frame.
Module projects could declare their "type" and say that they would be deployable on a J2EE 1.3 or J2EE 1.4. Servers would advertise the J2EE spec level that they supported and the types of module that they could support (link to api change).This early implementation was flawed, since web containers like Tomcat (which only implements a subset of the web related J2EE specs) could not advertise their limitations in a useful manner. Developers just needed to "know" that a Tomcat server might not have support for some features, like Web Services.
Since web service capabilities could be added to Tomcat by installing additional software, a new group of APIs was added to J2eePlatform: the 'tool support' methods. These allowed for supporting Tomcat+WS, to some extent (link to api change).
With the advent of Java EE 5, a new wrinkle came into being: the mixed server. The prototypical mixed server was JBoss, which supported putting EJB 3.0 modules into an ear with web modules that were targeted to older releases of Tomcat that that did not support Java EE 5 (like the Servlet 2.5 spec). The J2eePlatform API was extended again, to attempt to account for this (link to api change).
The advent of profiles and pruning limits the further utility of these APIs. A server may implement a subset of one of the Java EE 6 specs and still be deemed compliant. Different vendors may even have their own variations on the specified profiles... So the problem becomes much finer grained.
java EE 6 also introduces the ability to blend/package EJBs inside web archives. This violates a fundamental assumption of the J2eeModule API, since modules were assumed to have only one "type". To fit Java EE 6 into the current assumptions, we would need to create new module type to represent these blended web-apps. This strategy may not be useful in the long term, since there is the possibility that the spec would eventually allow for 15 different blended modules.
The fundamental weakness
The J2EE and Java EE spec define what has to be supported for a server to be certified as J2EE or Java EE compliant. This spec is a collection of a number of individual specs. Developers may create modules that leverage a limited subset of the capabilites perscribed by the spec. A server vendor may implement some combination of the individual specs, that will not be compliant with the "collection" spec, that delivers value.
The current J2eeModule and J2eePlatform/J2eePlatformImpl apis do not create a way to express either of these situations.
Here are a couple of examples:
- A web module that doesn't leverage all of the Java EE 5 web technologies.
It is simple to imagine that a developer would create a web app that leverages the Servlet and JSP specs that doesn't use JSF or depend on any of web services specs. But a J2eeModule instance can only describe what it is using at the coarsest level... "all or nothing' - A server may implement a subset of the specs that make up Java EE, like Tomcat, which is an implementation of the Servlet and JSP specs.
Developers may create web apps that are useful with such a limited set of supported specs. The limits of the J2eePlatform api force the server integration module developer to provide false information about a Tomcat instance, though, since Java EE includes many more web related specs, that may not be supported by a particular instance of Tomcat.
Use cases for the new API
UC1 : Describe the actual requirements of an application.
When the user creates an project that requires a subset of the Java EE specs they should not be forced to say that their app requires a much larger set of specs be implemented by a server to execute. A J2eeModule would leverage or require a set of specifications to deploy and execute correctly.
J2eeModule.java
/** Set of specs used as the foundations of this J2eeModule. * * @return the foundation specs. */ Set<SpecificationID> getRequiredSpecifications()
UC2 : Modifying an app will change the requirements.
As the user manipulates their project, they may change the requirements that need to be satisfied to deploy and execute the project. This capability would probably be exposed as a friend on a project type by project type basis, to module which would manipulate the content of the project.
UC3 : server integration plugins need to be able to describe the specifications implemented by the server.
J2eePlatform.java and J2eePlatformImpl.java
/** Set of specs supported by this server instance. * * @return the implemented specifications. */ Set<SpecificationID> getSupportedSpecifications()
UC 4 : a server integration plugin may allow other NetBeans modules to extend the server's capabilities. One example would be Web Service development module which would install web service support onto a "generic" Tomcat instance, via an explicit user action or implicitly at deployment time.
J2eePlatformImpl.java
/** Update the specs supported by the server instance. */ void updateSupportedSpecifications(set<SpecificationID>)
UC 5 : Determine whether the module that is being developed can be deployed on a particular server instance.
This could be determined with intersection and compare test:
Set<SpecificationID> necessary = j2eeModule.getRequiredSpecifications();
Set<SpecificationID> available = j2eePlatform.getSupportedSpecifications();
Set<SpecificationID> intersection = available.intersect(necessary);
if (intersection.getSize() == necessary.getSize()) {
// do something
} else {
// tell user that something was not not possible.
}
Another way to do it would be to provide a static helper method on J2eeModule that would do the test. A second method would be necessary to describe what is missing from the server would also be useful.
J2eeModule.java
/** determine if a module can be deployed on a target J2eePlatform * * @param module the module * @param platform the target server's platform * @return can the module deploy successfully */ static boolean deploymentCompatable(J2eeModule,J2eePlatform) /** find unsatisfied requirements * * @param module the module * @param platform the target server's platform * @return set of unsatisfied deployment requirements */ static Set<SpecificationID> unsatisfiedRequiredSpecifications(J2eeModule, J2eePlatform)
New Constants
Deprecated fields and methods
J2eeModule.getModuleVersion() : this can be determined by looking at the required specifications.
J2eeModule.J2EE_13, J2eeModule.J2EE_14, J2eeModule.JAVA_EE_5 : these coarse grained spec identifiers are replaced by fine-grained spec identifiers.
The parallel interfaces on the other side of the 'Bridge' in J2eeModuleImplementation are also deprecated.
J2eePlatform.getSupportedSpecVersions() : returns the coarse grained spec identifiers from J2eeModule. Associative deprecation.
J2eePlatform.getSupportedSpecVersions(Object) : returns the coarse grained spec identifiers. Associative deprecation.
The parallel interfaces on the other side of the 'Bridge' in J2eePlatformImpl are also deprecated.

