type=page
status=published
title=Adding Container Capabilities
next=session-persistence-modules.html
prev=adding-configuration-data.html
~~~~~~
Adding Container Capabilities
=============================

[[GSACG00007]][[ghmon]]


[[adding-container-capabilities]]
7 Adding Container Capabilities
-------------------------------

Applications run on Eclipse GlassFish Server in containers. GlassFish Server
enables you to create containers that extend or replace the existing
containers of GlassFish Server. Adding container capabilities enables
you to run new types of applications and to deploy new archive types in
GlassFish Server.

The following topics are addressed here:

* link:#ghpjl[Creating a `Container` Implementation]
* link:#ghozu[Adding an Archive Type]
* link:#ghphp[Creating Connector Modules]
* link:#gkane[Example of Adding Container Capabilities]

[[ghpjl]][[GSACG00132]][[creating-a-container-implementation]]

Creating a `Container` Implementation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To implement a container that extends or replaces a service in GlassFish
Server, you must create a Java programming language class that includes
the following characteristics:

* It is annotated with the `org.jvnet.hk2.annotations.Service`
annotation.
* It implements the `org.glassfish.api.container.Container` interface.

You should also run the HK2 Inhabitants Generator utility on your class
files, which adds classes marked with the `@Service` annotation to the
`META-INF/hk2-locator/default` file in your JAR file. For more
information about the HK2 Inhabitants Generator, see the
https://hk2.java.net/inhabitant-generator.html[HK2 Inhabitants Generator
page].

[[ghogv]][[GSACG00234]][[marking-the-class-with-the-service-annotation]]

Marking the Class With the `@Service` Annotation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Add a `com.jvnet.hk2.annotations.Service` annotation at the class
definition level to identify your class as a service implementation.

[source,oac_no_warn]
----
@Service
public class MyContainer implements Container {
...
}
----

To avoid potential name collisions with other containers, use the fully
qualified class name of your container class in the `@Service`
annotation's `name` element:

[source,oac_no_warn]
----
package com.example.containers;
...

@Service @jakarta.inject.Named("com.example.containers.MyContainer")
public class MyContainer implements Container {
...
}
----

[[ghohg]][[GSACG00235]][[implementing-the-container-interface]]

Implementing the `Container` Interface
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The `org.glassfish.api.container.Container` interface is the contract
that defines a container implementation. Classes that implement
`Container` can extend or replace the functionality in GlassFish Server
by allowing applications to be deployed and run within the GlassFish
Server runtime.

The `Container` interface consists of two methods, `getDeployer` and
`getName`. The `getDeployer` method returns an implementation class of
the `org.glassfish.api.deployment.Deployer` interface capable of
managing applications that run within this container. The `getName`
method returns a human-readable name for the container, and is typically
used to display messages belonging to the container.

The `Deployer` interface defines the contract for managing a particular
application that runs in the container. It consists of the following
methods:

`getMetaData`::
  Retrieves the metadata used by the `Deployer` instance, and returns an
  `org.glassfish.api.deployment.MetaData` object.
`loadMetaData`::
  Loads the metadata associated with an application.
`prepare`::
  Prepares the application to run in GlassFish Server.
`load`::
  Loads a previously prepared application to the container.
`unload`::
  Unloads or stops a previously loaded application.
`clean`::
  Removes any artifacts generated by an application during the `prepare`
  phase.

The `DeploymentContext` is the usual context object passed around
deployer instances during deployment.

[[GSACG00064]][[ghojg]]


Example 7-1 Example Implementation of `Container`

This example shows a Java programming language class that implements the
`Container` interface and is capable of extending the functionality of
GlassFish Server.

[source,oac_no_warn]
----
package com.example.containers;
contains
@Service(name="com.example.containers.MyContainer")
public class MyContainer implements Container {
    public String getName() {
        return "MyContainer";
    }

    public Class<? extends org.glassfish.api.deployment.Deployer> getDeployer() {
        return MyDeployer.class;
    }
}
----

[[GSACG00065]][[ghoiv]]


Example 7-2 Example Implementation of `Deployer`

[source,oac_no_warn]
----
package com.example.containers;

@Service
public class MyDeployer {

    public MetaData getMetaData() {
        return new MetaData(...);
    }

    public <V> v loadMetaData(Class<V> type, DeploymentContext dc) {
        ...
    }

    public boolean prepare(DeploymentContext dc) {
        // performs any actions needed to allow the application to run,
        // such as generating artifacts
        ...
    }

    public MyApplication load(MyContainer container, DeploymentContext dc) {
        // creates a new instance of an application
        MyApplication myApp = new MyApplication (...);
        ...
        // returns the application instance
        return myApp;
    }

    public void unload(MyApplication myApp, DeploymentContext dc) {
        // stops and removes the application
        ...
    }

    public void clean (DeploymentContext dc) {
        // cleans up any artifacts generated during prepare()
        ...
    }
}
----

[[ghozu]][[GSACG00133]][[adding-an-archive-type]]

Adding an Archive Type
~~~~~~~~~~~~~~~~~~~~~~

An archive type is an abstraction of the archive file format. An archive
type can be implemented as a plain JAR file, as a directory layout, or a
custom type. By default, GlassFish Server recognizes JAR based and
directory based archive types. A new container might require a new
archive type.

There are two sub-interfaces of the
`org.glassfish.api.deployment.archive.Archive` interface,
`org.glassfish.api.deployment.archive.ReadableArchive` and
`org.glassfish.api.deployment.archive.WritableArchive`. Typically
developers of new archive types will provide separate implementations of
`ReadableArchive` and `WritableArchive`, or a single implementation that
implements both `ReadableArchive` and `WritableArchive`.

Implementations of the `ReadableArchive` interface provide read access
to an archive type. `ReadableArchive` defines the following methods:

`getEntry(String name)`::
  Returns a `java.io.InputStream` for the specified entry name, or null
  if the entry doesn't exist.
`exists(String name)`::
  Returns a `boolean` value indicating whether the specified entry name
  exists.
`getEntrySize(String name)`::
  Returns the size of the specified entry as a `long` value.
`open(URI uri)`::
  Returns an archive for the given `java.net.URI`.
`getSubArchive(String name)`::
  Returns an instance of `ReadableArchive` for the specified sub-archive
  contained within the parent archive, or null if no such archive
  exists.
`exists()`::
  Returns a `boolean` value indicating whether this archive exists.
`delete()`::
  Deletes the archive, and returns a `boolean` value indicating whether
  the archive has been successfully deleted.
`renameTo(String name)`::
  Renames the archive to the specified name, and returns a `boolean`
  value indicating whether the archive has been successfully renamed.

Implementations of the `WritableArchive` interface provide write access
to the archive type. `WritableArchive` defines the following methods:

`create(URI uri)`::
  Creates a new archive with the given path, specified as a
  `java.net.URI`.
`closeEntry(WritableArchive subArchive)`::
  Closes the specified sub-archive contained within the parent archive.
`closeEntry()`::
  Closes the current entry.
`createSubArchive(String name)`::
  Creates a new sub-archive in the parent archive with the specified
  name, and returns it as a `WritableArchive` instance.
`putNextEntry(String name)`::
  Creates a new entry in the archive with the specified name, and
  returns it as a `java.io.OutputStream`.

[[ghoyp]][[GSACG00236]][[implementing-the-archivehandler-interface]]

Implementing the `ArchiveHandler` Interface
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

An archive handler is responsible for handling the particular layout of
an archive. Jakarta EE defines a set of archives (WAR, JAR, and RAR, for
example), and each of these archives has an `ArchiveHandler` instance
associated with the archive type.

Each layout should have one handler associated with it. There is no
extension point support at this level; the archive handler's
responsibility is to give access to the classes and resources packaged
in the archive, and it should not contain any container-specific code.
The `java.lang.ClassLoader` returned by the handler is used by all the
containers in which the application will be deployed.

`ArchiveHandler` defines the following methods:

`getArchiveType()`::
  Returns the name of the archive type as a `String`. Typically, this is
  the archive extension, such as `jar` or `war`.
`getDefaultApplicationName(ReadableArchive archive)`::
  Returns the default name of the specified archive as a `String`.
  Typically this default name is the name part of the `URI` location of
  the archive.
`handles(ReadableArchive archive)`::
  Returns a `boolean` value indicating whether this implementation of
  `ArchiveHandler` can work with the specified archive.
`getClassLoader(DeploymentContext dc)`::
  Returns a `java.lang.ClassLoader` capable of loading all classes from
  the archive passed in by the `DeploymentContext` instance. Typically
  the `ClassLoader` will load classes in the scratch directory area,
  returned by `DeploymentContext.getScratchDir()`, as stubs and other
  artifacts are generated in the scratch directory.
`expand(ReadableArchive source, WritableArchive target)`::
  Prepares the `ReadableArchive`source archive for loading into the
  container in a format the container accepts. Such preparation could be
  to expand a compressed archive, or possibly nothing at all if the
  source archive format is already in a state that the container can
  handle. This method returns the archive as an instance of
  `WritableArchive`.

[[ghphp]][[GSACG00134]][[creating-connector-modules]]

Creating Connector Modules
~~~~~~~~~~~~~~~~~~~~~~~~~~

Connector modules are small add-on modules that consist of application
"sniffers" that associate application types with containers that can run
the application type. GlassFish Server connector modules are separate
from the associated add-on module that delivers the container
implementation to allow GlassFish Server to dynamically install and
configure containers on demand.

When a deployment request is received by the GlassFish Server runtime:

1.  The current `Sniffer` implementations are used to determine the
application type.
2.  Once an application type is found, the runtime looks for a running
container associated with that application type. If no running container
is found, the runtime attempts to install and configure the container
associated with the application type as defined by the `Sniffer`
implementation.
3.  The `Deployer` interface is used to prepare and load the
implementation.

[[ghozd]][[GSACG00237]][[associating-file-types-with-containers-by-using-the-sniffer-interface]]

Associating File Types With Containers by Using the `Sniffer` Interface
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Containers do not necessarily need to be installed on the local machine
for GlassFish Server to recognize the container's application type.
GlassFish Server uses a "sniffer" concept to study the artifacts in a
deployment request and to choose the associated container that handles
the application type that the user is trying to deploy. To create this
association, create a Java programming language class that implements
the `org.glassfish.api.container.Sniffer` interface. This implementation
can be as simple as looking for a specific file in the application's
archive (such as the presence of `WEB-INF/web.xml`), or as complicated
as running an annotation scanner to determine an XML-less archive (such
as enterprise bean annotations in a JAR file). A `Sniffer`
implementation must be as small as possible and must not load any of the
container's runtime classes.

A simple version of a `Sniffer` implementation uses the `handles` method
to check the existence of a file in the archive that denotes the
application type (as `WEB-INF/web.xml` denotes a web application). Once
a `Sniffer` implementation has detected that it can handle the
deployment request artifact, GlassFish Server calls the `setUp` method.
The `setUp` method is responsible for setting up the container, which
can involve one or more of the following actions:

* Downloading the container's runtime (the first time that a container
is used)
* Installing the container's runtime (the first time that a container is
used)
* Setting up one or more repositories to access the runtime's classes
(these are implementations of the HK2
`com.sun.enterprise.module.Repository` interface, such as the
`com.sun.enterprise.module.impl.DirectoryBasedRepository` class)

The `setUp` method returns an array of the
`com.sun.enterprise.module.Module` objects required by the container.

The `Sniffer` interface defines the following methods:

`handles(ReadableArchive source, ClassLoader loader)`::
  Returns a `boolean` value indicating whether this `Sniffer`
  implementation can handle the specified archive.
`getURLPatterns()`::
  Returns a `String` array containing all URL patterns to apply against
  the request URL. If a pattern matches, the service method of the
  associated container is invoked.
`getAnnotationTypes()`::
  Returns a list of annotation types recognized by this `Sniffer`
  implementation. If an application archive contains one of the returned
  annotation types, the deployment process invokes the container's
  deployers as if the `handles` method had returned true.
`getModuleType()`::
  Returns the module type associated with this `Sniffer` implementation
  as a `String`.
`setup(String containerHome, Logger logger)`::
  Sets up the container libraries so that any dependent bundles from the
  connector JAR file will be made available to the HK2 runtime. The
  `setup` method returns an array of `com.sun.enterprise.module.Module`
  classes, which are definitions of container implementations. GlassFish
  Server can then load these modules so that it can create an instance
  of the container's `Deployer` or `Container` implementations when it
  needs to. The module is locked as long as at least one module is
  loaded in the associated container.
`teardown()`::
  Removes a container and all associated modules in the HK2 modules
  subsystem.
`getContainerNames()`::
  Returns a `String` array containing the `Container` implementations
  that this `Sniffer` implementation enables.
`isUserVisible()`::
  Returns a `boolean` value indicating whether this `Sniffer`
  implementation should be visible to end-users.
`getDeploymentConfigurations(final ReadableArchive source)`::
  Returns a `Map<String, String>` of deployment configuration names to
  configurations from this `Sniffer` implementation for the specified
  application (the archive source). The names are created by GlassFish
  Server; the configurations are the names of the files that contain
  configuration information (for example, `WEB-INF/web.xml` and possibly
  `WEB-INF/sun-web.xml` for a web application). If the
  `getDeploymentConfigurations` method encounters errors while searching
  or reading the specified archive source, it throws a
  `java.io.IOException`.

[[ghpbx]][[GSACG00172]][[making-sniffer-implementations-available-to-the-glassfish-server]]

Making `Sniffer` Implementations Available to the GlassFish Server
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package `Sniffer` implementation code into modules and install the
modules in the as-install`/modules` directory. GlassFish Server will
automatically discover these modules. If an administrator installs
connector modules that contain`Sniffer` implementations while GlassFish
Server is running, GlassFish Server will pick them up at the next
deployment request.

[[gkane]][[GSACG00135]][[example-of-adding-container-capabilities]]

Example of Adding Container Capabilities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This example shows a custom container and a web client of the container.
The example is comprised of the following code:

* Code for the container, which is shown in link:#gkbah[Container
Component Code]
* Code for a web client of the container, which is shown in
link:#gkbcq[Web Client Code]

Code that defines the configuration data for the container component is
shown in link:adding-configuration-data.html#gkaal[Examples of Adding
Configuration Data for a Component].

Code for an `asadmin` subcommand that updates the configuration data in
this example is shown in link:extending-asadmin.html#gkbdf[Example 4-7].

[[gkbah]][[GSACG00238]][[container-component-code]]

Container Component Code
^^^^^^^^^^^^^^^^^^^^^^^^

The container component code is comprised of the classes and interfaces
that are listed in the following table. The table also provides a
cross-reference to the listing of each class or interface.

[width="100%",cols="<50%,<50%",options="header",]
|==============================================
|Class or Interface |Listing
|`Greeter` |link:#gkamr[Example 7-3] +
|`GreeterContainer` |link:#gkand[Example 7-4] +
|`GreeterContainer` |link:#gkamm[Example 7-5] +
|`GreeterDeployer` |link:#gkalo[Example 7-6] +
|`GreeterSniffer` |link:#gkaks[Example 7-7] +
|==============================================


[[GSACG00066]][[gkamr]]


Example 7-3 Annotation to Denote a Container's Component

This example shows the code for defining a component of the `Greeter`
container.

[source,oac_no_warn]
----
package org.glassfish.examples.extension.greeter;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Simple annotation to denote Greeter's component
 */
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface Greeter {

    /**
     * Name to uniquely identify different greeters
     *
     * @return a good greeter name
     */
    public String name();
}
----

[[GSACG00067]][[gkand]]


Example 7-4 Application Container Class

This example shows the Java language class `GreeterAppContainer`, which
implements the `ApplicationContainer` interface.

[source,oac_no_warn]
----
package org.glassfish.examples.extension.greeter;

import org.glassfish.api.deployment.ApplicationContainer;
import org.glassfish.api.deployment.ApplicationContext;
import org.glassfish.api.deployment.archive.ReadableArchive;

import java.util.List;
import java.util.ArrayList;

public class GreeterAppContainer implements ApplicationContainer {

    final GreeterContainer ctr;
    final List<Class> componentClasses = new ArrayList<Class>();

    public GreeterAppContainer(GreeterContainer ctr) {
        this.ctr = ctr;
    }

    void addComponent(Class componentClass) {
        componentClasses.add(componentClass);
    }

    public Object getDescriptor() {
        return null;
    }

    public boolean start(ApplicationContext startupContext) throws Exception {
        for (Class componentClass : componentClasses) {
            try {
                Object component = componentClass.newInstance();
                Greeter greeter = (Greeter)
                     componentClass.getAnnotation(Greeter.class);
                ctr.habitat.addComponent(greeter.name(), component);
            } catch(Exception e) {
                throw new RuntimeException(e);
            }
        }
        return true;
    }

    public boolean stop(ApplicationContext stopContext) {
        for (Class componentClass : componentClasses) {
            ctr.habitat.removeAllByType(componentClass);
        }
        return true;
    }

    public boolean suspend() {
        return false;
    }

    public boolean resume() throws Exception {
        return false;
    }

    public ClassLoader getClassLoader() {
        return null;
    }
}
----

[[GSACG00068]][[gkamm]]


Example 7-5 Container Class

This example shows the Java language class `GreeterContainer`, which
implements the `Container` interface.

[source,oac_no_warn]
----
package org.glassfish.examples.extension.greeter;

import org.glassfish.api.container.Container;
import org.glassfish.api.deployment.Deployer;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.component.Habitat;

@Service(name="org.glassfish.examples.extension.GreeterContainer")
public class GreeterContainer implements Container {

    @Inject
    Habitat habitat;

    public Class<? extends Deployer> getDeployer() {
        return GreeterDeployer.class;
    }

    public String getName() {
        return "greeter";
    }
}
----

[[GSACG00069]][[gkalo]]


Example 7-6 Deployer Class

This example shows the Java language class `GreeterDeployer`, which
implements the `Deployer` interface.

[source,oac_no_warn]
----
package org.glassfish.examples.extension.greeter;

import org.glassfish.api.deployment.Deployer;
import org.glassfish.api.deployment.MetaData;
import org.glassfish.api.deployment.DeploymentContext;
import org.glassfish.api.deployment.ApplicationContainer;
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.api.container.Container;
import org.jvnet.hk2.annotations.Service;

import java.util.Enumeration;

@Service
public class GreeterDeployer
    implements Deployer<GreeterContainer, GreeterAppContainer> {

    public MetaData getMetaData() {
        return null;
    }

    public <V> V loadMetaData(Class<V> type, DeploymentContext context) {
        return null;
    }

    public boolean prepare(DeploymentContext context) {
        return false;
    }

    public GreeterAppContainer load(
        GreeterContainer container, DeploymentContext context) {

        GreeterAppContainer appCtr = new GreeterAppContainer(container);
        ClassLoader cl = context.getClassLoader();

        ReadableArchive ra = context.getOriginalSource();
        Enumeration<String> entries = ra.entries();
        while (entries.hasMoreElements()) {
            String entry = entries.nextElement();
            if (entry.endsWith(".class")) {
                String className = entryToClass(entry);
                try {
                    Class componentClass = cl.loadClass(className);
                    // ensure it is one of our component
                    if (componentClass.isAnnotationPresent(Greeter.class)) {
                        appCtr.addComponent(componentClass);
                    }
                } catch(Exception e) {
                    throw new RuntimeException(e);
                }

            }
        }
        return appCtr;
    }

    public void unload(GreeterAppContainer appContainer, DeploymentContext context) {

    }

    public void clean(DeploymentContext context) {

    }

    private String entryToClass(String entry) {
        String str = entry.substring("WEB-INF/classes/".length(), entry.length()-6);
        return str.replaceAll("/", ".");
    }
}
----

[[GSACG00070]][[gkaks]]


Example 7-7 Sniffer Class

This example shows the Java language class `GreeterSniffer`, which
implements the `Sniffer` interface.

[source,oac_no_warn]
----
package org.glassfish.examples.extension.greeter;

import org.glassfish.api.container.Sniffer;
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.api.admin.config.ConfigParser;
import org.glassfish.examples.extension.greeter.config.GreeterContainerConfig;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.component.Habitat;
import com.sun.enterprise.module.Module;

import java.util.logging.Logger;
import java.util.Map;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.net.URL;

/**
 * @author Jerome Dochez
 */
@Service(name="greeter")
public class GreeterSniffer implements Sniffer {

    @Inject(optional=true)
    GreeterContainerConfig config=null;

    @Inject
    ConfigParser configParser;

    @Inject
    Habitat habitat;

    public boolean handles(ReadableArchive source, ClassLoader loader) {
        return false;
    }

    public String[] getURLPatterns() {
        return new String[0];
    }

    public Class<? extends Annotation>[] getAnnotationTypes() {
        Class<? extends Annotation>[] a = (Class<? extends Annotation>[]) Array.newInstance(Class.class, 1);
        a[0] = Greeter.class;
        return a;
    }

    public String getModuleType() {
        return "greeter";
    }

    public Module[] setup(String containerHome, Logger logger) throws IOException {
        if (config==null) {
            URL url = this.getClass().getClassLoader().getResource("init.xml");
            if (url!=null) {
                configParser.parseContainerConfig(
                    habitat, url, GreeterContainerConfig.class);
            }
        }
        return null;
    }

    public void tearDown() {

    }

    public String[] getContainersNames() {
        String[] c = { GreeterContainer.class.getName() };
        return c;
    }

    public boolean isUserVisible() {
        return true;
    }

    public Map<String, String> getDeploymentConfigurations
        (ReadableArchive source) throws IOException {
        return null;
    }

    public String[] getIncompatibleSnifferTypes() {
        return new String[0];
    }
}
----

[[gkbcq]][[GSACG00239]][[web-client-code]]

Web Client Code
^^^^^^^^^^^^^^^

The web client code is comprised of the classes and resources that are
listed in the following table. The table also provides a cross-reference
to the listing of each class or resource.

[width="100%",cols="<50%,<50%",options="header",]
|==================================================
|Class or Resource |Listing
|`HelloWorld` |link:#gkaki[Example 7-8] +
|`SimpleGreeter` |link:#gkalf[Example 7-9] +
|Deployment descriptor |link:#gkaly[Example 7-10] +
|==================================================


[[GSACG00071]][[gkaki]]


Example 7-8 Container Client Class

[source,oac_no_warn]
----
import components.SimpleGreeter;

import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.annotation.Resource;


@WebServlet(urlPatterns={"/hello"})
public class HelloWorld extends HttpServlet {

    @Resource(name="Simple")
    SimpleGreeter greeter;

    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws IOException, ServletException {


        PrintWriter pw = res.getWriter();
        try {
            pw.println("Injected service is " + greeter);
            if (greeter!=null) {
                pw.println("SimpleService says " + greeter.saySomething());
                pw.println("<br>");
            }
                } catch(Exception e) {
                e.printStackTrace();
        }
    }
}
----

[[GSACG00072]][[gkalf]]


Example 7-9 Component for Container Client

[source,oac_no_warn]
----
package components;

import org.glassfish.examples.extension.greeter.Greeter;

@Greeter(name="simple")
public class SimpleGreeter {

    public String saySomething() {
        return "Bonjour";
    }
}
----

[[GSACG00073]][[gkaly]]


Example 7-10 Deployment Descriptor for Container Client

[source,oac_no_warn]
----
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
  xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation=
    "http://xmlns.jcp.org/xml/ns/javaee
    http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
</web-app>
----
