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]]
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,java]
----
@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,java]
----
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,java]
----
package com.example.containers;

@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,java]
----
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`++'s++ 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,java]
----
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,java]
----
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,java]
----
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,java]
----
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,java]
----
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,java]
----
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,java]
----
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,xml]
----
<?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>
----
