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 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 @javax.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. Java 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 javax.servlet.annotation.WebServlet;
import javax.servlet.*;
import javax.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>
----
