JavaEE 6 compliance
General deployment functionality
Extensibility interfaces relevant to deployment
Application management (app config customization)
(This last feature is not truly “deleting” the item from the descriptor, although the net effect is the same.)






Please refer to v2 doc
for the details of the above mechanisms. One exception here, the application's repository for standalone modules has moved from $DOMAIN_DIR/applications/j2ee-modules to $DOMAIN_DIR/applications. And the application's repository for enterprise applications has moved from $DOMAIN_DIR/applications/j2ee-applications to $DOMAIN_DIR/applications. So in the dynamic application reloading case, the path of the .reload file needs to change accordingly.
We continue supporting the same set of operations to manipulate the application lifecycle as in v2: deploy/redeploy, undeploy, enable, disable. These are the limitations/additions in this release:
describes the interfaces in detail.
They are summarized briefly below for convenience. There are no changes to these interface at this point, but we expect these interfaces to evolve through the engineering process of this release.
Once the container developer implements these interfaces, he or she packages the Sniffer into one OSGi module and the other classes into one or more other OSGi modules. (The deployment infrastructure must be able to ask each sniffer implementation if it handles an application being deployed. The other implementation classes for the container type are not needed unless an application of that type has been deployed to the server. The sniffer should be packaged separately from the other classes so GlassFish can load it without loading the other classes related to the same container type.)
public interface org.glassfish.api.container.Container {
public Class<? extends Deployer> getDeployer();
public String getName();
}
public interface org.glassfish.api.deployment.ApplicationContainer<T> {
public T getDescriptor();
public boolean start(ApplicationContext startupContext) throws Exception;
public boolean stop(ApplicationContext stopContext);
public boolean suspend();
public boolean resume() throws Exception;
public ClassLoader getClassLoader();
}
public interface org.glassfish.api.container.Sniffer {
public Class<? extends Annocation>[] getAnnotationTypes();
public String[] getContainersNames();
public Map<String,String> getDeploymentConfigurations(ReadableArchive archive);
public String getModuleType();
public String[] getURLPatterns();
public boolean handles(ReadableArchive archive, ClassLoader loader) throws IOException;
public boolean isUserVisible();
public Module[] setup(String containerHome, Logger logger);
public void tearDown();
}
public interface org.glassfish.api.deployment.Deployer<T extends Container, U extends ApplicationContainer> {
public MetaData getMetaData();
public <V> V loadMetaData(Class<V> type, DeploymentContext context);
public boolean prepare(DeploymentContext context);
public U load(T container, DeploymentContext context);
public void unload(U appContainer, DeploymentContext context);
public void clean(DeploymentContext context);
}
public interface org.glassfish.api.deployment.archive.ReadableArchive extends Archive {
public InputStream getEntry(String name) throws IOException;
public boolean exists(String name) throws IOException;
public long getEntrySize(String name);
public void open(URI uri) throws IOException;
public ReadableArchive getSubArchive(String name) throws IOException;
public ReadableArchive getParentArchive();
public void setParentArchive(ReadableArchive parentArchive);
public boolean exists();
public boolean delete();
public boolean renameTo(String name);
}
public interface org.glassfish.api.deployment.archive.WritableArchive extends Archive {
public void create(URI uri) throws IOException;
public void closeEntry(WritableArchive subArchive) throws IOException;
public OutputStream putNextEntry(String name) throws java.io.IOException;
public void closeEntry() throws IOException;
public WritableArchive createSubArchive(String name) throws IOException;
}
public interface org.glassfish.api.deployment.archive.ArchiveHandler {
public String getArchiveType();
public String getDefaultApplicationName(ReadableArchive archive);
public boolean handles(ReadableArchive archive) throws IOException;
public ClassLoader getClassLoader(ClassLoader parent, ReadableArchive archive);
public void expand(ReadableArchive source, WritableArchive target) throws IOException;
public Manifest getManifest(ReadableArchive archive) throws IOException;
}
Container developers can choose what, if any, configuration to expose for post-deployment customization. They make this customization possible by completing the following tasks:
(Note, for completeness, we describe all the aspects of this feature in the following section. The work from the GlassFish side will be shared by different teams: admin, deployment, GUI, and the container teams. The implementation of web module configuration described below is the initial delivery; enhancements and further customizations can be added later.)
1. Declare a Configured interface, representing the module type's customizable configuration, that extends ApplicationConfig and is particular to the container type. For example, here is the definition for the initial web component customization support:
@Configured
public interface WebModuleConfig extends ApplicationConfig ... {
...
@Element
public List<EnvEntry> getEnvEntry();
@Element
public List<ContextParam> getContextParam();
...
}
The container developer also implements any lower-level interfaces referenced from this interface (EnvEntry and ContextParam in this example).
By defining these interfaces the container developer implicitly extends the domain.xml format as well. Specifically, a container-provided interface which extends ApplicationConfig corresponds to a new child element of <engine> (the <engine> element represents one component of an application that runs inside a single container type). For example, the web container implementation introduces <web-module-config> as a new optional child of <engine> for those <engine> elements that correspond to web components. Because the definitions of and inheritance among the @Configured interfaces determines the domain.xml format the container developer does not need to do any additional work to expand the domain.xml format to allow for customizable configuration.
Note, in v3 prelude the parent node was <application>element. It was changed to <engine> element in this release so it would work for both the standalone and embedded (inside an enterprise application) cases.
Here is what a fragment of domain.xml might look like after a user had customized a web module's configuration:
<application ...>
<module name="foo">
<engine sniffer="web">
<web-module-config>
<env-entry>
<env-entry-name>SomeName</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>7</env-entry-value>
</env-entry>
...
<context-param>
<param-name>greeting</param-name>
<param-value>Hello</param-value>
</context-param>
...
</web-module-config>
</engine>
</module>
</application>
2. Implement the ApplicationContainer interface's start method so that, as part of starting the module, the method retrieves the module-type-specific customization information and uses it to prepare the execution environment for the module. The com.sun.enterprise.web.WebApplication class (which implements ApplicationContainer) illustrates this for the web module type.
3. If desired, create AMX interfaces specific to the new module type with convenience methods for accessing the customizable configuration for the module type. (The com.sun.appserv.management.config.WebModuleConfigConfig interface illustrates this for the web module type.) Defining these interfaces simplifies writing the GUI plug-in. (Note - recent and pending changes to AMX which Lloyd is considering might do away with the specific interfaces.)
4. Implement a GUI plug-in which developers and administrators can use to customize the configuration that is exposed for the given container type. The plug-in uses AMX (either the generic access methods common to all AMX entities or the module-specific AMX interfaces defined above) to retrieve and assign values for the customizable configuration for a given module type. Ideally the plug-in should reside in its own OSGi module or one with few other classes, since the GUI will load and use the plug-in module and we want to keep the admin console footprint as small as possible. (This goal conflicts somewhat with the goal of improving start-up performance by minimizing the total number of modules GlassFish must load and one might need to be traded-off in favor of the other.)
For example, the plug-in for customizing web apps will expose the env entries and context params from the application's descriptor, augmented by the contents of the default-web.xml and the context.xml files. The display to the user will show the value for each env-entry and context-param as the web container would compute it as if it were preparing to start the app. The user will be able to modify the value of an existing item, add a new env-entry or context-param, or mark an existing env-entry or context-param to be ignored (suppressed).
5. Implement commands which developers and administrators can use to customize the configuration. The Add-on Component Development Guide
explains this process in detail.
These commands as proposed for this release are listed below and follow the customization guidelines listed in the add-on documentation.
A container offering application configuration will likely provide commands to set, delete, and list the customizable items for that container's module type. Note that the set- and delete-style commands should require the user to identify the configured item uniquely using
For example, the web-container-specific information is
Note that the --config-type option specifies which variety of configuration information is of interest, while the --type option specifies, for creating or setting env-entry items, what env-entry-type setting should be assigned.
All customizations apply to the application. The administrator can customize differently for different targets by using placeholders.
set-web-env-entry --name=name --value=value --type=env-entry-type [--description=description] [--ignoreDescriptorItem=true/false] application-name[/module-name] list-web-env-entry [--name=name] application-name[/module-name] unset-web-env-entry --name=name application-name[/module-name] set-web-context-param --name=name --value=value [--description=description] [--ignoreDescriptorItem=true/false] application-name[/module-name] list-web-context-param [--name=name] application-name[/module-name] unset-web-context-param --name=name application-name[/module-name]
Note that the design of the commands is generally up to the container developer; the ones described here are our proposal for the initial commands related to web app customization. Even so, most if not all such commands for any container should let the user set overriding values, unset them (that is, remove the customization for a particular element), and list them.
The user specifies the --ignoreDescriptorItem option on the set commands to suppress the effect of the same-named item from the "effective" descriptor. In the web case these values are composed from the module's descriptor, the default-web.xml settings, and the context.xml settings.
We propose separate, component-provided commands rather than generic, GlassFish-implemented commands. Doing so leverages the existing, documented mechanism for extending the command set while no such mechanism exists - yet - for extending existing commands with expanded syntax. At least as importantly, it also allows more user-friendly, container-specific command syntax. In particular, the option names themselves refer to specific aspects of the web module customization. This is more convenient for the user as it collapses the actual implementation hierarchy in the configuration implementation.
Another alternative we considered was a single set of generic, GlassFish-provided commands that would apply to all module customization types. One difficulty with this approach is that the commands would not know about the details of any given container type's configuration structure. This would require a generic way for command users to identify a particular configurable item. We concluded this was user-unfriendly enough that adding new generic commands would not be worthwhile.
Note that users can use the existing dotted notation and/or the proposed path notation with the generic set and list commands to manage post-deployment customization.
The v3 prelude release includes much of the framework for this feature although that release did not expose this feature to the end-user. The GUI and the CLI commands for customizing web applications will be added in this release (post-JavaOne).
Changes from v3 prelude:
Changes from v2:
Disclose all interfaces that this project exports.
For the initial implementation of web app customization:
Change from v2:
The internal applications repository layout: the applications repository for standalone module has moved from $DOMAIN_DIR/applications/j2ee-modules to $DOMAIN_DIR/applications. The internal applications repository layout: the applications repository for enterprise application has moved from $DOMAIN_DIR/applications/j2ee-applications to $DOMAIN_DIR/applications. This change was made to simplify the implementation, avoid unnecessary code branching. Also users will have one uniform place to look for all types of application regardless of the module type.
Stability: evolving
The domain.xml: we use a generic "application" element to represent any JavaEE module type.
Stability: evovling
The admin content should be enhanced to describe the ability to use the GUI or the CLI commands to manage application customization.
Changes from v2:
The applications repository layout change might impact upgrade depending on the upgrade mechanism we choose.
User scripts that currently leverage the dynamic reload functionality will need to be corrected to reflect the new repository layout.
User scripts that depend on the default behavior of the v2 deploy subcommand may need to be corrected. For example, to adapt to the new default value of the "force" option.

