<repo_name>bstansberry/wildflysite<file_sep>/_docs/docs.md
---
layout: docs
title: Wildfly Documentation
permalink: /docs/
---
<file_sep>/_docs/13/_testsuite/Pre-requisites_-_test_quality_standards.adoc
[[Pre-requisites_-_test_quality_standards]]
== Before you add a test

Every added test, whether ported or new should follow the same
guidelines:

== Verify the test belongs in WildFly
AS6 has a lot of tests for things that are discontinued. For example
the +
legacy JBoss Transaction Manager which was replaced by Arjuna. Also we +
had tests for SPIs that no longer exist. None of these things should
be +
migrated.

== Only add CORRECT and UNDERSTANDABLE tests
If you don't understand what a test is doing (perhaps too complex), or +
it's going about things in a strange way that might not be correct,
THEN +
DO NOT PORT IT. Instead we should have a simpler, understandable, and +
correct test. Write a new one, ping the author, or skip it altogether.

== Do not add duplicate tests
Always check that the test you are adding doesn't have coverage +
elsewhere (try using "git grep"). As mentioned above we have some +
overlap between 6 and 7. The 7 test version will likely be better.

== Don't name tests after JIRAs
A JIRA number is useless without an internet connection, and they are +
hard to read. If I get a test failure thats XDGR-843534578 I have to
dig +
to figure out the context. It's perfectly fine though to link to a
JIRA +
number in the comments of the test. Also the commit log is always
available.

== Tests should contain javadoc that explains what is being tested
This is especially critical if the test is non-trivial

== Prefer expanding an EXISTING test over a new test class
If you are looking at migrating or creating a test with similar +
functionality to an exiting test, it is better to +
expand upon the existing one by adding more test methods, rather than +
creating a whole new test. In general each +
new test class adds at least 300ms to execution time, so as long as it +
makes sense it is better to add it to an +
existing test case.

== Organize tests by subsystem
Integration tests should be packaged in subpackages under the relevant +
subsystem (e.g org.jboss.as.test.integration.ejb.async). When a test +
impacts multiple subsystems this is a bit of a judgement call, but in +
general the tests should go into the package of +
the spec that defines the functionality (e.g. CDI based constructor +
injection into an EJB, even though this involves CDI and EJB, +
the CDI spec defines this behaviour)

== Explain non-obvious spec behavior in comments
The EE spec is full of odd requirements. If the test is covering +
behavior that is not obvious then please add something like "Verifies
EE +
X.T.Z - The widget can't have a foobar if it is declared like blah"

== Put integration test resources in the source directory of the test
At the moment there is not real organization of these files. It makes +
sense for most apps to have this separation, however the testsuite is +
different. e.g. most apps will have a single deployment descriptor of
a +
given type, for the testsuite will have hundreds, and maintaining
mirroring +
package structures is error prone. +
This also makes the tests easier to understand, as all the artifacts
in +
the deployment are in one place, and that place tends to be small
(only +
a handful of files).

== Do not hard-code values likely to need configuration (URLs, ports, ...)
URLs hardcoded to certain address (localhost) or port (like the default
8080 for web) prevent running the test against different address or with
IPv6 adress. +
Always use the configurable values provided by Arquillian or as a system
property. +
If you come across a value which is not configurable but you think it
should be, file an WildFly {wildflyVersion} jira issue with component "Test suite". +
See
https://github.com/arquillian/arquillian/blob/master/examples/junit/src/test/java/com/acme/web/LocalRunServletTestCase.java[@ArquillianResourrce
usage example].

== Follow best committing practices
* Only do changes related to the topic of the jira/pull request.
* Do not clutter your pull request with e.g. reformatting, fixing typos
spotted along the way - do another pull request for such.
* Prefer smaller changes in more pull request over one big pull request
which are difficult to merge.
* Keep the code consistent across commits - e.g. when renaming
something, be sure to update all references to it.
* Describe your commits properly as they will appear in master's linear
history.
* If you're working on a jira issue, include it's ID in the commit
message(s).

== Do not use blind timeouts
Do not use Thread.sleep() without checking for the actual condition you
need to be fulfilled. +
You may use active waiting with a timeout, but prefer using timeouts of
the API/SPI you test where available.

Make the timeouts configurable: For a group of similar test, use a
configurable timeout value with a default if not set.

== Provide messages in assert*() and fail() calls
Definitely, it's better to see "File x/y/z.xml not found" instead of:

[source, java]
----
junit.framework.AssertionFailedError
     at junit.framework.Assert.fail(Assert.java:48) [arquillian-service:]
     at junit.framework.Assert.assertTrue(Assert.java:20) [arquillian-service:]
     at junit.framework.Assert.assertTrue(Assert.java:27) [arquillian-service:]
     at org.jboss.as.test.smoke.embedded.parse.ParseAndMarshalModelsTestCase.getOriginalStandaloneXml(ParseAndMarshalModelsTestCase.java:554) [bogus.jar:]
----

== Provide configuration properties hints in exceptions
If your test uses some configuration property and it fails possibly due
to misconfiguration, note the property and it's value in the exception:

[source, java]
----
File jdbcJar = new File( System.getProperty("jbossas.ts.dir", "."),
       "integration/src/test/resources/mysql-connector-java-5.1.15.jar");
    if( !jdbcJar.exists() )
        throw new IllegalStateException("Can't find " + jdbcJar + " using $\{jbossas.ts.dir} == " + System.getProperty("jbossas.ts.dir") );
----

== Clean up
* Close sockets, connections, file descriptors;
* Don't put much data to static fields, or clean them in a finaly {...} block.
* Don't alter AS config (unless you are absolutely sure that it will
reload in a final \{...} block or an @After* method)

== Keep the tests configurable
Keep these things in properties, set them at the beginning of the test:
* Timeouts
* Paths
* URLs
* Numbers (of whatever)

They either will be or already are provided in form of system
properties, or a simple testsuite until API (soon to come).
<file_sep>/_docs/13/_high-availability/subsystem-support/JGroups_Subsystem.adoc
[[JGroups_Subsystem]]
== JGroups Subsystem

[[jgroups-purpose]]
== Purpose

The JGroups subsystem provides group communication support for HA
services in the form of JGroups channels.

Named channel instances permit application peers in a cluster to
communicate as a group and in such a way that the communication
satisfies defined properties (e.g. reliable, ordered,
failure-sensitive). Communication properties are configurable for each
channel and are defined by the protocol stack used to create the
channel. Protocol stacks consist of a base transport layer (used to
transport messages around the cluster) together with a user-defined,
ordered stack of protocol layers, where each protocol layer supports a
given communication property.

The JGroups subsystem provides the following features:

* allows definition of named protocol stacks
* view run-time metrics associated with channels
* specify a default stack for general use

In the following sections, we describe the JGroups subsystem.

[IMPORTANT]

JGroups channels are created transparently as part of the clustering
functionality (e.g. on clustered application deployment, channels will
be created behind the scenes to support clustered features such as
session replication or transmission of SSO contexts around the cluster).

[[jgroups-configuration-example]]
== Configuration example

What follows is a sample JGroups subsystem configuration showing all of
the possible elements and attributes which may be configured. We shall
use this example to explain the meaning of the various elements and
attributes.

[IMPORTANT]

The schema for the subsystem, describing all valid elements and
attributes, can be found in the WildFly distribution, in the `docs/schema`
directory.

[source, xml]
----
<subsystem xmlns="urn:jboss:domain:jgroups:6.0">
    <channels default="ee">
        <channel name="ee" stack="udp" cluster="ejb"/>
    </channels>
    <stacks>
        <stack name="udp">
            <transport type="UDP" socket-binding="jgroups-udp"/>
            <protocol type="PING"/>
            <protocol type="MERGE3"/>
            <protocol type="FD_SOCK"/>
            <protocol type="FD_ALL"/>
            <protocol type="VERIFY_SUSPECT"/>
            <protocol type="pbcast.NAKACK2"/>
            <protocol type="UNICAST3"/>
            <protocol type="pbcast.STABLE"/>
            <protocol type="pbcast.GMS"/>
            <protocol type="UFC"/>
            <protocol type="MFC"/>
            <protocol type="FRAG3"/>
        </stack>
        <stack name="tcp">
            <transport type="TCP" socket-binding="jgroups-tcp"/>
            <socket-protocol type="MPING" socket-binding="jgroups-mping"/>
            <protocol type="MERGE3"/>
            <protocol type="FD_SOCK"/>
            <protocol type="FD_ALL"/>
            <protocol type="VERIFY_SUSPECT"/>
            <protocol type="pbcast.NAKACK2"/>
            <protocol type="UNICAST3"/>
            <protocol type="pbcast.STABLE"/>
            <protocol type="pbcast.GMS"/>
            <protocol type="MFC"/>
            <protocol type="FRAG3"/>
        </stack>
    </stacks>
</subsystem>
----

[[subsystem]]
=== <subsystem>

This element is used to configure the subsystem within a WildFly system
profile.

* `xmlns` This attribute specifies the XML namespace of the JGroups
subsystem and, in particular, its version.

* `default-stack` This attribute is used to specify a default stack for
the JGroups subsystem. This default stack will be used whenever a stack
is required but no stack is specified.

[[stack]]
=== <stack>

This element is used to configure a JGroups protocol stack.

* `name` This attribute is used to specify the name of the stack.

[[jgroups-transport]]
=== <transport>

This element is used to configure the transport layer (required) of the
protocol stack.

* `type` This attribute specifies the transport type (e.g. UDP, TCP,
TCPGOSSIP)
* `socket-binding` This attribute references a defined socket binding in
the server profile. It is used when JGroups needs to create general
sockets internally.
* `diagnostics-socket-binding` This attribute references a defined
socket binding in the server profile. It is used when JGroups needs to
create sockets for use with the diagnostics program. For more about the
use of diagnostics, see the JGroups documentation for probe.sh.
* `default-executor` This attribute references a defined thread pool
executor in the threads subsystem. It governs the allocation and
execution of runnable tasks to handle incoming JGroups messages.
* `oob-executor` This attribute references a defined thread pool
executor in the threads subsystem. It governs the allocation and
execution of runnable tasks to handle incoming JGroups OOB
(out-of-bound) messages.
* `timer-executor` This attribute references a defined thread pool
executor in the threads subsystem. It governs the allocation and
execution of runnable timer-related tasks.
* `shared` This attribute indicates whether or not this transport is
shared amongst several JGroups stacks or not.
* `thread-factory` This attribute references a defined thread factory in
the threads subsystem. It governs the allocation of threads for running
tasks which are not handled by the executors above.
* `site` This attribute defines a site (data centre) id for this node.
* `rack` This attribute defines a rack (server rack) id for this node.
* `machine` This attribute defines a machine (host) is for this node.

[IMPORTANT]

site, rack and machine ids are used by the Infinispan topology-aware
consistent hash function, which when using dist mode, prevents dist mode
replicas from being stored on the same host, rack or site

.

[[property]]
==== <property>

This element is used to configure a transport property.

* `name` This attribute specifies the name of the protocol property. The
value is provided as text for the property element.

[[protocol]]
=== <protocol>

This element is used to configure a (non-transport) protocol layer in
the JGroups stack. Protocol layers are ordered within the stack.

* `type` This attribute specifies the name of the JGroups protocol
implementation (e.g. MPING, pbcast.GMS), with the package prefix
org.jgroups.protocols removed.
* `socket-binding` This attribute references a defined socket binding in
the server profile. It is used when JGroups needs to create general
sockets internally for this protocol instance.

[[relay]]
=== <relay>

This element is used to configure the RELAY protocol for a JGroups
stack. RELAY is a protocol which provides cross-site replication between
defined sites (data centres). In the RELAY protocol, defined sites
specify the names of remote sites (backup sites) to which their data
should be backed up. Channels are defined between sites to permit the
RELAY protocol to transport the data from the current site to a backup
site.

* `site` This attribute specifies the name of the current site. Site
names can be referenced elsewhere (e.g. in the JGroups remote-site
configuration elements, as well as backup configuration elements in the
Infinispan subsystem)

[[remote-site]]
==== <remote-site>

This element is used to configure a remote site for the RELAY protocol.

* `name` This attribute specifies the name of the remote site to which
this configuration applies.
* `stack` This attribute specifies a JGroups protocol stack to use for
communication between this site and the remote site.
* `cluster` This attribute specifies the name of the JGroups channel to
use for communication between this site and the remote site.

[[jgroups-use-cases]]
== Use Cases

In many cases, channels will be configured via XML as in the example
above, so that the channels will be available upon server startup.
However, channels may also be added, removed or have their
configurations changed in a running server by making use of the WildFly
management API command-line interface (CLI). In this section, we present
some key use cases for the JGroups management API.

The key use cases covered are:

* adding a stack
* adding a protocol to an existing stack
* adding a property to a protocol

[IMPORTANT]

The WildFly management API command-line interface (CLI) itself can be
used to provide extensive information on the attributes and commands
available in the JGroups subsystem interface used in these examples.

[[add-a-stack]]
=== Add a stack

[source]
----
/subsystem=jgroups/stack=mystack:add(transport={}, protocols={})
----

[[add-a-protocol-to-a-stack]]
=== Add a protocol to a stack

[source]
----
/subsystem=jgroups/stack=mystack/transport=TRANSPORT:add(type=<type>, socket-binding=<socketbinding>)
----

[source]
----
/subsystem=jgroups/stack=mystack:add-protocol(type=<type>, socket-binding=<socketbinding>)
----

[[add-a-property-to-a-protocol]]
=== Add a property to a protocol

[source]
----
/subsystem=jgroups/stack=mystack/transport=TRANSPORT/property=<property>:add(value=<value>)
----
<file_sep>/_docs/14/JavaEE_Tutorial.adoc
[[JavaEE_Tutorial]]
= JavaEE 7 Tutorial
WildFly team;
:revnumber: {version}
:revdate: {localdate}
:toc: macro
:toclevels: 3
:toc-title: JavaEE 7 Tutorial
:doctype: book
:icons: font
:source-highlighter: coderay
:wildflyVersion: 14

:leveloffset: +1

ifndef::ebook-format[:leveloffset: 1]

(C) 2017 The original authors.

:numbered:


Coming Soon

[IMPORTANT]

This guide is still under development, check back soon!

include::_javaee-guide/Java_API_for_RESTful_Web_Services_(JAX-RS).adoc[]
include::_javaee-guide/Java_Servlet_Technology.adoc[]
include::_javaee-guide/Java_Server_Faces_Technology_(JSF).adoc[]
include::_javaee-guide/Java_Persistence_API_(JPA).adoc[]
include::_javaee-guide/Java_Transaction_API_(JTA).adoc[]
include::_javaee-guide/Managed_Beans.adoc[]
include::_javaee-guide/Contexts_and_Dependency_Injection_(CDI).adoc[]
include::_javaee-guide/Bean_Validation.adoc[]
include::_javaee-guide/Java_Message_Service_API_(JMS).adoc[]
include::_javaee-guide/JavaEE_Connector_Architecture_(JCA).adoc[]
include::_javaee-guide/JavaMail_API.adoc[]
include::_javaee-guide/Java_Authorization_Contract_for_Containers_(JACC).adoc[]
include::_javaee-guide/Java_Authentication_Service_Provider_Interface_for_Containers_(JASPIC).adoc[]
include::_javaee-guide/Enterprise_JavaBeans_Technology_(EJB).adoc[]
include::_javaee-guide/Java_API_for_XML_Web_Services_(JAX-WS).adoc[]
<file_sep>/_docs/13/Testsuite.adoc
[[Testsuite]]
= WildFly Testsuite
WildFly team;
:revnumber: {version}
:revdate: {localdate}
:toc: macro
:toclevels: 3
:toc-title: WildFly testsuite
:doctype: book
:icons: font
:source-highlighter: coderay
:wildflyVersion: 13

:leveloffset: +1

ifndef::ebook-format[:leveloffset: 1]

(C) 2017 The original authors.

:numbered:

include::_testsuite/WildFly_Testsuite_Overview.adoc[]
include::_testsuite/WildFly_Integration_Testsuite_User_Guide.adoc[]
include::_testsuite/WildFly_Testsuite_Harness_Developer_Guide.adoc[]
include::_testsuite/WildFly_Testsuite_Test_Developer_Guide.adoc[]<file_sep>/_docs/13/_high-availability/subsystem-support/Infinispan_Subsystem.adoc
[[Infinispan_Subsystem]]
== Infinispan Subsystem

The Infinispan subsystem configures a set of Infinispan cache containers and cache configurations for use by WildFly clustering services.

== Cache container

A cache container manages a set of cache configurations that share the same transport and marshalling configuration.
Cache containers returned by the Infinispan subsystem are auto-configured with the following customizations:

* A custom xref:transport[transport] capable of sharing a JGroups channel defined by the JGroups subsystem.
* Uses WildFly's mbean server, if the org.jboss.as.jmx extension is present.
* Marshaller configured to resolve classes using JBoss Modules.
* Marshaller configured with a set of marshalling optimizations for common JDK classes
* Marshaller configured with additional Externalizers loadable from the configured module attribute.

e.g. To create a new cache container that loads marshallers from the "org.bar" module:
[source]
----
/subsystem=infinispan/cache-container=foo:add(module=org.foo)
----

A cache container may designate a specific cache as its default cache, i.e. the cache returned via http://docs.jboss.org/infinispan/9.2/apidocs/org/infinispan/manager/CacheContainer.html#getCache--[CacheContainer.getCache()]:

e.g. To set "bar" as the default cache of the "foo" container:
[source]
----
/subsystem=infinispan/cache-container=foo:write-attribute(name=default-cache, value=bar)
----

[[transport]]
=== Transport

Configures the mechanism used by clustered caches to communicate with each other.
It is only necessary to define a transport if the cache container contains clustered caches.

To create a JGroups transport using the default channel of the server:

[source]
----
/subsystem=infinispan/cache-container=foo/transport=jgroups:add()
----

To create a JGroups transport using a distinct "alpha" channel, that uses the "tcp" stack:

[source]
----
/subsystem=jgroups/channel=alpha:add(stack=tcp)
/subsystem=infinispan/cache-container=foo/transport=jgroups:add(channel=alpha)
----

For a complete list of transport attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

To remove an existing JGroups transport, you can either use the standard remove resource operation:

[source]
----
/subsystem=infinispan/cache-container=foo/transport=jgroups:remove()
----

{empty}... or by adding the "none" transport (which will auto-remove any existing transport):

[source]
----
/subsystem=infinispan/cache-container=foo/transport=none:add(){allow-resource-service-restart=true}
----

=== Cache types

Infinispan supports a number of cache types for use in both HA and non-HA server profiles.

==== Local

A local cache stores a given cache entry only on the local node.
A local cache does not require a transport, as cache reads and writes are always local.

For more information about this cache type, refer to the http://infinispan.org/docs/stable/user_guide/user_guide.html#local_mode[the Infinispan documentation].

To create a local cache:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar:add()
----

For a complete list of local-cache attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Replicated

A replicated cache stores a given cache entry on every node in the cluster.
A replicated cache requires a transport, as cache writes are replicated to all nodes in the cluster on which the associated cache is running.

For more information about this cache type, refer to the http://infinispan.org/docs/stable/user_guide/user_guide.html#replicated_mode[the Infinispan documentation].

To create a replicated cache:

[source]
----
/subsystem=infinispan/cache-container=foo/replicated-cache=bar:add()
----

For a complete list of replicated-cache attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Distributed

A distributed cache stores a given cache entry on a configurable number of nodes in the cluster, assigned via an algorithm based on consistent hashing.
A distributed cache requires a transport, as cache writes need to forward to each owner, and cache reads from a non-owner require a remote request.

For more information about this cache type, refer to the http://infinispan.org/docs/stable/user_guide/user_guide.html#distribution_mode[the Infinispan documentation].

To create a distributed cache where a given entry is stored on 3 nodes:

[source]
----
/subsystem=infinispan/cache-container=foo/distributed-cache=bar:add(owners=3)
----

For a complete list of distributed-cache attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Scattered

A scattered cache is a variation of a distributed cache that maintains 2 copies of a particular cache entry.
Consequently, it can only tolerate failure of a single node at a time.
Primary ownership of a cache entry is determined by the same mechanism used by a distributed cache,
while the backup copy is the node that last updated the entry.

This design means that a scattered cache only requires 1 remote invocation to write a given cache entry, regardless of which node initiated the cache operation.
By comparison, a distributed cache (with 2 owners) uses 1 remote invocation to write a cache entry if and only if the primary owner initiated the cache operation, and otherwise requires 2 remote invocations.

For more information about this cache type, refer to the http://infinispan.org/docs/stable/user_guide/user_guide.html#scattered_mode[the Infinispan documentation].

To create a scattered cache:

[source]
----
/subsystem=infinispan/cache-container=foo/scattered-cache=bar:add()
----

For a complete list of scattered-cache attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Invalidation

An invalidation cache is a special type of clustered cache that does not share state, but instead ensures that remote state is invalidated any time a given entry is updated locally.
An invalidation cache requires a transport, as cache writes trigger invalidation on remote nodes on which the associated cache is running.

For more information about this cache type, refer to the http://infinispan.org/docs/stable/user_guide/user_guide.html#invalidation_mode[the Infinispan documentation].

To create an invalidation cache:

[source]
----
/subsystem=infinispan/cache-container=foo/invalidation-cache=bar:add()
----

For a complete list of invalidation-cache attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

=== Cache features

The configuration of a cache is divided into several components, each defining a specific cache feature.
Because a given cache configuration requires each component relevant to its cache type, cache add operations and cache component add operations are typically batched.
Any undefined components are auto-created using their defaults.

e.g. The following cache add operation:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar:add()
----

{empty}... is actually equivalent to the following sequence of operations:

[source]
----
batch
/subsystem=infinispan/cache-container=foo/local-cache=bar:add()
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=expiration:add()
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=locking:add()
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=transaction:add()
/subsystem=infinispan/cache-container=foo/local-cache=bar/memory=object:add()
/subsystem=infinispan/cache-container=foo/local-cache=bar/store=none:add()
run-batch
----

Similarly, you can reset all the attributes of a component by simply removing the component.
e.g.

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar:component=expiration:remove(){allow-resource-service-restart=true}
----

{empty}... is equivalent to:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar:component=expiration:remove(){allow-resource-service-restart=true}
/subsystem=infinispan/cache-container=foo/local-cache=bar:component=expiration:add(){allow-resource-service-restart=true}
----

==== Memory

An Infinispan cache can be configured to store cache entries as Java objects or as binary data (i.e. byte[]), either on or off the JVM heap.
The type of storage used has semantic implications for the user of the cache.
When using object storage, the cache has store-as-reference semantics, whereas when using binary storage the cache has call-by-value semantics.
Consider the following logic:

[source,java]
----
List<String> list = new ArrayList<>();
cache.startBatch();
cache.put("a", list);
list.add("test");
cache.endBatch(true);

List<String> result = cache.get("a");
System.out.println(result.size());
----

How many elements are in the "result" list? The answer depends on how the cache is configured.

When the cache is configured to use object memory, our result list has 1 element.
When the cache is configured to use binary (or off-heap) memory, our result list is empty.
When using binary memory, the cache value must be marshalled to a byte[] on write and unmarshalled on read, thus any mutations of the cache value in the interim are not reflected in the cache.

===== Object storage

When using object storage, cache keys and values are stored as Java object references.
Object storage may be configured with a maximum size.
When the number of entries in the cache exceeds this threshold, the least recently used entries are evicted from memory.

e.g. To store a maximum of 100 objects in the Java heap:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/memory=object:add(size=100)
----

For a complete list of memory=object attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

===== Binary storage (on-heap)

When using binary storage, each cache entry is stored as a byte[] within the JVM heap.
Binary storage may also be configured with a maximum size.
This size can be specified either as a maximum number of entries (i.e. COUNT), or as a maximum number of bytes (i.e. MEMORY).
When the number of entries in the cache exceeds this threshold, the least recently used entries are evicted from memory.

e.g. To store a maximum of 1 MB of binary data in the Java heap:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/memory=binary:add(size=1048576, eviction-type=MEMORY)
----

For a complete list of memory=binary attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

===== Off-heap binary storage

When using off-heap storage, each cache entry is stored as a byte[] in native memory allocated via sun.misc.Unsafe.
Off-heap memory storage may also be configured with a maximum size, specified either as a maximum number of entries (i.e. COUNT), or as a maximum number of bytes (i.e. MEMORY).
When the number of entries in the cache exceeds this threshold, the least recently used entries are evicted from memory.

e.g. To store a maximum of 1 GB of binary data in native memory outside of the Java heap:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/memory=off-heap:add(size=1073741824)
----

For a complete list of memory=off-heap attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Transactions

An Infinispan cache can be configured as transactional or non-transactional.
This behavior is determined by the mode attribute, which supports the following values:

NONE::
    Non-transactional cache (the default behavior).
BATCH::
    Transactional cache using a local Infinispan transaction manager.
    Infinispan transactions are started/committed/rolled-back using http://docs.jboss.org/infinispan/9.2/apidocs/org/infinispan/commons/api/BatchingCache.html[Infinispan's batching API].
NON_XA::
    Transactional cache configured to use the server's transaction manager, registering as a Synchronization to the current transaction.
    Cache commit/rollback happens after the associated transaction completes.
NON_DURABLE_XA::
    Transactional cache configured to use the server's transaction manager, enlisting as an XAResource to the current transaction, but without transaction recovery support.
FULL_XA::
    Transactional cache configured to use the server's transaction manager, with full transaction recovery support.

Within the context of a transaction, cache write operations must obtain a lock on the affected keys.
Locks may be acquired either pessimistically (the default), i.e. before invoking the operation, or optimistically, i.e. before transaction commit.

e.g. To configure a transactional cache using local Infinispan transactions with OPTIMISTIC locking:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=transaction(mode=BATCH, locking=OPTIMISTIC)
----

For a complete list of transaction attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Locking

Within the context of a transaction, entries read from the cache are isolated from other concurrent transactions according to the configured isolation level.
Infinispan supports the following transaction isolation levels:

READ_COMMITTED::
    A cache read may return a different value than a previous read within the same transaction, even if a concurrent transaction updated the entry.
    This is the default isolation level.
REPEATABLE_READ::
    A cache read will return the same value as a previous read within the same transaction, even if a concurrent transaction updated the entry.

IMPORTANT: Cache reads are always lock-free unless invoked using Flag.FORCE_WRITE_LOCK.

e.g. To configure a cache using REPEATABLE_READ isolation:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=locking(isolation=REPEATABLE_READ)
----

For a complete list of locking attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Expiration

The expiration component configures expiration defaults for cache entries.
Cache entries may be configured to expire after some duration since creation (i.e. lifespan) or since last accessed (i.e. max-idle).

e.g. To configure expiration of entries older than 1 day, or that have not been accessed within the past hour:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=expiration(lifespan=86400000, max-idle=3600000)
----

CAUTION: max-idle based expiration is not generally safe for use with clustered caches, as the meta data of a cache entry is not replicated by cache read operations

For a complete list of expiration attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]

==== Persistence

An Infinispan cache can optionally load/store cache entries from an external storage.
All cache stores support the following attributes:

fetch-state::
    Indicates whether to refresh persistent state from cluster members on cache start.
    Does not apply to a local or invalidation cache, nor a shared store.
    Default is true.
passivation::
    Indicates whether cache entries should only be persisted upon eviction from memory.
    Default is true.
preload::
    Indicates whether cache entries should be loaded into memory on cache start.
    Default is false.
purge::
    Indicates whether the cache store should be purged on cache start.
    Purge should never be enabled on a shared store.
    Default is true.
shared::
    Indicates that the same cache store endpoint (e.g. database, data grid, etc.) is used by all members of the cluster.
    When using a shared cache store, cache entries are only persisted by the primary owner of a given cache entry.
    Default is false.

To remove an existing cache store, you can either use the standard resource remove operation:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/store=file:remove()
----

{empty}... or by adding the "none" store (which auto-removes any existing store):

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/store=none:add(){allow-resource-service-restart=true}
----

===== File store

A file store persists cache entries to the local filesystem.
By default, files are stored in a file named "_cache-name_.dat" within a subdirectory named "infinispan/_container-name_" relative to the server's data directory.

e.g. To persist cache entries to $HOME/foo/bar.dat:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/store=file:add(path=foo, relative-to=user.home)
----

===== JDBC store

A JDBC store persists cache entries to a database.

e.g. To persist cache entries to an H2 database via the ExampleDS data-source:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/store=jdbc:add(data-source=ExampleDS, dialect=H2)
----

===== Remote cache store

A remote store persists cache entries to a set of remote Infinispan server instances via the HotRod protocol.

[source]
----
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=node1:add(host=server1, port=1000)
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=node2:add(host=server2, port=1000)
/subsystem=infinispan/cache-container=foo/local-cache=bar/store=remote:add(remote-servers=[node1,node2])
----

==== State transfer

The state transfer component defines the behavior for the initial transfer of state from remote caches on cache start.
State transfer is only applicable to distributed and replicated caches.
When configured with a timeout, a cache is only available after its initial state transfer completes.
If state transfer does not complete within the configured timeout, the cache will fail to start.

e.g. To configure a state-transfer timeout of 1 minute:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=state-transfer:add(timeout=60000)
----

Alternatively, state transfer can be configured to be non-blocking, by configuring a timeout of 0.
While this prevents timeouts due to large state transfers, cache operations on the new node will require remote invocations to retrieve the requisite state until state transfer is complete.

e.g. To configure a non-blocking state transfer:

[source]
----
/subsystem=infinispan/cache-container=foo/local-cache=bar/component=state-transfer:add(timeout=0)
----

For a complete list of state-transfer attributes, refer to the https://wildscribe.github.io/[WildFly management model documentation]
<file_sep>/_docs/13/_testsuite/How_to_Add_a_Test_Case.adoc
[[How_to_Add_a_Test_Case]]
== How to Add a Test Case

_(Please don't (re)move - this is a landing page from a Jira link.)_

*Thank you for finding time to contribute to WildFly {wildflyVersion} quality.* +
Covering corner cases found by community users with tests is very
important to increase stability. +
If you're providing a test case to support your bug report, it's very
likely that your bug will be fixed much sooner.

[[create-a-test-case.]]
== 1) Create a test case.

It's quite easy - a simple use case may even consist of one short .java
file.

Check WildFly {wildflyVersion}
https://github.com/wildfly/wildfly/tree/master/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration[test
suite test cases] for examples.

For more information, see <<WildFly_Testsuite_Test_Developer_Guide,WildFly Testsuite Test
Developer Guide>>. Check the requirements for a test to be included in
the testsuite.

Ask for help at WildFly {wildflyVersion} forum or at IRC - #wildfly @ FreeNode.

[[push-your-test-case-to-github-and-create-a-pull-request.]]
== 2) Push your test case to GitHub and create a pull request.

For information on how to create a GitHub account and push your code
therein, see https://community.jboss.org/wiki/HackingOnWildFly[Hacking
on WildFly].

If you're not into Git, send a diff file to JBoss forums, someone might
pick it up.

[[wait-for-the-outcome.]]
== 3) Wait for the outcome.

Your test case will be reviewed and eventually added. It may take few
days.

When something happens, you'll receive a notification e-mail.
<file_sep>/_docs/14/Getting_Started_Guide.adoc
[[Getting_Started_Guide]]
= Getting Started Guide
WildFly team;
:revnumber: {version}
:revdate: {localdate}
:toc: macro
:toclevels: 3
:toc-title: Getting Started Guide
:doctype: book
:icons: font
:source-highlighter: coderay

ifndef::ebook-format[:leveloffset: 1]

(C) 2017 The original authors.

:numbered:

[[getting-started-with-wildfly]]
== Getting Started with WildFly {wildflyVersion}

WildFly {wildflyVersion} is the latest release in a series of JBoss open-source
application server offerings. WildFly {wildflyVersion} is an exceptionally fast,
lightweight and powerful implementation of the Java Enterprise Edition {javaee_version}
Platform specifications. The state-of-the-art architecture built on the
Modular Service Container enables services on-demand when your
application requires them. The table below lists the Java Enterprise
Edition {javaee_version} technologies and the technologies available in WildFly {wildflyVersion}
server configuration profiles.

[cols=",,,,",options="header"]
|=======================================================================
|Java EE {javaee_version} Platform Technology |Java EE {javaee_version} Full Profile |Java EE {javaee_version} Web
Profile |WildFly {wildflyVersion} Full Profile |WildFly {wildflyVersion} Web Profile

|JSR-356: Java API for Web Socket |X |X |X |X

|JSR-374: Java API for JSON Processing 1.1 |X |X |X |X

|JSR-367: Java API for JSON Binding 1.0 |X |X |X |X

|JSR-369: Java Servlet 4.0 |X |X |X |X

|JSR-372: JavaServer Faces 2.3 |X |X |X |X

|JSR-341: Expression Language 3.0 |X |X |X |X

|JSR-245: JavaServer Pages 2.3 |X |X |X |X

|JSR-52: Standard Tag Library for JavaServer Pages (JSTL) 1.2 |X |X |X
|X

|JSR-352: Batch Applications for the Java Platform 1.0 |X |-- |X |--

|JSR-236: Concurrency Utilities for Java EE 1.0 |X |X |X |X

|JSR-365: Contexts and Dependency Injection for Java 2.0 |X |X |X |X

|JSR-330: Dependency Injection for Java 1.0 |X |X |X |X

|JSR-380: Bean Validation 2.0 |X |X |X |X

|JSR-345: Enterprise JavaBeans 3.2 |XCMP 2.0Optional |X(Lite) |XCMP
2.0Not Available |X(Lite)

|JSR-318: Interceptors 1.2 |X |X |X |X

|JSR-322: Java EE Connector Architecture 1.7 |X |-- |X |X

|JSR-338: Java Persistence 2.2 |X |X |X |X

|JSR-250: Common Annotations for the Java Platform 1.3 |X |X |X |X

|JSR-343: Java Message Service API 2.0 |X |-- |X |--

|JSR-907: Java Transaction API 1.2 |X |X |X |X

|JSR-919: JavaMail 1.6 |X |-- |X |X

|JSR-370: Java API for RESTFul Web Services 2.1 |X |X |X |X

|JSR-109: Implementing Enterprise Web Services 1.3 |X |-- |X |--

|JSR-224: Java API for XML-Based Web Services 2.3 |X |X |X |X

|JSR-181: Web Services Metadata for the Java Platform |X |-- |X |--

|JSR-101: Java API for XML-Based RPC 1.1 |Optional |-- |-- |--

|JSR-67: Java APIs for XML Messaging 1.3 |X |-- |X |--

|JSR-93: Java API for XML Registries |Optional |-- |-- |--

|JSR-222: Java Architecture for XML Binding (JAXB) 2.3 |X |X |X |X

|JSR-196: Java Authentication Service Provider Interface for Containers
1.1 |X |-- |X |--

|JSR-115: Java Authorization Contract for Containers 1.5 |X |-- |X |--

|JSR-88: Java EE Application Deployment 1.2 |Optional |-- |-- |--

|JSR-77: J2EE Management 1.1 |X |  |X | 

|JSR-45: Debugging Support for Other Languages 1.0 |X |X |X |X

|JSR-375: Java EE Security API 1.0 |X |X |X |X
|=======================================================================

Missing HornetQ and JMS?

[WARNING]

The WildFly Web Profile doesn't include JMS (provided by HornetQ) by
default. If you want to use messaging, make sure you start the server
using the "Full Profile" configuration.

This document provides a quick overview on how to download and get
started using WildFly {wildflyVersion} for your application development. For in-depth
content on administrative features, refer to the WildFly {wildflyVersion} Admin Guide.

[[download]]
=== Download

WildFly {wildflyVersion} distributions can be obtained from:

http://www.wildfly.org/downloads/[wildfly.org/downloads]

WildFly {wildflyVersion} provides a single distribution available in zip or tar file
formats.

* *wildfly-{wildflyVersion}.0.0.Final.zip*
* *wildfly-{wildflyVersion}.0.0.Final.tar.gz*

[[requirements]]
=== Requirements

* Java SE 8 or later (we recommend that you use the latest update
available)

[[installation]]
=== Installation

Simply extract your chosen download to the directory of your choice. You
can install WildFly {wildflyVersion} on any operating system that supports the zip or
tar formats. Refer to the Release Notes for additional information
related to the release.

[[wildfly---a-quick-tour]]
=== Wild**Fly** - A Quick Tour

Now that you've downloaded WildFly {wildflyVersion}, the next thing to discuss is the
layout of the distribution and explore the server directory structure,
key configuration files, log files, user deployments and so on. It's
worth familiarizing yourself with the layout so that you'll be able to
find your way around when it comes to deploying your own applications.

[[wildfly-directory-structure]]
==== Wild**Fly** Directory Structure

[cols=",",options="header"]
|=======================================================================
|DIRECTORY |DESCRIPTION

|appclient |Configuration files, deployment content, and writable areas
used by the application client container run from this installation.

|bin |Start up scripts, start up configuration files and various command
line utilities like Vault, add-user and Java diagnostic reportavailable
for Unix and Windows environments

|bin/client |Contains a client jar for use by non-maven based clients.

|docs/schema |XML schema definition files

|docs/examples/configs |Example configuration files representing
specific use cases

|domain |Configuration files, deployment content, and writable areas
used by the domain mode processes run from this installation.

|modules |WildFly is based on a modular classloading architecture.
The various modules used in the server are stored here.

|standalone |Configuration files, deployment content, and writable areas
used by the single standalone server run from this installation.

|welcome-content |Default Welcome Page content
|=======================================================================

[[standalone-directory-structure]]
===== Standalone Directory Structure

In " *_standalone_* " mode each WildFly {wildflyVersion} server instance is an
independent process (similar to previous JBoss AS versions; e.g., 3, 4,
5, or 6). The configuration files, deployment content and writable areas
used by the single standalone server run from a WildFly installation are
found in the following subdirectories under the top level "standalone"
directory:

[cols=",",options="header"]
|=======================================================================
|DIRECTORY |DESCRIPTION

|configuration |Configuration files for the standalone server that runs
off of this installation. All configuration information for the running
server is located here and is the single place for configuration
modifications for the standalone server.

|data |Persistent information written by the server to survive a restart
of the server

|deployments |End user deployment content can be placed in this
directory for automatic detection and deployment of that content into
the server's runtime.NOTE: The server's management API is recommended
for installing deployment content. File system based deployment scanning
capabilities remain for developer convenience.

|lib/ext |Location for installed library jars referenced by applications
using the Extension-List mechanism

|log |standalone server log files

|tmp |location for temporary files written by the server

|tmp/auth |Special location used to exchange authentication tokens with
local clients so they can confirm that they are local to the running AS
process.
|=======================================================================

[[domain-directory-structure]]
===== Domain Directory Structure

A key feature of WildFly {wildflyVersion} is the managing multiple servers from a
single control point. A collection of multiple servers are referred to
as a " *_domain_* ". Domains can span multiple physical (or virtual)
machines with all WildFly instances on a given host under the control of
a Host Controller process. The Host Controllers interact with the Domain
Controller to control the lifecycle of the WildFly instances running on
that host and to assist the Domain Controller in managing them. The
configuration files, deployment content and writeable areas used by
domain mode processes run from a WildFly installation are found in the
following subdirectories under the top level "domain" directory:

[cols=",",options="header"]
|=======================================================================
|DIRECTORY |DESCRIPTION

|configuration |Configuration files for the domain and for the Host
Controller and any servers running off of this installation. All
configuration information for the servers managed wtihin the domain is
located here and is the single place for configuration information.

|content |an internal working area for the Host Controller that controls
this installation. This is where it internally stores deployment
content. This directory is not meant to be manipulated by end users.Note
that "domain" mode does not support deploying content based on scanning
a file system.

|lib/ext |Location for installed library jars referenced by applications
using the Extension-List mechanism

|log |Location where the Host Controller process writes its logs. The
Process Controller, a small lightweight process that actually spawns the
other Host Controller process and any Application Server processes also
writes a log here.

|servers |Writable area used by each Application Server instance that
runs from this installation. Each Application Server instance will have
its own subdirectory, created when the server is first started. In each
server's subdirectory there will be the following subdirectories:data --
information written by the server that needs to survive a restart of the
serverlog -- the server's log filestmp -- location for temporary files
written by the server

|tmp |location for temporary files written by the server

|tmp/auth |Special location used to exchange authentication tokens with
local clients so they can confirm that they are local to the running AS
process.
|=======================================================================

[[wildfly-10-configurations]]
==== Wild**Fly** {wildflyVersion} Configurations

[[standalone-server-configurations]]
===== Standalone Server Configurations

* standalone.xml (_default_)
** Java Enterprise Edition {javaee_version} web profile certified configuration with
the required technologies plus those noted in the table above.

* standalone-ha.xml
** Java Enterprise Edition {javaee_version} web profile certified configuration with
high availability

* standalone-full.xml
** Java Enterprise Edition {javaee_version} full profile certified configuration
including all the required EE {javaee_version} technologies

* standalone-full-ha.xml
** Java Enterprise Edition {javaee_version} full profile certified configuration with
high availability

[[domain-server-configurations]]
===== Domain Server Configurations

* domain.xml
** Java Enterprise Edition {javaee_version} full and web profiles available with or
without high availability

Important to note is that the *_domain_* and *_standalone_* modes
determine how the servers are managed not what capabilities they
provide.

[[starting-wildfly-10]]
==== Starting WildFly {wildflyVersion}

To start WildFly {wildflyVersion} using the default web profile configuration in "
_standalone_" mode, change directory to $JBOSS_HOME/bin.

[source]
----
./standalone.sh
----

To start the default web profile configuration using domain management
capabilities,

[source]
----
./domain.sh
----

[[starting-wildfly-with-an-alternate-configuration]]
==== Starting WildFly with an Alternate Configuration

If you choose to start your server with one of the other provided
configurations, they can be accessed by passing the --server-config
argument with the server-config file to be used.

To use the full profile with clustering capabilities, use the following
syntax from $JBOSS_HOME/bin:

[source, bash]
----
./standalone.sh --server-config=standalone-full-ha.xml
----

Similarly to start an alternate configuration in _domain_ mode:

[source, bash]
----
./domain.sh --domain-config=my-domain-configuration.xml
----

Alternatively, you can create your own selecting the additional
subsystems you want to add, remove, or modify.

[[test-your-installation]]
===== Test Your Installation

After executing one of the above commands, you should see output similar
to what's shown below.

[source, bash]
----
=========================================================================
 
  JBoss Bootstrap Environment
 
  JBOSS_HOME: /opt/wildfly-10.0.0.Final
 
  JAVA: java
 
  JAVA_OPTS:  -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=com.yourkit,org.jboss.byteman -Djava.awt.headless=true
 
=========================================================================
 
11:46:11,161 INFO  [org.jboss.modules] (main) JBoss Modules version 1.5.1.Final
11:46:11,331 INFO  [org.jboss.msc] (main) JBoss MSC version 1.2.6.Final
11:46:11,391 INFO  [org.jboss.as] (MSC service thread 1-6) WFLYSRV0049: WildFly Full 10.0.0.Final (WildFly Core 2.0.10.Final) starting
<snip>
11:46:14,300 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 10.0.0.Final (WildFly Core 2.0.10.Final) started in 1909ms - Started 267 of 553 services (371 services are lazy, passive or on-demand)
----

As with previous WildFly releases, you can point your browser to
*_http://localhost:8080_* (if using the default configured http port)
which brings you to the Welcome Screen:

image:images/wildfly.png[wildfly.png]

From here you can access links to the WildFly community documentation
set, stay up-to-date on the latest project information, have a
discussion in the user forum and access the enhanced web-based
Administration Console. Or, if you uncover a defect while using WildFly,
report an issue to inform us (attached patches will be reviewed). This
landing page is recommended for convenient access to information about
WildFly {wildflyVersion} but can easily be replaced with your own if desired.

[[managing-your-wildfly-10]]
==== Managing your WildFly {wildflyVersion}

WildFly {wildflyVersion} offers two administrative mechanisms for managing your
running instance:

* web-based Administration Console
* command-line interface

===== Authentication

By default WildFly {wildflyVersion} is now distributed with security enabled for the
management interfaces, this means that before you connect using the
administration console or remotely using the CLI you will need to add a
new user, this can be achieved simply by using the _add-user.sh_ script
in the bin folder.

After starting the script you will be guided through the process to add
a new user: -

[source, java]
----
./add-user.sh
What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a):
----

In this case a new user is being added for the purpose of managing the
servers so select option a.

You will then be prompted to enter the details of the new user being
added: -

[source, bash]
----
Enter the details of the new user to add.
Realm (ManagementRealm) :
Username :
Password :
Re-enter Password :
----

It is important to leave the name of the realm as 'ManagementRealm' as
this needs to match the name used in the server's configuration, for the
remaining fields enter the new username, password and password
confirmation.

Provided there are no errors in the values entered you will then be
asked to confirm that you want to add the user, the user will be written
to the properties files used for authentication and a confirmation
message will be displayed.

The modified time of the properties files are inspected at the time of
authentication and the files reloaded if they have changed, for this
reason you do not need to re-start the server after adding a new user.

[[administration-console]]
===== Administration Console

To access the web-based Administration Console, simply follow the link
from the Welcome Screen. To directly access the Management Console,
point your browser at:

*_http://localhost:9990/console_*

NOTE: port 9990 is the default port configured.

[source, xml]
----
<management-interfaces>
   <native-interface security-realm="ManagementRealm">
      <socket-binding native="management-native"/>
   </native-interface>
   <http-interface security-realm="ManagementRealm">
      <socket-binding http="management-http"/>
   </http-interface>
</management-interfaces>
----

If you modify the _management-http_ socket binding in your running
configuration: adjust the above command accordingly. If such
modifications are made, then the link from the Welcome Screen will also
be inaccessible.

If you have not yet added at least one management user an error page
will be displayed asking you to add a new user, after a user has been
added you can click on the 'Try Again' link at the bottom of the error
page to try connecting to the administration console again.

[[command-line-interface]]
===== Command-Line Interface

If you prefer to manage your server from the command line (or batching),
the _jboss-cli.sh_ script provides the same capabilities available via
the web-based UI. This script is accessed from $JBOSS_HOME/bin
directory; e.g.,

[source, bash]
----
$JBOSS_HOME/bin/jboss-cli.sh --connect
Connected to standalone controller at localhost:9990
----

Notice if no host or port information provided, it will default to
localhost:9990.

When running locally to the WildFly process the CLI will silently
authenticate against the server by exchanging tokens on the file system,
the purpose of this exchange is to verify that the client does have
access to the local file system. If the CLI is connecting to a remote
WildFly installation then you will be prompted to enter the username and
password of a user already added to the realm.

Once connected you can add, modify, remove resources and deploy or
undeploy applications. For a complete list of commands and command
syntax, type *_help_* once connected.

[[modifying-the-example-datasource]]
==== Modifying the Example DataSource

As with previous JBoss application server releases, a default data
source, *_ExampleDS_* , is configured using the embedded H2 database for
developer convenience. There are two ways to define datasource
configurations:

1.  as a module
2.  as a deployment

In the provided configurations, H2 is configured as a module. The module
is located in the $JBOSS_HOME/modules/com/h2database/h2 directory. The
H2 datasource configuration is shown below.

[source, xml]
----
<subsystem xmlns="urn:jboss:domain:datasources:1.0">
    <datasources>
        <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS">
            <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
            <driver>h2</driver>
            <pool>
                <min-pool-size>10</min-pool-size>
                <max-pool-size>20</max-pool-size>
                <prefill>true</prefill>
            </pool>
            <security>
                <user-name>sa</user-name>
                <password>sa</password>
            </security>
        </datasource>
        <xa-datasource jndi-name="java:jboss/datasources/ExampleXADS" pool-name="ExampleXADS">
           <driver>h2</driver>
           <xa-datasource-property name="URL">jdbc:h2:mem:test</xa-datasource-property>
           <xa-pool>
                <min-pool-size>10</min-pool-size>
                <max-pool-size>20</max-pool-size>
                <prefill>true</prefill>
           </xa-pool>
           <security>
                <user-name>sa</user-name>
                <password><PASSWORD>>
           </security>
        </xa-datasource>
        <drivers>
            <driver name="h2" module="com.h2database.h2">
                <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
            </driver>
        </drivers>
  </datasources>
</subsystem>
----

The datasource subsystem is provided by the
http://www.jboss.org/ironjacamar[IronJacamar] project. For a detailed
description of the available configuration properties, please consult
the project documentation.

* IronJacamar homepage: http://www.jboss.org/ironjacamar
* Project Documentation: http://www.jboss.org/ironjacamar/docs
* Schema description:
http://docs.jboss.org/ironjacamar/userguide/1.0/en-US/html/deployment.html#deployingds_descriptor

[[configure-logging-in-wildfly]]
===== Configure Logging in WildFly

WildFly logging can be configured with the web console or the command
line interface. You can get more detail on the link:Admin_Guide{outfilesuffix}#Logging[Logging
Configuration] page.

Turn on debugging for a specific category with CLI:

[source, ruby]
----
/subsystem=logging/logger=org.jboss.as:add(level=DEBUG)
----

By default the `server.log` is configured to include all levels in it's
log output. In the above example we changed the console to also display
debug messages.
<file_sep>/_docs/13/_developer-guide/Migrate_Seam_2_Booking_EAR_Binaries_-_Step_by_Step.adoc
[[Migrate_Seam_2_Booking_EAR_Binaries_-_Step_by_Step]]
== Seam 2 Booking Application - Migration of Binaries from EAP5.1 to
WildFly
=========================================================================

This is a step-by-step how-to guide on porting the Seam Booking
application binaries from EAP5.1 to WildFly {wildflyVersion}. Although there are better
approaches for migrating applications, the purpose of this document is
to show the types of issues you might encounter when migrating an
application and how to debug and resolve those issues.

For this example, the application EAR is deployed to the
JBOSS_HOME/standalone/deployments directory with no changes other than
extracting the archives so we can modify the XML files contained within
them.

[[step-1-build-and-deploy-the-eap5.1-version-of-the-seam-booking-application]]
== Step 1: Build and deploy the EAP5.1 version of the Seam Booking
application

1.  Build the EAR
+
[source, java]
----
    cd /EAP5_HOME/jboss-eap5.1/seam/examples/booking
    ~/tools/apache-ant-1.8.2/bin/ant explode
  
----

* Copy the EAR to the JBOSS_HOME deployments directory:
+
[source, java]
----
    cp -r EAP5_HOME/jboss-eap-5.1/seam/examples/booking/exploded-archives/jboss-seam-booking.ear AS7_HOME/standalone/deployments/
    cp -r EAP5_HOME/jboss-eap-5.1/seam/examples/booking/exploded-archives/jboss-seam-booking.war AS7_HOME/standalone/deployments/jboss-seam.ear
    cp -r EAP5_HOME/jboss-eap-5.1/seam/examples/booking/exploded-archives/jboss-seam-booking.jar AS7_HOME/standalone/deployments/jboss-seam.ear
  
----
* Start the WildFly server and check the log. You will see:
+
[source, java]
----
    INFO [org.jboss.as.deployment] (DeploymentScanner-threads - 1) Found jboss-seam-booking.ear in deployment directory. To trigger deployment create a file called jboss-seam-booking.ear.dodeploy
  
----
* Create an empty file with the name `jboss-seam-booking.ear.dodeploy`
and copy it into the deployments directory. In the log, you will now see
the following, indicating that it is deploying:
+
[source, java]
----
    INFO [org.jboss.as.server.deployment] (MSC service thread 1-1) Starting deployment of "jboss-seam-booking.ear"
    INFO [org.jboss.as.server.deployment] (MSC service thread 1-3) Starting deployment of "jboss-seam-booking.jar"
    INFO [org.jboss.as.server.deployment] (MSC service thread 1-6) Starting deployment of "jboss-seam.jar"
    INFO [org.jboss.as.server.deployment] (MSC service thread 1-2) Starting deployment of "jboss-seam-booking.war"
  
----
* At this point, you will first encounter your first deployment error.
In the next section, we will step through each issue and how to debug
and resolve it.
+
[[step-2-debug-and-resolve-deployment-errors-and-exceptions]]
== Step 2: Debug and resolve deployment errors and exceptions

[[first-issue-java.lang.classnotfoundexception-javax.faces.facesexception]]
=== First Issue: java.lang.ClassNotFoundException:
javax.faces.FacesException

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR \[org.jboss.msc.service.fail\] (MSC service thread 1-1) MSC00001: Failed to start service jboss.deployment.subunit."jboss-seam-booking.ear"."jboss-seam-booking.war".POST_MODULE:
org.jboss.msc.service.StartException in service jboss.deployment.subunit."jboss-seam-booking.ear"."jboss-seam-booking.war".POST_MODULE:
Failed to process phase POST_MODULE of subdeployment "jboss-seam-booking.war" of deployment "jboss-seam-booking.ear"
    (.. additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: javax.faces.FacesException from \[Module "deployment.jboss-seam-booking.ear:main" from Service Module Loader\]
    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)
----

[[what-it-means]]
==== What it means:

The ClassNotFoundException indicates a missing dependency. In this case,
it can not find the class `javax.faces.FacesException` and you need to
explicitly add the dependency.

[[how-to-resolve-it]]
==== How to resolve it:

Find the module name for that class in the `AS7_HOME/modules` directory
by looking for a path that matches the missing class. In this case, you
will find 2 modules that match:

[source, java]
----
    javax/faces/api/main
    javax/faces/api/1.2
----

Both modules have the same module name: "javax.faces.api" but one in the
main directory is for JSF 2.0 and the one located in the 1.2 directory
is for JSF 1.2. If there was only one module available, we could simply
create a `MANIFEST.MF` file and added the module dependency. But in this
case, we want to use the JSF 1.2 version and not the 2.0 version in
main, so we need to be able to specify one and exclude the other. To do
this, we create a `jboss-deployment-structure.xml` file in the EAR
`META-INF/` directory that contains the following data:

[source, java]
----
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
     <dependencies>
       <module name="javax.faces.api" slot="1.2" export="true"/>
     </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
   <exclusions>
       <module name="javax.faces.api" slot="main"/>
     </exclusions>
     <dependencies>
       <module name="javax.faces.api" slot="1.2"/>
     </dependencies>
  </sub-deployment>
</jboss-deployment-structure>
----
+
In the "deployment" section, we add the dependency for the
`javax.faces.api` for the JSF 1.2 module. We also add the dependency for
the JSF 1.2 module in the sub-deployment section for the WAR and exclude
the module for JSF 2.0.
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy` file in the same directory.
+
[[next-issue-java.lang.classnotfoundexception-org.apache.commons.logging.log]]
=== Next Issue: java.lang.ClassNotFoundException:
org.apache.commons.logging.Log

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR [org.jboss.msc.service.fail] (MSC service thread 1-8) MSC00001: Failed to start service jboss.deployment.unit."jboss-seam-booking.ear".INSTALL:
org.jboss.msc.service.StartException in service jboss.deployment.unit."jboss-seam-booking.ear".INSTALL:
Failed to process phase INSTALL of deployment "jboss-seam-booking.ear"
    (.. additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.Log from [Module "deployment.jboss-seam-booking.ear.jboss-seam-booking.war:main" from Service Module Loader]
----
+
[[what-it-means-1]]
==== What it means:

The ClassNotFoundException indicates a missing dependency. In this case,
it can not find the class `org.apache.commons.logging.Log` and you need
to explicitly add the dependency.
+
[[how-to-resolve-it-1]]
==== How to resolve it:

Find the module name for that class in the `JBOSS_HOME/modules/`
directory by looking for a path that matches the missing class. In this
case, you will find one module that matches the path
`org/apache/commons/logging/`. The module name is
"org.apache.commons.logging".

Modify the `jboss-deployment-structure.xml` to add the module dependency
to the deployment section of the file.

[source, java]
----
<module name="org.apache.commons.logging" export="true"/>
----
+
The `jboss-deployment-structure.xml` should now look like this:
+
[source, java]
----
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
     <dependencies>
       <module name="javax.faces.api" slot="1.2" export="true"/>
       <module name="org.apache.commons.logging" export="true"/>
     </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
   <exclusions>
       <module name="javax.faces.api" slot="main"/>
     </exclusions>
     <dependencies>
       <module name="javax.faces.api" slot="1.2"/>
     </dependencies>
  </sub-deployment>
</jboss-deployment-structure>
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[next-issue-java.lang.classnotfoundexception-org.dom4j.documentexception]]
=== Next Issue: java.lang.ClassNotFoundException:
org.dom4j.DocumentException

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-booking]] (MSC service thread 1-3) Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener: java.lang.NoClassDefFoundError: org/dom4j/DocumentException
    (... additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.dom4j.DocumentException from [Module "deployment.jboss-seam-booking.ear.jboss-seam.jar:main" from Service Module Loader]
----
+
[[what-it-means-2]]
==== What it means:

Again, the ClassNotFoundException indicates a missing dependency. In
this case, it can not find the class `org.dom4j.DocumentException`.
+
[[how-to-resolve-it-2]]
==== How to resolve it:

Find the module name in the `JBOSS_HOME/modules/` directory by looking
for the `org/dom4j/DocumentException`. The module name is "org.dom4j".

Modify the `jboss-deployment-structure.xml` to add the module dependency
to the deployment section of the file.

[source, java]
----
<module name="org.dom4j" export="true"/>
----
+
The `jboss-deployment-structure.xml` file should now look like this:
+
[source, java]
----
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
     <dependencies>
       <module name="javax.faces.api" slot="1.2" export="true"/>
       <module name="org.apache.commons.logging" export="true"/>
           <module name="org.dom4j" export="true"/>
          </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
   <exclusions>
       <module name="javax.faces.api" slot="main"/>
     </exclusions>
     <dependencies>
       <module name="javax.faces.api" slot="1.2"/>
     </dependencies>
  </sub-deployment>
</jboss-deployment-structure>
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[next-issue-java.lang.classnotfoundexception-org.hibernate.validator.invalidvalue]]
=== Next Issue: java.lang.ClassNotFoundException:
org.hibernate.validator.InvalidValue

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-booking]] (MSC service thread 1-6) Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener: java.lang.RuntimeException: Could not create Component: org.jboss.seam.international.statusMessages
    (... additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.hibernate.validator.InvalidValue from [Module "deployment.jboss-seam-booking.ear.jboss-seam.jar:main" from Service Module Loader]
----
+
[[what-it-means-3]]
==== What it means:

Again, the ClassNotFoundException indicates a missing dependency. In
this case, it can not find the class
`org.hibernate.validator.InvalidValue`.
+
[[how-to-resolve-it-3]]
==== How to resolve it:

There is a module "org.hibernate.validator", but the JAR does not
contain the `org.hibernate.validator.InvalidValue` class, so adding the
module dependency will not resolve this issue.

In this case, the JAR containing the class was part of the EAP 5.1
deployment. We will look for the JAR that contains the missing class in
the `EAP5_HOME/jboss-eap-5.1/seam/lib/` directory. To do this, open a
console and type the following:

[source, java]
----
cd EAP5_HOME/jboss-eap-5.1/seam/lib
grep 'org.hibernate.validator.InvalidValue' `find . -name '*.jar'`
----
+
The result shows:
+
[source, java]
----
Binary file ./hibernate-validator.jar matches
Binary file ./test/hibernate-all.jar matches
----
+
In this case, we need to copy the `hibernate-validator.jar` to the
`jboss-seam-booking.ear/lib/` directory:
+
[source, java]
----
cp EAP5_HOME/jboss-eap-5.1/seam/lib/hibernate-validator.jar jboss-seam-booking.ear/lib
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[next-issue-java.lang.instantiationexception-org.jboss.seam.jsf.seamapplicationfactory]]
=== Next Issue: java.lang.InstantiationException:
org.jboss.seam.jsf.SeamApplicationFactory

When you deploy the application, the log contains the following error:

[source, java]
----
INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-7) Unsanitized stacktrace from failed start...: com.sun.faces.config.ConfigurationException: Factory 'javax.faces.application.ApplicationFactory' was not configured properly.
 at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:296) [jsf-impl-2.0.4-b09-jbossorg-4.jar:2.0.4-b09-jbossorg-4]
 (... additional logs removed ...)
Caused by: javax.faces.FacesException: org.jboss.seam.jsf.SeamApplicationFactory
 at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:606) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]
 (... additional logs removed ...)
 at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:294) [jsf-impl-2.0.4-b09-jbossorg-4.jar:2.0.4-b09-jbossorg-4]
 ... 11 more
Caused by: java.lang.InstantiationException: org.jboss.seam.jsf.SeamApplicationFactory
 at java.lang.Class.newInstance0(Class.java:340) [:1.6.0_25]
 at java.lang.Class.newInstance(Class.java:308) [:1.6.0_25]
 at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:604) [jsf-api-1.2_13.jar:1.2_13-b01-FCS]
 ... 16 more
----
+
[[what-it-means-4]]
==== What it means:

The com.sun.faces.config.ConfigurationException and
java.lang.InstantiationException indicate a dependency issue. In this
case, it is not as obvious.
+
[[how-to-resolve-it-4]]
==== How to resolve it:

We need to find the module that contains the com.sun.faces classes.
While there is no com.sun.faces module, there are are two
com.sun.jsf-impl modules. A quick check of the jsf-impl-1.2_13.jar in
the 1.2 directory shows it contains the com.sun.faces classes.

As we did with the javax.faces.FacesException ClassNotFoundException, we
want to use the JSF 1.2 version and not the JSF 2.0 version in main, so
we need to be able to specify one and exclude the other. We need to
modify the jboss-deployment-structure.xml to add the module dependency
to the deployment section of the file. We also need to add it to the WAR
subdeployment and exclude the JSF 2.0 module. The file should now look
like this:

[source, java]
----
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
     <dependencies>
       <module name="javax.faces.api" slot="1.2" export="true"/>
              <module name="com.sun.jsf-impl" slot="1.2" export="true"/>
       <module name="org.apache.commons.logging" export="true"/>
       <module name="org.dom4j" export="true"/>
     </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
   <exclusions>
       <module name="javax.faces.api" slot="main"/>
       <module name="com.sun.jsf-impl" slot="main"/>
     </exclusions>
     <dependencies>
       <module name="javax.faces.api" slot="1.2"/>
              <module name="com.sun.jsf-impl" slot="1.2"/>
     </dependencies>
  </sub-deployment>
</jboss-deployment-structure>
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[next-issue-java.lang.classnotfoundexception-org.apache.commons.collections.arraystack]]
=== Next Issue: java.lang.ClassNotFoundException:
org.apache.commons.collections.ArrayStack

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/seam-booking]] (MSC service thread 1-1) Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener: java.lang.RuntimeException: com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! org.apache.commons.collections.ArrayStack from [Module "deployment.jboss-seam-booking.ear:main" from Service Module Loader]
    (... additional logs removed ...)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.ArrayStack from [Module "deployment.jboss-seam-booking.ear:main" from Service Module Loader] 
----
+
[[what-it-means-5]]
==== What it means:

Again, the ClassNotFoundException indicates a missing dependency. In
this case, it can not find the class
`org.apache.commons.collections.ArrayStack`.
+
[[how-to-resolve-it-5]]
==== How to resolve it:

Find the module name in the `JBOSS_HOME/modules/` directory by looking
for the `org/apache/commons/collections` path. The module name is
"org.apache.commons.collections".

Modify the `jboss-deployment-structure.xml` to add the module dependency
to the deployment section of the file.

[source, java]
----
<module name="org.apache.commons.collections" export="true"/>
----
+
The `jboss-deployment-structure.xml` file should now look like this:
+
[source, java]
----
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
     <dependencies>
       <module name="javax.faces.api" slot="1.2" export="true"/>
              <module name="com.sun.jsf-impl" slot="1.2" export="true"/>
       <module name="org.apache.commons.logging" export="true"/>
       <module name="org.dom4j" export="true"/>
       <module name="org.apache.commons.collections" export="true"/>
   </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
   <exclusions>
       <module name="javax.faces.api" slot="main"/>
       <module name="com.sun.jsf-impl" slot="main"/>
     </exclusions>
     <dependencies>
       <module name="javax.faces.api" slot="1.2"/>
              <module name="com.sun.jsf-impl" slot="1.2"/>
     </dependencies>
  </sub-deployment>
</jboss-deployment-structure>
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[next-issue-services-with-missingunavailable-dependencies]]
=== Next Issue: Services with missing/unavailable dependencies

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR [org.jboss.as.deployment] (DeploymentScanner-threads - 2) {"Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"Services with missing/unavailable dependencies" => ["jboss.deployment.subunit.\"jboss-seam-booking.ear\".\"jboss-seam-booking.jar\".component.AuthenticatorAction.START missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".AuthenticatorAction.\"env/org.jboss.seam.example.booking.AuthenticatorAction/em\" ]","jboss.deployment.subunit.\"jboss-seam-booking.ear\".\"jboss-seam-booking.jar\".component.HotelSearchingAction.START missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".HotelSearchingAction.\"env/org.jboss.seam.example.booking.HotelSearchingAction/em\" ]","
<... additional logs removed ...>
"jboss.deployment.subunit.\"jboss-seam-booking.ear\".\"jboss-seam-booking.jar\".component.BookingListAction.START missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".BookingListAction.\"env/org.jboss.seam.example.booking.BookingListAction/em\" ]","jboss.persistenceunit.\"jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase\" missing [ jboss.naming.context.java.bookingDatasource ]"]}}}
----
+
[[what-it-means-6]]
==== What it means:

When you get a "Services with missing/unavailable dependencies" error,
look that the text within the brackets after "missing".

In this case you see:

[source, java]
----
missing [ jboss.naming.context.java.comp.jboss-seam-booking.\"jboss-seam-booking.jar\".AuthenticatorAction.\"env/org.jboss.seam.example.booking.AuthenticatorAction/em\" ]
----
+
The "/em" indicates an Entity Manager and datasource issue.
+
[[how-to-resolve-it-6]]
==== How to resolve it:

In WildFly {wildflyVersion}, datasource configuration has changed and needs to be
defined in the `standalone/configuration/standalone.xml` file. Since
WildFly ships with an example database that is already defined in the
standalone.xml file, we will modify the `persistence.xml` file to use
that example database. Looking in the `standalone.xml` file, you can see
that the jndi-name for the example database is
"java:jboss/datasources/ExampleDS".

Modify the `jboss-seam-booking.jar/META-INF/persistence.xml` file to
comment the existing jta-data-source element and replace it as follows:

[source, java]
----
<!-- <jta-data-source>java:/bookingDatasource</jta-data-source> -->
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[next-issue-java.lang.classnotfoundexception-org.hibernate.cache.hashtablecacheprovider]]
=== Next Issue: java.lang.ClassNotFoundException:
org.hibernate.cache.HashtableCacheProvider

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed to start service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": org.jboss.msc.service.StartException in service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": Failed to start service
 at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1786)
 (... log messages removed ...)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: bookingDatabase] Unable to build EntityManagerFactory
 at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:903)
 {... log messages removed ...)
Caused by: org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge]
 at org.hibernate.cfg.SettingsFactory.createRegionFactory(SettingsFactory.java:355)
 (... log messages removed ...)
Caused by: java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [:1.6.0_25]
 (... log messages removed ...)
Caused by: org.hibernate.cache.CacheException: could not instantiate CacheProvider [org.hibernate.cache.HashtableCacheProvider]
 at org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge.<init>(RegionFactoryCacheProviderBridge.java:68)
 ... 20 more
Caused by: java.lang.ClassNotFoundException: org.hibernate.cache.HashtableCacheProvider from [Module "org.hibernate:main" from local module loader @12a3793 (roots: /home/sgilda/tools/jboss7/modules)]
 at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)
 (... log messages removed ...)
----
+
[[what-it-means-7]]
==== What it means:

The ClassNotFoundException indicates a missing dependency. In this case,
it can not find the class org.hibernate.cache.HashtableCacheProvider.
+
[[how-to-resolve-it-7]]
==== How to resolve it:

There is no module for "org.hibernate.cache". In this case, the JAR
containing the class was part of the EAP 5.1 deployment. We will look
for the JAR that contains the missing class in the
`EAP5_HOME/jboss-eap-5.1/seam/lib/` directory.

To do this, open a console and type the following:

[source, java]
----
cd EAP5_HOME/jboss-eap-5.1/seam/lib
grep 'org.hibernate.validator.InvalidValue' `find . -name '*.jar'`
----
+
The result shows:
+
[source, java]
----
Binary file ./hibernate-core.jar matches
Binary file ./test/hibernate-all.jar matches
----
+
In this case, we need to copy the `hibernate-core.jar` to the
`jboss-seam-booking.ear/lib/` directory:
+
[source, java]
----
cp EAP5_HOME/jboss-eap-5.1/seam/lib/hibernate-core.jar jboss-seam-booking.ear/lib
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[next-issue-java.lang.classcastexception-org.hibernate.cache.hashtablecacheprovider]]
=== Next Issue: java.lang.ClassCastException:
org.hibernate.cache.HashtableCacheProvider

When you deploy the application, the log contains the following error:

[source, java]
----
ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC00001: Failed to start service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": org.jboss.msc.service.StartException in service jboss.persistenceunit."jboss-seam-booking.ear/jboss-seam-booking.jar#bookingDatabase": Failed to start service
 at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1786)
 (... log messages removed ...)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: bookingDatabase] Unable to build EntityManagerFactory
 at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:903)
 (... log messages removed ...)
Caused by: org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge]
 at org.hibernate.cfg.SettingsFactory.createRegionFactory(SettingsFactory.java:355)
 (... log messages removed ...)
Caused by: java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [:1.6.0_25]
 (... log messages removed ...)
Caused by: org.hibernate.cache.CacheException: could not instantiate CacheProvider [org.hibernate.cache.HashtableCacheProvider]
 at org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge.<init>(RegionFactoryCacheProviderBridge.java:68)
 ... 20 more
Caused by: java.lang.ClassCastException: org.hibernate.cache.HashtableCacheProvider cannot be cast to org.hibernate.cache.spi.CacheProvider
 at org.hibernate.cache.internal.bridge.RegionFactoryCacheProviderBridge.<init>(RegionFactoryCacheProviderBridge.java:65)
 ... 20 more
----
+
[[what-it-means-8]]
==== What it means:

A ClassCastException can be a result of many problems. If you look at
this exception in the log, it appears the class
org.hibernate.cache.HashtableCacheProvider extends
org.hibernate.cache.spi.CacheProvider and is being loaded by a different
class loader than the class it extends. The
org.hibernate.cache.HashtableCacheProvider class is in in the
hibernate-core.jar and is being loaded by the application class loader.
The class it extends, org.hibernate.cache.spi.CacheProvider, is in the
org/hibernate/main/hibernate-core-4.0.0.Beta1.jar and is implicitly
loaded by that module.

This is not obvious, but due to changes in Hibernate 4, this problem is
caused by a backward compatibility issue due moving the
HashtableCacheProvider class into another package. This class was moved
from the org.hibernate.cache package to the org.hibernate.cache.internal
package. If you don't remove the hibernate.cache.provider_class property
from the persistence.xml file, it will force the Seam application to
bundle the old Hibernate libraries, resulting in ClassCastExceptions, In
WildFly, you should move away from using HashtableCacheProvider and use
Infinispan instead.
+
[[how-to-resolve-it-8]]
==== How to resolve it:

In WildFly, you need to comment out the hibernate.cache.provider_class
property in the `jboss-seam-booking.jar/META-INF persistence.xml` file
as follows:

[source, java]
----
<!-- <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/> -->
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy file` in the same directory.
+
[[no-more-issues-deployment-errors-should-be-resolved]]
=== No more issues: Deployment errors should be resolved

At this point, the application should deploy without errors, but when
you access the URL " http://localhost:8080/seam-booking/" in a browser
and attempt "Account Login", you will get a runtime error "The page
isn't redirecting properly". In the next section, we will step through
each runtime issue and how to debug and resolve it.
+
[[step-3-debug-and-resolve-runtime-errors-and-exceptions]]
== Step 3: Debug and resolve runtime errors and exceptions

[[first-issue-javax.naming.namenotfoundexception-name-jboss-seam-booking-not-found-in-context]]
=== First Issue: javax.naming.NameNotFoundException: Name
'jboss-seam-booking' not found in context ''

The application deploys successfully, but when you access the URL "
http://localhost:8080/seam-booking/" in a browser, you get "The page
isn't redirecting properly" and the log contains the following error:

[source, java]
----
SEVERE [org.jboss.seam.jsf.SeamPhaseListener] (http--127.0.0.1-8080-1) swallowing exception: java.lang.IllegalStateException: Could not start transaction
 at org.jboss.seam.jsf.SeamPhaseListener.begin(SeamPhaseListener.java:598) [jboss-seam.jar:]
 (... log messages removed ...)
Caused by: org.jboss.seam.InstantiationException: Could not instantiate Seam component: org.jboss.seam.transaction.synchronizations
 at org.jboss.seam.Component.newInstance(Component.java:2170) [jboss-seam.jar:]
 (... log messages removed ...)
Caused by: javax.naming.NameNotFoundException: Name 'jboss-seam-booking' not found in context ''
 at org.jboss.as.naming.util.NamingUtils.nameNotFoundException(NamingUtils.java:109)
 (... log messages removed ...)
----

[[what-it-means-9]]
==== What it means:

A NameNotFoundException indications a JNDI naming issue. JNDI naming
rules have changed in WildFly and we need to modify the lookup names to
follow the new rules.

[[how-to-resolve-it-9]]
==== How to resolve it:

To debug this, look earlier in the server log trace to what JNDI binding
were used. Looking at the server log we see this:

[source, java]
----
15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named RegisterAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam-booking.jar/RegisterAction!org.jboss.seam.example.booking.Register
 java:app/jboss-seam-booking.jar/RegisterAction!org.jboss.seam.example.booking.Register
 java:module/RegisterAction!org.jboss.seam.example.booking.Register
 java:global/jboss-seam-booking/jboss-seam-booking.jar/RegisterAction
 java:app/jboss-seam-booking.jar/RegisterAction
 java:module/RegisterAction
 
15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named BookingListAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam-booking.jar/BookingListAction!org.jboss.seam.example.booking.BookingList
 java:app/jboss-seam-booking.jar/BookingListAction!org.jboss.seam.example.booking.BookingList
 java:module/BookingListAction!org.jboss.seam.example.booking.BookingList
 java:global/jboss-seam-booking/jboss-seam-booking.jar/BookingListAction
 java:app/jboss-seam-booking.jar/BookingListAction
 java:module/BookingListAction
 
15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named HotelBookingAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelBookingAction!org.jboss.seam.example.booking.HotelBooking
 java:app/jboss-seam-booking.jar/HotelBookingAction!org.jboss.seam.example.booking.HotelBooking
 java:module/HotelBookingAction!org.jboss.seam.example.booking.HotelBooking
 java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelBookingAction
 java:app/jboss-seam-booking.jar/HotelBookingAction
 java:module/HotelBookingAction
 
15:01:16,138 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named AuthenticatorAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam-booking.jar/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator
 java:app/jboss-seam-booking.jar/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator
 java:module/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator
 java:global/jboss-seam-booking/jboss-seam-booking.jar/AuthenticatorAction
 java:app/jboss-seam-booking.jar/AuthenticatorAction
 java:module/AuthenticatorAction
 
15:01:16,139 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named ChangePasswordAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam-booking.jar/ChangePasswordAction!org.jboss.seam.example.booking.ChangePassword
 java:app/jboss-seam-booking.jar/ChangePasswordAction!org.jboss.seam.example.booking.ChangePassword
 java:module/ChangePasswordAction!org.jboss.seam.example.booking.ChangePassword
 java:global/jboss-seam-booking/jboss-seam-booking.jar/ChangePasswordAction
 java:app/jboss-seam-booking.jar/ChangePasswordAction
 java:module/ChangePasswordAction
 
15:01:16,139 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named HotelSearchingAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching
 java:app/jboss-seam-booking.jar/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching
 java:module/HotelSearchingAction!org.jboss.seam.example.booking.HotelSearching
 java:global/jboss-seam-booking/jboss-seam-booking.jar/HotelSearchingAction
 java:app/jboss-seam-booking.jar/HotelSearchingAction
 java:module/HotelSearchingAction
 
15:01:16,140 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named EjbSynchronizations in deployment unit subdeployment "jboss-seam.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations
 java:app/jboss-seam/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations
 java:module/EjbSynchronizations!org.jboss.seam.transaction.LocalEjbSynchronizations
 java:global/jboss-seam-booking/jboss-seam/EjbSynchronizations
 java:app/jboss-seam/EjbSynchronizations
 java:module/EjbSynchronizations
 
15:01:16,140 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-6) JNDI bindings for session bean named TimerServiceDispatcher in deployment unit subdeployment "jboss-seam.jar" of deployment "jboss-seam-booking.ear" are as follows:
 
 java:global/jboss-seam-booking/jboss-seam/TimerServiceDispatcher!org.jboss.seam.async.LocalTimerServiceDispatcher
 java:app/jboss-seam/TimerServiceDispatcher!org.jboss.seam.async.LocalTimerServiceDispatcher
 java:module/TimerServiceDispatcher!org.jboss.seam.async.LocalTimerServiceDispatcher
 java:global/jboss-seam-booking/jboss-seam/TimerServiceDispatcher
 java:app/jboss-seam/TimerServiceDispatcher
 java:module/TimerServiceDispatcher
----

We need to modify the WAR's lib/components.xml file to use the new JNDI
bindings. In the log, note the EJB JNDI bindings all start with
"java:app/jboss-seam-booking.jar"

Replace the <core:init> element as follows:

[source, java]
----
<!--     <core:init jndi-pattern="jboss-seam-booking/#{ejbName}/local" debug="true" distributable="false"/> -->
<core:init jndi-pattern="java:app/jboss-seam-booking.jar/#{ejbName}" debug="true" distributable="false"/>
----
+
Next, we need to add the EjbSynchronizations and TimerServiceDispatcher
JNDI bindings. Add the following component elements to the file:
+
[source, java]
----
<component class="org.jboss.seam.transaction.EjbSynchronizations" jndi-name="java:app/jboss-seam/EjbSynchronizations"/>
<component class="org.jboss.seam.async.TimerServiceDispatcher" jndi-name="java:app/jboss-seam/TimerServiceDispatcher"/>
----
+
The components.xml file should now look like this:
+
[source, java]
----
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core="http://jboss.com/products/seam/core"
            xmlns:security="http://jboss.com/products/seam/security"
            xmlns:transaction="http://jboss.com/products/seam/transaction"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation=
                "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
                 http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.2.xsd
                 http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.2.xsd
                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">
 
    <!-- <core:init jndi-pattern="jboss-seam-booking/#{ejbName}/local" debug="true" distributable="false"/> -->
    <core:init jndi-pattern="java:app/jboss-seam-booking.jar/#{ejbName}" debug="true" distributable="false"/>
 
    <core:manager conversation-timeout="120000"
                  concurrent-request-timeout="500"
                  conversation-id-parameter="cid"/>
 
    <transaction:ejb-transaction/>
 
    <security:identity authenticate-method="#{authenticator.authenticate}"/>
 
    <component class="org.jboss.seam.transaction.EjbSynchronizations"
            jndi-name="java:app/jboss-seam/EjbSynchronizations"/>
    <component class="org.jboss.seam.async.TimerServiceDispatcher"
            jndi-name="java:app/jboss-seam/TimerServiceDispatcher"/>
</components>
----
+
Redeploy the application by deleting the
`standalone/deployments/jboss-seam-booking.ear.failed` file and creating
a blank `jboss-seam-booking.ear.dodeploy` file in the same directory.
+
At this point, the application should deploy and run without error. When
you access the URL " http://localhost:8080/seam-booking/" in a browser,
you will be able to login successfully.
+
[[step-4-access-the-application]]
== Step 4: Access the application

Access the URL " http://localhost:8080/seam-booking/" in a browser and
login with demo/demo. You should the Booking welcome page.
+
[[summary-of-changes]]
== Summary of Changes

Although it would be much more efficient to determine dependencies in
advance and add the implicit dependencies in one step, this exercise
shows how problems appear in the log and provides some information on
how to debug and resolve them.

The following is a summary of changes made to the application when
migrating it to WildFly:

1.  We created a `jboss-deployment-structure.xml` file in the EAR's
`META-INF/` directory. We added "dependencies" and "exclusions" to
resolve ClassNotFoundExceptions. This file contains the following data:
+
[source, java]
----
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
  <deployment>
     <dependencies>
       <module name="javax.faces.api" slot="1.2" export="true"/>
       <module name="com.sun.jsf-impl" slot="1.2" export="true"/>
       <module name="org.apache.commons.logging" export="true"/>
           <module name="org.dom4j" export="true"/>
       <module name="org.apache.commons.collections" export="true"/>
     </dependencies>
  </deployment>
  <sub-deployment name="jboss-seam-booking.war">
   <exclusions>
       <module name="javax.faces.api" slot="main"/>
       <module name="com.sun.jsf-impl" slot="main"/>
     </exclusions>
     <dependencies>
       <module name="javax.faces.api" slot="1.2"/>
       <module name="com.sun.jsf-impl" slot="1.2"/>
     </dependencies>
  </sub-deployment>
</jboss-deployment-structure>
----
* We copied the following JARs from the
`EAP5_HOME/jboss-eap-5.1/seam/lib/` directory to the
`jboss-seam-booking.ear/lib/` directory to resolve
ClassNotFoundExceptions:
+
[source, java]
----
hibernate-core.jar
hibernate-validator.jar
----
* We modified the \{\{jboss-seam-booking.jar/META-INF/persistence.xml}
file as follows.
1.  First, we changed the jta-data-source element to use the Example
database that ships with AS7:
+
[source, java]
----
<!-- <jta-data-source>java:/bookingDatasource</jta-data-source> -->
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
----
2.  Next, we commented out the hibernate.cache.provider_class property:
+
[source, java]
----
<!-- <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/> -->
----
* We modified the WAR's lib/components.xml file to use the new JNDI
bindings
1.  We replaced the <core:init> existing element as follows:
+
[source, java]
----
<!-- <core:init jndi-pattern="jboss-seam-booking/#{ejbName}/local" debug="true" distributable="false"/> -->
<core:init jndi-pattern="java:app/jboss-seam-booking.jar/#{ejbName}" debug="true" distributable="false"/>
----
2.  We added component elements for the "EjbSynchronizations" and
"TimerServiceDispatcher" JNDI bindings
+
[source, java]
----
 <component class="org.jboss.seam.transaction.EjbSynchronizations" jndi-name="java:app/jboss-seam/EjbSynchronizations"/>
 <component class="org.jboss.seam.async.TimerServiceDispatcher" jndi-name="java:app/jboss-seam/TimerServiceDispatcher"/>
----
* The unmodified EAR from EAP 5.1 (jboss-seam-booking-eap51.ear.tar.gz)
and the EAR as modified to run on AS7
(jboss-seam-booking-as7.ear.tar.gz) are attached to this document.
<file_sep>/_docs/13/_testsuite/How_the_server_is_built_and_configured_for_testsuite_modules.adoc
[[How_the_server_is_built_and_configured_for_testsuite_modules]]
== How the WildFly is built and configured for testsuite modules.

Refer to <<Shortened_Maven_Run_Overview,Shortened Maven Run Overview>> to see the
mentioned build steps.

\1) AS instance is copied from `${jboss.dist`} to
`testsuite/target/jbossas`. +
Defaults to AS which is built by the project (
`build/target/jboss-as-*`).

2)

*testsuite/pom.xml:*

from $\{jboss.home} to $\{basedir}/target/jbossas +
phase generate-test-resources: resource-plugin, goal copy-resources

*testsuite/integration/pom.xml:*

phase process-test-resources: antrun-plugin:

[source, xml]
----
<ant antfile="$\{basedir}/src/test/scripts/basic-integration-build.xml">
    <target name="build-basic-integration"/>
    <target name="build-basic-integration-jts"/>
</ant>
----

Which invokes

[source, xml]
----
<target name="build-basic-integration" description="Builds server configuration for basic-integration tests">
      <build-server-config name="jbossas"/>
----

Which invokes

[source, xml]
----
<!-- Copy the base distribution. -->
<!-- We exclude modules and bundles as they are read-only and we locate the via sys props. -->
<copy todir="@{output.dir}/@{name}">
    <fileset dir="@{jboss.dist}">
        <exclude name="**/modules/**"/>
        <exclude name="**/bundles/**"/>
    </fileset>
</copy>
 
<!-- overwrite with configs from test-configs and apply property filtering -->
<copy todir="@{output.dir}/@{name}" overwrite="true" failonerror="false">
    <fileset dir="@{test.configs.dir}/@{name}"/>
    <filterset begintoken="${" endtoken="}">
        <filter token="node0" value="${node0}"/>
        <filter token="node1" value="${node1}"/>
        <filter token="udpGroup" value="${udpGroup}"/>
        <filter-elements/>
    </filterset>
</copy>
----

[[arquillian-config-file-location]]
== Arquillian config file location

[source, bash]
----
-Darquillian.xml=some-file-or-classpath-resource.xml
----
<file_sep>/_docs/13/common_attributes.adoc
:oracle-javadoc:    https://docs.oracle.com/javase/8/docs/api/java
:appservername:     WildFly<file_sep>/_docs/14/_admin-guide/add-user-utility.adoc
[[add-user-utility]]
= add-user utility
ifdef::env-github[:imagesdir: ../]

For use with the default configuration we supply a utility `add-user`
which can be used to manage the properties files for the default realms
used to store the users and their roles.

The add-user utility can be used to manage both the users in the
`ManagementRealm` and the users in the `ApplicationRealm`, changes made
apply to the properties file used both for domain mode and standalone
mode.

[TIP]

After you have installed your application server and decided if you are
going to run in standalone mode or domain mode you can delete the parent
folder for the mode you are not using, the add-user utility will then
only be managing the properties file for the mode in use.

The add-user utility is a command line utility however it can be run in
both interactive and non-interactive mode. Depending on your platform
the script to run the add-user utility is either `add-user.sh` or
`add-user.bat` which can be found in \{ `jboss.home}/bin`.

This guide now contains a couple of examples of this utility in use to
accomplish the most common tasks.

[[adding-a-user]]
== Adding a User

Adding users to the properties files is the primary purpose of this
utility. Usernames can only contain the following characters in any
number and in any order:

* Alphanumeric characters (a-z, A-Z, 0-9)
* Dashes (-), periods (.), commas (,), at (@)
* Escaped backslash ( \\ )
* Escaped equals (\=)

[NOTE]

The server caches the contents of the properties files in memory,
however the server does check the modified time of the properties files
on each authentication request and re-load if the time has been updated
- this means all changes made by this utility are immediately applied to
any running server.

[[a-management-user]]
=== A Management User

[NOTE]

The default name of the realm for management users is `ManagementRealm`,
when the utility prompts for the realm name just accept the default
unless you have switched to a different realm.

[[interactive-mode]]
==== Interactive Mode

image:images/add-mgmt-user-interactive.png[Add mgmt user interactive]

Here we have added a new Management User called `adminUser`, as you can
see some of the questions offer default responses so you can just press
enter without repeating the default value.

For now just answer `n` or `no` to the final question, adding users to
be used by processes is described in more detail in the domain
management chapter.

[[add-user-non-interactive-mode]]
==== Non-Interactive Mode

To add a user in non-interactive mode the command
`./add-user.sh {username} {password`} can be used.

image:images/add-mgmt-user-non-interactive.png[add-mgmt-user-non-interactive.png]

[WARNING]

If you add users using this approach there is a risk that any other user
that can view the list of running process may see the arguments
including the password of the user being added, there is also the risk
that the username / password combination will be cached in the history
file of the shell you are currently using.

[[an-application-user]]
=== An Application User

When adding application users in addition to adding the user with their
pre-hashed password it is also now possible to define the roles of the
user.

[[interactive-mode-1]]
==== Interactive Mode

image:images/add-app-user-interactive.png[add-app-user-interactive.png]

Here a new user called `appUser` has been added, in this case a comma
separated list of roles has also been specified.

As with adding a management user just answer `n` or `no` to the final
question until you know you are adding a user that will be establishing
a connection from one server to another.

[[non-interactive-mode-1]]
==== Non-Interactive Mode

To add an application user non-interactively use the command
`./add-user.sh -a {username} {password`}.

image:images/add-app-user-non-interactive.png[add-app-user-non-interactive.png]

[NOTE]

Non-interactive mode does not support defining a list of users, to
associate a user with a set of roles you will need to manually edit the
`application-roles.properties` file by hand.

[[updating-a-user]]
== Updating a User

Within the add-user utility it is also possible to update existing
users, in interactive mode you will be prompted to confirm if this is
your intention.

[[a-management-user-1]]
=== A Management User

[[interactive-mode-2]]
==== Interactive Mode

image:images/update-mgmt-user-interactive.png[update-mgmt-user-interactive.png]

[[non-interactive-mode-2]]
==== Non-Interactive Mode

In non-interactive mode if a user already exists the update is automatic
with no confirmation prompt.

[[an-application-user-1]]
=== An Application User

==== Interactive Mode

image:images/update-app-user-interactive.png[images/update-app-user-interactive.png]

[NOTE]

On updating a user with roles you will need to re-enter the list of
roles assigned to the user.

==== Non-Interactive Mode

In non-interactive mode if a user already exists the update is automatic
with no confirmation prompt.

[[community-contributions]]
== Community Contributions

There are still a few features to add to the add-user utility such as
removing users or adding application users with roles in non-interactive
mode, if you are interested in contributing to Wild**Fly** development the
add-user utility is a good place to start as it is a stand alone
utility, however it is a part of the AS build so you can become familiar
with the AS development processes without needing to delve straight into
the internals of the application server.
<file_sep>/_docs/13/_testsuite/WildFly_Testsuite_Harness_Developer_Guide.adoc
[[WildFly_Testsuite_Harness_Developer_Guide]]
== WildFly Testsuite Harness Developer Guide

*Audience:* Whoever wants to change the testsuite harness

*JIRA*: https://issues.jboss.org/browse/WFLY-576[WFLY-576]

[[testsuite-requirements]]
== Testsuite requirements

http://community.jboss.org/wiki/ASTestsuiteRequirements will probably be
merged here later.

[[adding-a-new-maven-plugin]]
== Adding a new maven plugin

The plugin version needs to be specified in jboss-parent. See
https://github.com/jboss/jboss-parent-pom/blob/master/pom.xml#L65 .

[[shortened-maven-run-overview]]
== Shortened Maven run overview

See <<Shortened_Maven_Run_Overview,Shortened Maven Run Overview>>.

[[how-the-as-instance-is-built]]
== How the AS instance is built

See <<How_the_server_is_built_and_configured_for_testsuite_modules,How the JBoss AS instance is built and configured
for testsuite modules.>>

[[properties-and-their-propagation]]
== Properties and their propagation

﻿Propagated to tests through arquillian.xml: +
`<property name="javaVmArguments">${server.jvm.args}</property>` +
TBD: https://issues.jboss.org/browse/ARQ-647

[[jboss-as-instance-dir]]
=== JBoss AS instance dir

*integration/pom.xml*

(currently nothing)

**-arquillian.xml*

[source, xml]
----
<container qualifier="jboss" default="true">
    <configuration>
        <property name="jbossHome">${basedir}/target/jbossas</property>
----

[[server-jvm-arguments]]
=== Server JVM arguments

[source, xml]
----
<surefire.memory.args>-Xmx512m -XX:MaxPermSize=256m</surefire.memory.args>
    <surefire.jpda.args></surefire.jpda.args>
    <surefire.system.args>${surefire.memory.args} ${surefire.jpda.args}</surefire.system.args>
----

[[ip-settings]]
=== IP settings

* `${ip.server.stack` *}* - used in
`<systemPropertyVariables> / <server.jvm.args>` which is used in
`*-arquillian.xml`.

[[testsuite-directories]]
=== Testsuite directories

* `${jbossas.ts.integ.dir`}
* `${jbossas.ts.dir`}
* `${jbossas.project.dir`}

[[clustering-properties]]
=== Clustering properties

* node0
* node1

== Debug parameters propagation

[source, xml]
----
<surefire.jpda.args></surefire.jpda.args>       - default

<surefire.jpda.args>-Xrunjdwp:transport=dt_socket,address=${as.debug.port},server=y,suspend=y</surefire.jpda.args> - activated by -Ddebug or -Djpda


testsuite/pom.xml:        <surefire.system.args>... ${surefire.jpda.args} ...</surefire.system.args>
testsuite/pom.xml:                        <jboss.options>${surefire.system.args}</jboss.options>

testsuite/integration/pom.xml:     <server.jvm.args>${surefire.system.args} ${jvm.args.ip.server} ${jvm.args.security} ${jvm.args.timeouts} -Dnode0=${node0} -Dnode1=


integration/pom.xml:
<server.jvm.args>${surefire.system.args} ${jvm.args.ip.server} ${jvm.args.security} ${jvm.args.timeouts} -Dnode0=${node0} -Dnode1=${node1} -DudpGroup=${udpGroup} ${jvm.args.dirs}</server.jvm.args>

arquillian.xml:
<property name="javaVmArguments">${server.jvm.args} -Djboss.inst=${basedir}/target/jbossas</property>
----

include::How_the_server_is_built_and_configured_for_testsuite_modules.adoc[]

include::Plugin_executions_matrix.adoc[]

include::Shortened_Maven_Run_Overview.adoc[]
<file_sep>/assets/javascript/random-color-picker.js
$(document).ready(function(){
    var listClasses = ["red", "orange", "yellow", "teal", "blue"];
    var blockClasses = ["red", "orange", "yellow", "teal"];

    // Random color class for blog feed on /blog 
    $(".blog-list-item").each(function(){
        $(this).addClass(listClasses[~~(Math.random()*listClasses.length)]);
    });

    // Random color class for blog feed in blocks format on homepage
    $(".blog-block-item").each(function(){
        $(this).addClass(blockClasses[~~(Math.random()*blockClasses.length)]);
    });
});
<file_sep>/_docs/14/_testsuite/WildFly_Testsuite_Overview.adoc
[[WildFly_Testsuite_Overview]]
= Wild**Fly** Testsuite Overview

This document will detail the implementation of the testsuite
Integration submodule as it guides you on adding your own test cases.

The Wild**Fly** integration test suite has been designed with the following
goals:

* support execution of all identified test case use cases
* employ a design/organization which is scalable and maintainable
* provide support for the automated measurement of test suite quality
(generation of feature coverage reports, code coverage reports)

In addition, these requirements were considered:

* identifying distinct test case runs of the same test case with a
different set of client side parameters and server side parameters
* separately maintaining server side execution results (e.g. logs, the
original server configuration) for post-execution debugging
* running the testsuite in conjunction with a debugger
* the execution of a single test (for debugging purposes)
* running test cases against different container modes (managed in the
main, but also remote and embedded)
* configuring client and server JVMs separately (e.g., IPv6 testing)

[[test-suite-organization]]
== Test Suite Organization

The testsuite module has a small number of submodules:

* *benchmark* - holds all benchmark tests intended to assess relative
performance of specific feature
* *domain* - holds all domain management tests
* *integration* - holds all integration tests
* *stress* - holds all stress tests

It is expected that test contributions fit into one of these categories.

The pom.xml file located in the testsuite module is inherited by all
submodules and is used to do the following:

* set defaults for common testsuite system properties (which can then be
overridden on the command line)
* define dependencies common to all tests (Arquillian, junit or testng,
and container type)
* provide a workaround for @Resource(lookup=...) which requires
libraries in jbossas/endorsed

It should not:

* define module-specific server configuration build steps
* define module-specific surefire executions

These elements should be defined in logical profiles associated with
each logical grouping of tests; e.g., in the pom for the module which
contains the tests. The submodule poms contain additional details of
their function and purpose as well as expanded information as shown in
this document.

[[profiles]]
== Profiles

You should not activate the abovementioned profiles by -P, because that
disables other profiles which are activated by default.

Instead, you should always use activating properties, which are in
parenthesis in the lists below.

*Testsuite profiles* are used to group tests into logical groups.

* all-modules.module.profile (all-modules)
* integration.module.profile (integration.module)
* compat.module.profile (compat.module)
* domain.module.profile (domain.module)
* benchmark.module.profile (benchmark.module)
* stress.module.profile (stress.module)

They also pprepare WildFly instances and resources for respective
testsuite submodules.

* jpda.profile - sets surefire.jpda.args (debug)
* ds.profile -sets database properties and prepares the datasource
(ds=<db id>)
** Has related database-specific profiles, like mysql51.profile etc.

*Integration testsuite profiles* configure surefire executions.

* smoke.integration.tests.profile
* basic.integration.tests.profile
* clustering.integration.tests.profile

== Integration tests

[[smoke--dts.smoke--dts.nosmoke]]
=== Smoke -Dts.smoke, -Dts.noSmoke

Contains smoke tests.

Runs by default; use -Dts.noSmoke to prevent running.

Tests should execute quickly.

Divided into two Surefire executions:

* One with full profile
* Second with web profile (majority of tests).

[[basic--dts.basic]]
=== Basic -Dts.basic

Basic integration tests - those which do not need special configuration
like cluster.

Divided into three Surefire executions:

* One with full profile,
* Second with web profile (majority of tests).
* Third with web profile, but needs to be run after server restart to
check whether persistent data are really persisted.

[[cluster--dts.clust]]
=== Cluster -Dts.clust

Sets up a cluster of two nodes.

[[iiop--dts.iiop]]
=== IIOP -Dts.iiop

[[xts--dts.xts]]
== XTS -Dts.XTS

[[multinode--dts.multinode]]
=== Multinode -Dts.multinode
<file_sep>/_docs/14/_admin-guide/Subsystem_configuration.adoc
[[Subsystem_configuration]]
= Subsystem configuration
Subsystem configuration reference
:author: <EMAIL>
:icons: font
:source-highlighter: coderay
:toc: macro
:toclevels: 2


The following chapters will focus on the high level management use cases
that are available through the CLI and the web interface. For a detailed
description of each subsystem configuration property, please consult the
respective component reference.

Schema Location

TIP: The configuration schemas can found in `$JBOSS_HOME/docs/schema`.

:leveloffset: +1

include::subsystem-configuration/EE.adoc[]

include::subsystem-configuration/Naming.adoc[]

include::subsystem-configuration/DataSource.adoc[]

include::subsystem-configuration/Datasources_Agroal.adoc[]

include::subsystem-configuration/Logging.adoc[]

include::subsystem-configuration/EJB3.adoc[]

include::subsystem-configuration/Undertow.adoc[]

include::subsystem-configuration/Messaging.adoc[]

include::subsystem-configuration/MicroProfile_Config_SmallRye.adoc[]

include::subsystem-configuration/MicroProfile_OpenTracing_SmallRye.adoc[]

include::subsystem-configuration/Security.adoc[]

include::subsystem-configuration/Web_services.adoc[]

include::subsystem-configuration/Resource_adapters.adoc[]

include::subsystem-configuration/Batch_(JSR-352).adoc[]

include::subsystem-configuration/JSF.adoc[]

include::subsystem-configuration/JMX.adoc[]

include::subsystem-configuration/Deployment_Scanner.adoc[]

include::subsystem-configuration/Core_Management.adoc[]

include::subsystem-configuration/Simple_configuration_subsystems.adoc[]

:leveloffset: -1
<file_sep>/_docs/13/_high-availability/ha-singleton/Singleton_MSC_services.adoc
[[Singleton_MSC_services]]
== Singleton MSC services

The singleton service facility exposes a mechanism for installing an MSC service such that the service only starts on a single member of a cluster at a time.
If the member providing the singleton service is shutdown or crashes, the facility automatically elects a new primary provider and starts the service on that node.
In general, a singleton election happens in response to any change of membership, where the membership is defined as the set of cluster nodes on which the given service was installed.

[[installing-an-msc-service-using-an-existing-singleton-policy]]
== Installing an MSC service using an existing singleton policy

While singleton MSC services have been around since AS7, WildFly adds the ability to leverage the singleton subsystem to create singleton MSC services from existing singleton policies.

The singleton subsystem exposes capabilities for each singleton policy it defines. 

These policies, encapsulated by the `org.wildfly.clustering.singleton.service.SingletonPolicy` interface, can be referenced via the following capability name:
"org.wildfly.clustering.singleton.policy" + _policy-name_

You can reference the default singleton policy of the server via the name:
"org.wildfly.clustering.singleton.default-policy"
e.g.

[source, java]
----
public class MyServiceActivator implements ServiceActivator {
    @Override
    public void activate(ServiceActivatorContext context) {
        ServiceName name = ServiceName.parse("my.service.name");
        // Use default singleton policy
        Supplier<SingletonPolicy> policy = new ActiveServiceSupplier<>(context.getServiceTarget(), ServiceName.parse(SingletonDefaultRequirement.SINGLETON_POLICY.getName()));
        ServiceBuilder<?> builder = policy.get().createSingletonServiceConfigurator(name).build(context.getServiceTarget());
        Service service = new MyService();
        builder.setInstance(service).install();
    }
}
----

[[installing-an-msc-service-using-dynamic-singleton-policy]]
== Installing an MSC service using dynamic singleton policy

Alternatively, you can configure a singleton policy dynamically, which is particularly useful if you want to use a custom singleton election policy.
`org.wildfly.clustering.singleton.service.SingletonPolicy` is a generalization of the `org.wildfly.clustering.singleton.service.SingletonServiceConfiguratorFactory` interface,
which includes support for specifying an election policy and, optionally, a quorum.

The 'SingletonServiceConfiguratorFactory' capability may be references using the following capability name:
"org.wildfly.clustering.cache.singleton-service-configurator-factory" + _container-name_ + "." + _cache-name_

You can reference a 'SingletonServiceConfiguratorFactory' using the default cache of a given cache container via the name:
"org.wildfly.clustering.cache.default-singleton-service-configurator-factory" + _container-name_

e.g.

[source, java]
----
public class MyServiceActivator implements ServiceActivator {
    @Override
    public void activate(ServiceActivatorContext context) {
        String containerName = "foo";
        ElectionPolicy policy = new MySingletonElectionPolicy();
        int quorum = 3;
        ServiceName name = ServiceName.parse("my.service.name");
        // Use a SingletonServiceConfiguratorFactory backed by default cache of "foo" container
        Supplier<SingletonServiceConfiguratorFactory> factory = new ActiveServiceSupplier<>(context.getServiceTarget(), ServiceName.parse(SingletonDefaultCacheRequirement.SINGLETON_SERVICE_CONFIGURATOR_FACTORY.resolve(containerName).getName()));
        ServiceBuilder<?> builder = factory.get().createSingletonServiceConfigurator(name)
                .electionPolicy(policy)
                .requireQuorum(quorum)
        		.build(context.getServiceTarget());
        Service service = new MyService();
        builder.setInstance(service).install();
    }
}
----
<file_sep>/_docs/13/Admin_Guide.adoc
[[Admin_Guide]]
= Wild**Fly** Admin Guide
Wild**Fly** developer team;
:revnumber: {version}
:revdate: {localdate}
:toc: macro
:toclevels: 2
:toc-title: WildFly Admin guide
:doctype: book
:icons: font
:source-highlighter: coderay
:wildflyVersion: 13
:sectlinks:
:idseparator: -
:include-depth: 2

ifdef::env-github[:outfilesuffix: .adoc]


ifndef::ebook-format[:leveloffset: 1]

(C) 2017 The original authors.

:numbered:


////
:leveloffset: 1
////



include::_admin-guide/Target_Audience.adoc[]

include::_admin-guide/Core_management_concepts.adoc[]

include::_admin-guide/Management_Clients.adoc[]

include::_admin-guide/Interfaces_and_ports.adoc[leveloffset=1]

= Administrative security

include::_admin-guide/Security_Realms.adoc[]

include::_admin-guide/RBAC.adoc[]

include::_admin-guide/Application_deployment.adoc[]

include::_admin-guide/Subsystem_configuration.adoc[]

include::_admin-guide/Domain_Setup.adoc[]

include::_admin-guide/Management_tasks.adoc[]

include::_admin-guide/Management_API_reference.adoc[]

include::_admin-guide/CLI_Recipes.adoc[]

<file_sep>/_docs/13/_testsuite/Shared_Test_Classes_and_Resources.adoc
[[Shared_Test_Classes_and_Resources]]
== Shared Test Classes and Resources

[[among-testsuite-modules]]
== Among Testsuite Modules

Use the testsuite/shared module.

Classes and resources in this module are available in all testsuite
modules - i.e. in testsuite/* .

Only use it if necessary - don't put things "for future use" in there.

*Don't split packages across modules.* *Make sure the java package is
unique in the WildFly project.*

*Document your util classes* (javadoc) so they can be easily found and
reused! A generated list will be put here.

[[between-components-and-testsuite-modules]]
== Between Components and Testsuite Modules

To share component's test classes with some module in testsuite, you
don't need to split to submodules. 
You can create a jar with classifier using this:

[source, xml]
----
<plugin> 
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>test-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>
----

This creates a jar with classifier "tests", so you can add it as
dependency to a testsuite module:

[source, xml]
----
    <dependency>
        <groupId>org.wildfly</groupId>
        <artifactId>wildfly-clustering-common</artifactId>
        <classifier>tests</classifier>
        <version>${project.version}</version>
        <scope>test</scope>
    </dependency>
----<file_sep>/_docs/14/_extending-wildfly/WildFly_JNDI_Implementation.adoc
[[WildFly_JNDI_Implementation]]
= Wild**Fly** JNDI Implementation

[[introduction]]
== Introduction

This page proposes a reworked WildFly JNDI implementation, and
new/updated APIs for WildFly subsystem and EE deployment processors
developers to bind new resources easier.

To support discussion in the community, the content includes a big focus
on comparing WildFly {wildflyVersion} JNDI implementation with the new proposal, and
should later evolve to the prime guide for WildFly developers needing to
interact with JNDI at subsystem level.

[[architecture]]
== Architecture

WildFly relies on MSC to provide the data source for the JNDI tree. Each
resource bound in JNDI is stored in a MSC service (BinderService), and
such services are installed as children of subsystem/deployment
services, for an automatically unbound as consequence of uninstall of
the parent services.

Since there is the need to know what entries are bound, and MSC does not
provides that, there is also the (ServiceBased)NamingStore concept,
which internally manage the set of service names bound. There are
multiple naming stores in every WildFly instance, serving different JNDI
namespaces:

* java:comp - the standard EE namespace for entries scoped to a specific
component, such as an EJB
* java:module - the standard EE namespace for entries scoped to specific
module, such as an EJB jar, and shared by all components in it
* java:app - the standard EE namespace for entries scoped to a specific
application, i.e. EAR, and shared by all modules in it
* java:global - the standard EE namespace for entries shared by all
deployments
* java:jboss - a proprietary namespace "global" namespace
* java:jboss/exported - a proprietary "global" namespace which entries
are exposed to remote JNDI
* java: - any entries not in the other namespaces

One particular implementation choice, to save resources, is that JNDI
contexts by default are not bound, the naming stores will search for any
entry bound with a name that is a child of the context name, if found
then its assumed the context exists.

The reworked implementation introduces shared/global java:comp,
java:module and java:app namespaces. Any entry bound on these will
automatically be available to every EE deployment scoped instance of
these namespaces, what should result in a significant reduction of
binder services, and also of EE deployment processors. Also, the Naming
subsystem may now configure bind on these shared contexts, and these
contexts will be available when there is no EE component in the
invocation, which means that entries such as java:comp/DefaultDatasource
will always be available.

[[binding-apis]]
== Binding APIs

WildFly Naming subsystem exposes high level APIs to bind new JNDI
resources, there is no need to deal with the low level BinderService
type anymore.

[[subsystem]]
=== Subsystem

At the lowest level a JNDI entry is bound by installing a BinderService
to a ServiceTarget:

[source, java]
----
 
   /**
     * Binds a new entry to JNDI.
     * @param serviceTarget the binder service's target
     * @param name the new JNDI entry's name
     * @param value the new JNDI entry's value
     */
    private ServiceController<?> bind(ServiceTarget serviceTarget, String name, Object value) {
        
 // the bind info object provides MSC service names to use when creating the binder service
        final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(name);
        final BinderService binderService = new BinderService(bindInfo.getBindName());
        
 // the entry's value is provided by a managed reference factory,
        // since the value may need to be obtained on lookup (e.g. EJB reference)
        final ManagedReferenceFactory managedReferenceFactory = new ImmediateManagedReferenceFactory(value);
        
 return serviceTarget
                // add binder service to specified target
                .addService(bindInfo.getBinderServiceName(), binderService)
                // when started the service will be injected with the factory
                .addInjection(binderService.getManagedObjectInjector(), managedReferenceFactory)
                // the binder service depends on the related naming store service,
                // and on start/stop will add/remove its service name
                .addDependency(bindInfo.getParentContextServiceName(),
                        ServiceBasedNamingStore.class,
                        binderService.getNamingStoreInjector())
                .install();
    }
----

But the example above is the simplest usage possible, it may become
quite complicated if the entry's value is not immediately available, for
instance it is a value in another MSC service, or is a value in another
JNDI entry. It's also quite easy to introduce bugs when working with the
service names, or incorrectly assume that other MSC functionality, such
as alias names, may be used.

Using the new high level API, it's as simple as:

[source, java]
----
// bind an immediate value
ContextNames.bindInfoFor("java:comp/ORB").bind(serviceTarget, this.orb);
 
 
// bind value from another JNDI entry (an alias/linkref)
ContextNames.bindInfoFor("java:global/x").bind(serviceTarget, new JndiName("java:jboss/x"));
 
 
// bind value obtained from a MSC service
ContextNames.bindInfoFor("java:global/z").bind(serviceTarget, serviceName);
----

If there is the need to access the binder's service builder, perhaps to
add a service verification handler or simply not install the binder
service right away:

[source, java]
----
ContextNames.bindInfoFor("java:comp/ORB").builder(serviceTarget, verificationHandler, ServiceController.Mode.ON_DEMAND).installService(this.orb);
----

[[ee-deployment]]
=== EE Deployment

With respect to EE deployments, the subsystem API should not be used,
since bindings may need to be discarded/overridden, thus a EE deployment
processor should add a new binding in the form of a
BindingConfiguration, to the EeModuleDescription or
ComponentDescription, depending if the bind is specific to a component
or not. An example of a deployment processor adding a binding:

[source, java]
----
public class ModuleNameBindingProcessor implements DeploymentUnitProcessor {
 
    // jndi name objects are immutable
    private static final JndiName JNDI_NAME_java_module_ModuleName = new JndiName("java:module/ModuleName");
 
    @Override
    public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
        
 final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
        // skip deployment unit if it's the top level EAR
        if (DeploymentTypeMarker.isType(DeploymentType.EAR, deploymentUnit)) {
            return;
        }
        
 // the module's description is in the DUs attachments
        final EEModuleDescription moduleDescription = deploymentUnit
                .getAttachment(org.jboss.as.ee.component.Attachments.EE_MODULE_DESCRIPTION);
        if (moduleDescription == null) {
            return;
        }
        
 // add the java:module/ModuleName binding
        // the value's injection source for an immediate available value
        final InjectionSource injectionSource = new ImmediateInjectionSource(moduleDescription.getModuleName());
        
 // add the binding configuration to the module's description bindings configurations
        moduleDescription.getBindingConfigurations()
                .addDeploymentBinding(new BindingConfiguration(JNDI_NAME_java_module_ModuleName, injectionSource));
    }
 
    //...
}
----

[IMPORTANT]

When adding the binding configuration use:

* addDeploymentBinding() for a binding that may not be overriden, such
as the ones found in xml descriptors
* addPlatformBinding() for a binding which may be overriden by a
deployment descriptor bind or annotation, for instance
java:comp/DefaultDatasource

A deployment processor may now also add a binding configuration to all
components in a module:

[source, java]
----
     
moduleDescription.getBindingConfigurations().addPlatformBindingToAllComponents(bindingConfiguration);
----

[IMPORTANT]

In the reworked implementation there is now no need to behave
differently considering the deployment type, for instance if deployment
is a WAR or app client, the Module/Component BindingConfigurations
objects handle all of that. The processor should simply go for the 3 use
cases: module binding, component binding or binding shared by all
components.

[IMPORTANT]

All deployment binding configurations MUST be added before INSTALL
phase, this is needed because on such phase, when the bindings are
actually done, there must be a final set of deployment binding names
known, such information is need to understand if a resource injection
targets entries in the global or scoped EE namespaces.

Most cases for adding bindings to EE deployments are in the context of a
processor deploying a XML descriptor, or scanning deployment classes for
annotations, and there abstract types, such as the
AbstractDeploymentDescriptorBindingsProcessor, which simplifies greatly
the processor code for such use cases.

One particular use case is the parsing of EE Resource Definitions, and
the reworked implementation provides high level abstract deployment
processors for both XML descriptor and annotations, an example for each:

[source, java]
----
/**
 * Deployment processor responsible for processing administered-object deployment descriptor elements
 *
 * @author <NAME>
 */
public class AdministeredObjectDefinitionDescriptorProcessor extends ResourceDefinitionDescriptorProcessor {
 
    @Override
    protected void processEnvironment(RemoteEnvironment environment, ResourceDefinitionInjectionSources injectionSources) throws DeploymentUnitProcessingException {
        final AdministeredObjectsMetaData metaDatas = environment.getAdministeredObjects();
        if (metaDatas != null) {
            for(AdministeredObjectMetaData metaData : metaDatas) {
                injectionSources.addResourceDefinitionInjectionSource(getResourceDefinitionInjectionSource(metaData));
            }
        }
    }
 
    private ResourceDefinitionInjectionSource getResourceDefinitionInjectionSource(final AdministeredObjectMetaData metaData) {
        final String name = metaData.getName();
        final String className = metaData.getClassName();
        final String resourceAdapter = metaData.getResourceAdapter();
        final AdministeredObjectDefinitionInjectionSource resourceDefinitionInjectionSource = new AdministeredObjectDefinitionInjectionSource(name, className, resourceAdapter);
        resourceDefinitionInjectionSource.setInterface(metaData.getInterfaceName());
        if (metaData.getDescriptions() != null) {
            resourceDefinitionInjectionSource.setDescription(metaData.getDescriptions().toString());
        }
        resourceDefinitionInjectionSource.addProperties(metaData.getProperties());
        return resourceDefinitionInjectionSource;
    }
 
}
----

and

[source, java]
----
/**
 * Deployment processor responsible for processing {@link javax.resource.AdministeredObjectDefinition} and {@link javax.resource.AdministeredObjectDefinitions}.
 *
 * @author <NAME>
 * @author <NAME>
 */
public class AdministeredObjectDefinitionAnnotationProcessor extends ResourceDefinitionAnnotationProcessor {
 
    private static final DotName ANNOTATION_NAME = DotName.createSimple(AdministeredObjectDefinition.class.getName());
    private static final DotName COLLECTION_ANNOTATION_NAME = DotName.createSimple(AdministeredObjectDefinitions.class.getName());
 
    @Override
    protected DotName getAnnotationDotName() {
        return ANNOTATION_NAME;
    }
 
    @Override
    protected DotName getAnnotationCollectionDotName() {
        return COLLECTION_ANNOTATION_NAME;
    }
 
    @Override
    protected ResourceDefinitionInjectionSource processAnnotation(AnnotationInstance annotationInstance) throws DeploymentUnitProcessingException {
        final String name = AnnotationElement.asRequiredString(annotationInstance, AnnotationElement.NAME);
        final String className = AnnotationElement.asRequiredString(annotationInstance, "className");
        final String ra = AnnotationElement.asRequiredString(annotationInstance, "resourceAdapter");
        final AdministeredObjectDefinitionInjectionSource directAdministeredObjectInjectionSource =
                new AdministeredObjectDefinitionInjectionSource(name, className, ra);
        directAdministeredObjectInjectionSource.setDescription(AnnotationElement.asOptionalString(annotationInstance,
                AdministeredObjectDefinitionInjectionSource.DESCRIPTION));
        directAdministeredObjectInjectionSource.setInterface(AnnotationElement.asOptionalString(annotationInstance,
                AdministeredObjectDefinitionInjectionSource.INTERFACE));
        directAdministeredObjectInjectionSource.addProperties(AnnotationElement.asOptionalStringArray(annotationInstance,
                AdministeredObjectDefinitionInjectionSource.PROPERTIES));
        return directAdministeredObjectInjectionSource;
    }
 
}
----

[IMPORTANT]

The abstract processors with respect to Resource Definitions are already
submitted through WFLY-3292's PR.

[[resource-ref-processing]]
== Resource Ref Processing

TODO for now no changes on this in the reworked WildFly Naming.
<file_sep>/_docs/14/_extending-wildfly/Key_Interfaces_and_Classes_Relevant_to_Extension_Developers.adoc
[[Key_Interfaces_and_Classes_Relevant_to_Extension_Developers]]
= Key Interfaces and Classes Relevant to Extension Developers

In the first major section of this guide, we provided an example of how
to implement an extension to the AS. The emphasis there was learning by
doing. In this section, we'll focus a bit more on the major WildFly
interfaces and classes that most are relevant to extension developers.
The best way to learn about these interfaces and classes in detail is to
look at their javadoc. What we'll try to do here is provide a brief
introduction of the key items and how they relate to each other.

Before digging into this section, readers are encouraged to read the
"Core Management Concepts" section of the Admin Guide.

[[extension-interface]]
== Extension Interface

The `org.jboss.as.controller.Extension` interface is the hook by which
your extension to the AS kernel is able to integrate with the AS. During
boot of the AS, when the `<extension>` element in the AS's xml
configuration file naming your extension is parsed, the JBoss Modules
module named in the element's name attribute is loaded. The standard JDK
`java.lang.ServiceLoader` mechanism is then used to load your module's
implementation of this interface.

The function of an `Extension` implementation is to register with the
core AS the management API, xml parsers and xml marshallers associated
with the extension module's subsystems. An `Extension` can register
multiple subsystems, although the usual practice is to register just one
per extension.

Once the `Extension` is loaded, the core AS will make two invocations
upon it:

* `void initializeParsers(ExtensionParsingContext context)`

When this is invoked, it is the `Extension` implementation's
responsibility to initialize the XML parsers for this extension's
subsystems and register them with the given `ExtensionParsingContext`.
The parser's job when it is later called is to create
`org.jboss.dmr.ModelNode` objects representing WildFly management API
operations needed make the AS's running configuration match what is
described in the xml. Those management operation `ModelNode` s are added
to a list passed in to the parser.

A parser for each version of the xml schema used by a subsystem should
be registered. A well behaved subsystem should be able to parse any
version of its schema that it has ever published in a final release.

* `void initialize(ExtensionContext context)`

When this is invoked, it is the `Extension` implementation's
responsibility to register with the core AS the management API for its
subsystems, and to register the object that is capable of marshalling
the subsystem's in-memory configuration back to XML. Only one XML
marshaller is registered per subsystem, even though multiple XML parsers
can be registered. The subsystem should always write documents that
conform to the latest version of its XML schema.

The registration of a subsystem's management API is done via the
`ManagementResourceRegistration` interface. Before discussing that
interface in detail, let's describe how it (and the related `Resource`
interface) relate to the notion of managed resources in the AS.

[[wildfly-managed-resources]]
== Wild**Fly** Managed Resources

Each subsystem is responsible for managing one or more management
resources. The conceptual characteristics of a management resource are
covered in some detail in the link:Admin_Guide{outfilesuffix}#Management_resources[Admin
Guide]; here we'll just summarize the main points. A management resource
has

* An *_address_* consisting of a list of key/value pairs that uniquely
identifies a resource
* Zero or more *_attributes_* , the value of which is some sort of
`org.jboss.dmr.ModelNode`
* Zero or more supported *_operations_* . An operation has a string name
and zero or more parameters, each of which is a key/value pair where the
key is a string naming the parameter and the value is some sort of
`ModelNode`
* Zero or more *_children_* , each of which in turn is a managed
resource

The implementation of a managed resource is somewhat analogous to the
implementation of a Java object. A managed resource will have a "type",
which encapsulates API information about that resource and logic used to
implement that API. And then there are actual instances of the resource,
which primarily store data representing the current state of a
particular resource. This is somewhat analogous to the "class" and
"object" notions in Java.

A managed resource's type is encapsulated by the
`org.jboss.as.controller.registry.ManagementResourceRegistration` the
core AS creates when the type is registered. The data for a particular
instance is encapsulated in an implementation of the
`org.jboss.as.controller.registry.Resource` interface.

[[managementresourceregistration-interface]]
== ManagementResourceRegistration Interface

In the Java analogy used above, the `ManagementResourceRegistration` is
analogous to the "class", while the `Resource` discussed below is
analogous to an instance of that class.

A `ManagementResourceRegistration` represents the specification for a
particular managed resource type. All resources whose address matches
the same pattern will be of the same type, specified by the type's
`ManagementResourceRegistration`. The MRR encapsulates:

* A `PathAddress` showing the address pattern that matches resources of
that type. This `PathAddress` can and typically does involve wildcards
in the value of one or more elements of the address. In this case there
can be more than one instance of the type, i.e. different `Resource`
instances.
* Definition of the various attributes exposed by resources of this
type, including the `OperationStepHandler` implementations used for
reading and writing the attribute values.
* Definition of the various operations exposed by resources of this
type, including the `OperationStepHandler` implementations used for
handling user invocations of those operations.
* Definition of child resource types. `ManagementResourceRegistration`
instances form a tree.
* Definition of management notifications emitted by resources of this
type.
* Definition of
<<Working_with_WildFly_Capabilities,capabilities>> provided by
resources of this type.
* Definition of link:Admin_Guide{outfilesuffix}#RBAC[RBAC] access constraints that should be
applied by the management kernel when authorizing operations against
resources of this type.
* Whether the resource type is an alias to another resource type, and if
so information about that relationship. Aliases are primarily used to
preserve backwards compatibility of the management API when the location
of a given type of resources is moved in a newer release.

The `ManagementResourceRegistration` interface is a subinterface of
`ImmutableManagementResourceRegistration`, which provides a read-only
view of the information encapsulated by the MRR. The MRR subinterface
adds the methods needed for registering the attributes, operations,
children, etc.

Extension developers do not directly instantiate an MRR. Instead they
create a `ResourceDefinition` for the root resource type for each
subsystem, and register it with the `ExtensionContext` passed in to
their `Extension` implementation's `initialize` method:

[source, java]
----
    public void initialize(ExtensionContext context) {
        SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, CURRENT_VERSION);
        subsystem.registerXMLElementWriter(getOurXmlWriter());
        ResourceDefinition rd = getOurSubsystemDefinition();
        ManagementResourceRegistration mrr = subsystem.registerSubsystemModel(rd));
    }
----

The kernel uses the provided `ResourceDefinition` to construct a
`ManagementResourceRegistration` and then passes that MRR to the various
`registerXXX` methods implemented by the `ResourceDefinition`, giving it
the change to record the resource type's attributes, operations and
children.

[[resourcedefinition-interface]]
== ResourceDefinition Interface

An implementation of `ResourceDefinition` is the primary class used by
an extension developer when defining a managed resource type. It
provides basic information about the type, exposes a
`DescriptionProvider` used to generate a DMR description of the type,
and implements callbacks the kernel can invoke when building up the
`ManagementResourceRegistration` to ask for registration of definitions
of attributes, operations, children, notifications and capabilities.

Almost always an extension author will create their `ResourceDefinition`
by creating a subclass of the
`org.jboss.as.controller.SimpleResourceDefinition` class or of its
`PersistentResourceDefinition` subclass. Both of these classes have
constructors that take a `Parameters` object, which is a simple builder
class to use to provide most of the key information about the resource
type. The extension-specific subclass would then take responsibility for
any additional behavior needed by overriding the `registerAttributes`,
`registerOperations`, `registerNotifications` and `registerChildren`
callbacks to do whatever is needed beyond what is provided by the
superclasses.

For example, to add a writable attribute:

[source, java]
----
    @Override
    public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
        super.registerAttributes(resourceRegistration);
        // Now we register the 'foo' attribute
        AttributeDefinition ad = FOO; // constant declared elsewhere
        OperationStepHandler writeHandler = new FooWriteAttributeHandler();
        resourceRegistration.registerReadWriteHandler(ad, null, writeHandler); // null read handler means use default read handling
    }
----

To register a custom operation:

[source, java]
----
    @Override
    public void registerOperations(ManagementResourceRegistration resourceRegistration) {
        super.registerOperations(resourceRegistration);
        // Now we register the 'foo-bar' custom operation
        OperationDefinition od = FooBarOperationStepHandler.getDefinition();
        OperationStepHandler osh = new FooBarOperationStepHandler();
        resourceRegistration.registerOperationHandler(od, osh);
    }
----

To register a child resource type:

[source, java]
----
    @Override
    public void registerChildren(ManagementResourceRegistration resourceRegistration) {
        super.registerChildren(resourceRegistration);
        // Now we register the 'baz=*' child type
        ResourceDefinition rd = new BazResourceDefinition();
        resourceRegistration.registerSubmodel(rd);
    }
----

[[resourcedescriptionresolver]]
=== ResourceDescriptionResolver

One of the things a `ResourceDefinition` must be able to do is provide a
`DescriptionProvider` that provides a proper DMR description of the
resource to use as the output for the standard
`read-resource-description` management operation. Since you are almost
certainly going to be using one of the standard `ResourceDefinition`
implementations like `SimpleResourceDefinition`, the creation of this
`DescriptionProvider` is largely handled for you. The one thing that is
not handled for you is providing the localized free form text
descriptions of the various attributes, operations, operation
parameters, child types, etc used in creating the resource description.

For this you must provide an implementation of the
`ResourceDescriptionResolver` interface, typically passed to the
`Parameters` object provided to the `SimpleResourceDefinition`
constructor. This interface has various methods that are invoked when a
piece of localized text description is needed.

Almost certainly you'll satisfy this requirement by providing an
instance of the `StandardResourceDescriptionResolver` class.

`StandardResourceDescriptionResolver` uses a `ResourceBundle` to load
text from a properties file available on the classpath. The keys in the
properties file must follow patterns expected by
`StandardResourceDescriptionResolver`. See the
`StandardResourceDescriptionResolver` javadoc for further details.

The biggest task here is to create the properties file and add the text
descriptions. A text description must be provided for everything. The
typical thing to do is to store this properties file in the same package
as your `Extension` implementation, in a file named
`LocalDescriptions.properties`.

[[attributedefinition-class]]
== AttributeDefinition Class

The `AttributeDefinition` class is used to create the static definition
of one of a managed resource's attributes. It's a bit poorly named
though, because the same interface is used to define the details of
parameters to operations, and to define fields in the result of of
operations.

The definition includes all the static information about the
attribute/operation parameter/result field, e.g. the DMR `ModelType` of
its value, whether its presence is required, whether it supports
expressions, etc. See
link:Admin_Guide{outfilesuffix}#Description_of_the_Management_Model[Description of the
Management Model] for a description of the metadata available. Almost
all of this comes from the `AttributeDefinition`.

Besides basic metadata, the `AttributeDefinition` can also hold custom
logic the kernel should use when dealing with the attribute/operation
parameter/result field. For example, a `ParameterValidator` to use to
perform special validation of values (beyond basic things like DMR type
checks and defined/undefined checks), or an `AttributeParser` or
`AttributeMarshaller` to use to perform customized parsing from and
marshaling to XML.

WildFly Core's `controller` module provides a number of subclasses of
`AttributeDefinition` used for the usual kinds of attributes. For each
there is an associated builder class which you should use to build the
`AttributeDefinition`. Most commonly used are
`SimpleAttributeDefinition`, built by the associated
`SimpleAttributeDefinitionBuilder`. This is used for attributes whose
values are analogous to java primitives, `String` or byte[]. For
collections, there are various subclasses of `ListAttributeDefinition`
and `MapAttributeDefinition`. All have a `Builder` inner class. For
complex attributes, i.e. those with a fixed set of fully defined fields,
use `ObjectTypeAttributeDefinition`. (Each field in the complex type is
itself specified by an `AttributeDefinition`.) Finally there's
`ObjectListAttributeDefinition` and `ObjectMapAttributeDefinition` for
lists whose elements are complex types and maps whose values are complex
types respectively.

Here's an example of creating a simple attribute definition with extra
validation of the range of allowed values:

[source, java]
----
static final AttributeDefinition QUEUE_LENGTH = new SimpleAttributeDefinitionBuilder("queue-length", ModelType.INT)
                .setRequired(true)
                .setAllowExpression(true)
                .setValidator(new IntRangeValidator(1, Integer.MAX_VALUE))
                .setRestartAllServices() // means modification after resource add puts the server in reload-required
                .build();
----

Via a bit of dark magic, the kernel knows that the `IntRangeValidator`
defined here is a reliable source of information on min and max values
for the attribute, so when creating the `read-resource-description`
output for the attribute it will use it and output `min` and `max`
metadata. For STRING attributes, `StringLengthValidator` can also be
used, and the kernel will see this and provide `min-length` and
`max-length` metadata. In both cases the kernel is checking for the
presence of a `MinMaxValidator` and if found it provides the appropriate
metadata based on the type of the attribute.

Use `EnumValidator` to restrict a STRING attribute's values to a set of
legal values:

[source, java]
----
    static final SimpleAttributeDefinition TIME_UNIT = new SimpleAttributeDefinitionBuilder("unit", ModelType.STRING)
            .setRequired(true)
            .setAllowExpression(true)
            .setValidator(new EnumValidator<TimeUnit>(TimeUnit.class))
            .build();
----

`EnumValidator` is an implementation of `AllowedValuesValidator` that
works with Java enums. You can use other implementations or write your
own to do other types of restriction to certain values.

Via a bit of dark magic similar to what is done with `MinMaxValidator`,
the kernel recognizes the presence of an `AllowedValuesValidator` and
uses it to seed the `allowed-values` metadata in
`read-resource-description` output.

[[key-uses-of-attributedefinition]]
=== Key Uses of AttributeDefinition

Your `AttributeDefinition` instances will be some of the most commonly
used objects in your extension code. Following are the most typical
uses. In each of these examples assume there is a
`SimpleAttributeDefinition` stored in a constant FOO_AD that is
available to the code. Typically FOO_AD would be a constant in the
relevant `ResourceDefinition` implementation class. Assume FOO_AD
represents an INT attribute.

Note that for all of these cases except for "Use in Extracting Data from
the Configuration Model for Use in Runtime Services" there may be
utility code that handles this for you. For example
`PersistentResourceXMLParser` can handle the XML cases, and
`AbstractAddStepHandler` can handle the "Use in Storing Data Provided by
the User to the Configuration Model" case.

[[use-in-xml-parsing]]
==== Use in XML Parsing

Here we have your extension's implementation of
`XMLElementReader<List<ModelNode>>` that is being used to parse the xml
for your subsystem and add `ModelNode` operations to the list that will
be used to boot the server.

[source, java]
----
    @Override
    public void readElement(final XMLExtendedStreamReader reader, final List<ModelNode> operationList) throws XMLStreamException {
        // Create a node for the op to add our subsystem
        ModelNode addOp = new ModelNode();
        addOp.get("address").add("subsystem", "mysubsystem");
        addOp.get("operation").set("add");
        operationList.add(addOp);
 
        for (int i = 0; i < reader.getAttributeCount(); i++) {
            final String value = reader.getAttributeValue(i);
            final String attribute = reader.getAttributeLocalName(i);
            if (FOO_AD.getXmlName().equals(attribute) {
                FOO_AD.parseAndSetParameter(value, addOp, reader);
            } else ....
        }
 
        ... more parsing
    }
----

Note that the parsing code has deliberately been abbreviated. The key
point is the `parseAndSetParameter` call. FOO_AD will validate the
`value` read from XML, throwing an XMLStreamException with a useful
message if invalid, including a reference to the current location of the
`reader`. If valid, `value` will be converted to a DMR `ModelNode` of
the appropriate type and stored as a parameter field of `addOp`. The
name of the parameter will be what `FOO_AD.getName()` returns.

If you use `PersistentResourceXMLParser` this parsing logic is handled
for you and you don't need to write it yourself.

[[use-in-storing-data-provided-by-the-user-to-the-configuration-model]]
==== Use in Storing Data Provided by the User to the Configuration Model

Here we illustrate code in an `OperationStepHandler` that extracts a
value from a user-provided `operation` and stores it in the internal
model:

[source, java]
----
    @Override
    public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
        // Get the Resource targeted by this operation
        Resource resource = context.readResourceForUpdate(PathAddress.EMPTY_ADDRESS);
        ModelNode model = resource.getModel();
        // Store the value of any 'foo' param to the model's 'foo' attribute
        FOO_AD.validateAndSet(operation, model);
 
        ... do other stuff
    }
----

As the name implies `validateAndSet` will validate the value in
`operation` before setting it. A validation failure will result in an
`OperationFailedException` with an appropriate message, which the kernel
will use to provide a failure response to the user.

Note that `validateAndSet` will not perform expression resolution.
Expression resolution is not appropriate at this stage, when we are just
trying to store data to the persistent configuration model. However, it
will check for expressions and fail validation if found and FOO_AD
wasn't built with `setAllowExpressions(true)`.

This work of storing data to the configuration model is usually done in
handlers for the `add` and `write-attribute` operations. If you base
your handler implementations on the standard classes provided by WildFly
Core, this part of the work will be handled for you.

[[use-in-extracting-data-from-the-configuration-model-for-use-in-runtime-services]]
==== Use in Extracting Data from the Configuration Model for Use in
Runtime Services

This is the example you are most likely to use in your code, as this is
where data needs to be extracted from the configuration model and passed
to your runtime services. What your services need is custom, so there's
no utility code we provide.

Assume as part of `... do other stuff` in the last example that your
handler adds a step to do further work once operation execution proceeds
to RUNTIME state (see Operation Execution and the `OperationContext` for
more on what this means):

[source, java]
----
        context.addStep(new OperationStepHandler() {
            @Override
            public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
 
                // Get the Resource targetted by this operation
                Resource resource = context.readResource(PathAddress.EMPTY_ADDRESS);
                ModelNode model = resource.getModel();
                // Extract the value of the 'foo' attribute from the model
                int foo = FOO_AD.resolveModelAttribute(context, model).asInt();
               
                Service<XyZ> service = new MyService(foo);
 
                ... do other stuff, like install 'service' with MSC
    }
        }, Stage.RUNTIME);
----

Use `resolveModelAttribute` to extract data from the model. It does a
number of things:

* reads the value from the model
* if it's an expression and expressions are supported, resolves it
* if it's undefined and undefined is allowed but FOO_AD was configured
with a default value, uses the default value
* validates the result of that (which is how we check that expressions
resolve to legal values), throwing OperationFailedException with a
useful message if invalid
* returns that as a `ModelNode`

If when you built FOO_AD you configured it such that the user must
provide a value, or if you configured it with a default value, then you
know the return value of `resolveModelAttribute` will be a defined
`ModelNode`. Hence you can safely perform type conversions with it, as
we do in the example above with the call to `asInt()`. If FOO_AD was
configured such that it's possible that the attribute won't have a
defined value, you need to guard against that, e.g.:

[source, java]
----
    ModelNode node = FOO_AD.resolveModelAttribute(context, model);
    Integer foo = node.isDefined() ? node.asInt() : null;
----

[[use-in-marshaling-configuration-model-data-to-xml]]
==== Use in Marshaling Configuration Model Data to XML

Your `Extension` must register an
`XMLElementWriter<SubsystemMarshallingContext>` for each subsystem. This
is used to marshal the subsystem's configuration to XML. If you don't
use `PersistentResourceXMLParser` for this you'll need to write your own
marshaling code, and `AttributeDefinition` will be used.

[source, java]
----
    @Override
    public void writeContent(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
        context.startSubsystemElement(Namespace.CURRENT.getUriString(), false);
 
        ModelNode subsystemModel = context.getModelNode();
        // we persist foo as an xml attribute
        FOO_AD.marshalAsAttribute(subsystemModel, writer);
        // We also have a different attribute that we marshal as an element
        BAR_AD.marshalAsElement(subsystemModel, writer);
    }
----

The `SubsystemMarshallingContext` provides a `ModelNode` that represents
the entire resource tree for the subsystem (including child resources).
Your `XMLElementWriter` should walk through that model, using
`marshalAsAttribute` or `marshalAsElement` to write the attributes in
each resource. If the model includes child node trees that represent
child resources, create child xml elements for those and continue down
the tree.

[[operationdefinition-and-operationstephandler-interfaces]]
== OperationDefinition and OperationStepHandler Interfaces

`OperationDefinition` defines an operation, particularly its name, its
parameters and the details of any result value, with
`AttributeDefinition` instances used to define the parameters and result
details. The `OperationDefinition` is used to generate the
`read-operation-description` output for the operation, and in some cases
is also used by the kernel to decide details as to how to execute the
operation.

Typically `SimpleOperationDefinitionBuilder` is used to create an
`OperationDefinition`. Usually you only need to create an
`OperationDefinition` for custom operations. For the common `add` and
`remove` operations, if you provide minimal information about your
handlers to your `SimpleResourceDefinition` implementation via the
`Parameters` object passed to its constructor, then
`SimpleResourceDefinition` can generate a correct `OperationDefinition`
for those operations.

The `OperationStepHandler` is what contains the actual logic for doing
what the user requests when they invoke an operation. As its name
implies, each OSH is responsible for doing one step in the overall
sequence of things necessary to give effect to what the user requested.
One of the things an OSH can do is add other steps, with the result that
an overall operation can involve a great number of OSHs executing. (See
Operation Execution and the `OperationContext` for more on this.)

Each OSH is provided in its `execute` method with a reference to the
`OperationContext` that is controlling the overall operation, plus an
`operation` `ModelNode` that represents the operation that particular
OSH is being asked to deal with. The `operation` node will be of
`ModelType.OBJECT` with the following key/value pairs:

* a key named `operation` with a value of `ModelType.STRING` that
represents the name of the operation. Typically an OSH doesn't care
about this information as it is written for an operation with a
particular name and will only be invoked for that operation.
* a key named `address` with a value of `ModelType.LIST` with list
elements of `ModelType.PROPERTY`. This value represents the address of
the resource the operation targets. If this key is not present or the
value is undefined or an empty list, the target is the root resource.
Typically an OSH doesn't care about this information as it can more
efficiently get the address from the `OperationContext` via its
`getCurrentAddress()` method.
* other key/value pairs that represent parameters to the operation, with
the key the name of the parameter. This is the main information an OSH
would want from the `operation` node.

There are a variety of situations where extension code will instantiate
an `OperationStepHandler`

* When registering a writable attribute with a
`ManagementResourceRegistration` (typically in an implementation of
`ResourceDefinition.registerAttributes`), an OSH must be provided to
handle the `write-attribute` operation.
* When registering a read-only or read-write attribute that needs
special handling of the `read-attribute` operation, an OSH must be
provided.
* When registering a metric attribute, an OSH must be provided to handle
the `read-attribute` operation.
* Most resources need OSHs created for the `add` and `remove`
operations. These are passed to the `Parameters` object given to the
`SimpleResourceDefinition` constructor, for use by the
`SimpleResourceDefinition` in its implementation of the
`registerOperations` method.
* If your resource has custom operations, you will instantiate them to
register with a `ManagementResourceRegistration`, typically in an
implementation of `ResourceDefinition.registerOperations`
* If an OSH needs to tell the `OperationContext` to add additional steps
to do further handling, the OSH will create another OSH to execute that
step. This second OSH is typically an inner class of the first OSH.

[[operation-execution-and-the-operationcontext]]
== Operation Execution and the OperationContext

When the `ModelController` at the heart of the WildFly Core management
layer handles a request to execute an operation, it instantiates an
implementation of the `OperationContext` interface to do the work. The
`OperationContext` is configured with an initial list of operation steps
it must execute. This is done in one of two ways:

* During boot, multiple steps are configured, one for each operation in
the list generated by the parser of the xml configuration file. For each
operation, the `ModelController` finds the
`ManagementResourceRegistration` that matches the address of the
operation and finds the `OperationStepHandler` registered with that MRR
for the operation's name. A step is added to the `OperationContext` for
each operation by providing the operation `ModelNode` itself, plus the
`OperationStepHandler`.
* After boot, any management request involves only a single operation,
so only a single step is added. (Note that a `composite` operation is
still a single operation; it's just one that internally executes via
multiple steps.)

The `ModelController` then asks the `OperationContext` to execute the
operation.

The `OperationContext` acts as both the engine for operation execution,
and as the interface provided to `OperationStepHandler` implementations
to let them interact with the rest of the system.

[[execution-process]]
=== Execution Process

Operation execution proceeds via execution by the `OperationContext` of
a series of "steps" with an `OperationStepHandler` doing the key work
for each step. As mentioned above, during boot the OC is initially
configured with a number of steps, but post boot operations involve only
a single step initially. But even a post-boot operation can end up
involving numerous steps before completion. In the case of a
`/:read-resource(recursive=true)` operation, thousands of steps might
execute. This is possible because one of the key things an
`OperationStepHandler` can do is ask the `OperationContext` to add
additional steps to execute later.

Execution proceeds via a series of "stages", with a queue of steps
maintained for each stage. An `OperationStepHandler` can tell the
`OperationContext` to add a step for any stage equal to or later than
the currently executing stage. The instruction can either be to add the
step to the head of the queue for the stage or to place it at the end of
the stage's queue.

Execution of a stage continues until there are no longer any steps in
the stage's queue. Then an internal transition task can execute, and the
processing of the next stage's steps begins.

Here is some brief information about each stage:

[[stage.model]]
==== Stage.MODEL

This stage is concerned with interacting with the persistent
configuration model, either making changes to it or reading information
from it. Handlers for this stage should not make changes to the runtime,
and handlers running after this stage should not make changes to the
persistent configuration model.

If any step fails during this stage, the operation will automatically
roll back. Rollback of MODEL stage failures cannot be turned off.
Rollback during boot results in abort of the process start.

The initial step or steps added to the `OperationContext` by the
`ModelController` all execute in Stage.MODEL. This means that all
`OperationStepHandler` instances your extension registers with a
`ManagementResourceRegistration` must be designed for execution in
`Stage.MODEL`. If you need work done in later stages your `Stage.MODEL`
handler must add a step for that work.

When this stage completes, the `OperationContext` internally performs
model validation work before proceeding on to the next stage. Validation
failures will result in rollback.

[[stage.runtime]]
==== Stage.RUNTIME

This stage is concerned with interacting with the server runtime, either
reading from it or modifying it (e.g. installing or removing services or
updating their configuration.) By the time this stage begins, all model
changes are complete and model validity has been checked. So typically
handlers in this stage read their inputs from the model, not from the
original `operation` `ModelNode` provided by the user.

Most `OperationStepHandler` logic written by extension authors will be
for Stage.RUNTIME. The vast majority of Stage.MODEL handling can best be
performed by the base handler classes WildFly Core provides in its
`controller` module. (See below for more on those.)

During boot failures in `Stage.RUNTIME` will not trigger rollback and
abort of the server boot. After boot, by default failures here will
trigger rollback, but users can prevent that by using the
`rollback-on-runtime-failure` header. However, a RuntimeException thrown
by a handler will trigger rollback.

At the end of `Stage.RUNTIME`, the `OperationContext` blocks waiting for
the MSC service container to stabilize (i.e. for all services to have
reached a rest state) before moving on to the next stage.

[[stage.verify]]
==== Stage.VERIFY

Service container verification work is performed in this stage, checking
that any MSC changes made in `Stage.RUNTIME` had the expected effect.
Typically extension authors do not add any steps in this stage, as the
steps automatically added by the `OperationContext` itself are all that
are needed. You can add a step here though if you have an unusual use
case where you need to verify something after MSC has stabilized.

Handlers in this stage should not make any further runtime changes;
their purpose is simply to do verification work and fail the operation
if verification is unsuccessful.

During boot failures in `Stage.VERIFY` will not trigger rollback and
abort of the server boot. After boot, by default failures here will
trigger rollback, but users can prevent that by using the
`rollback-on-runtime-failure` header. However, a RuntimeException thrown
by a handler will trigger rollback.

There is no special transition work at the end of this stage.

[[stage.domain]]
==== Stage.DOMAIN

Extension authors should not add steps in this stage; it is only for use
by the kernel.

Steps needed to execute rollout across the domain of an operation that
affects multiple processes in a managed domain run here. This stage is
only run on Host Contoller processes, never on servers.

[[stage.done-and-resulthandler-rollbackhandler-execution]]
==== Stage.DONE and ResultHandler / RollbackHandler Execution

This stage doesn't maintain a queue of steps; no `OperationStepHandler`
executes here. What does happen here is persistence of any configuration
changes to the xml file and commit or rollback of changes affecting
multiple processes in a managed domain.

While no `OperationStepHandler` executes in this stage, following
persistence and transaction commit all `ResultHandler` or
`RollbackHandler` callbacks registered with the `OperationContext` by
the steps that executed are invoked. This is done in the reverse order
of step execution, so the callback for the last step to run is the first
to be executed. The most common thing for a callback to do is to respond
to a rollback by doing whatever is necessary to reverse changes made in
`Stage.RUNTIME`. (No reversal of `Stage.MODEL` changes is needed,
because if an operation rolls back the updated model produced by the
operation is simply never published and is discarded.)

[[tips-about-adding-steps]]
==== Tips About Adding Steps

Here are some useful tips about how to add steps:

* Add a step to the head of the current stage's queue if you want it to
execute next, prior to any other steps. Typically you would use this
technique if you are trying to decompose some complex work into pieces,
with reusable logic handling each piece. There would be an
`OperationStepHandler` for each part of the work, added to the head of
the queue in the correct sequence. This would be a pretty advanced use
case for an extension author but is quite common in the handlers
provided by the kernel.
* Add a step to the end of the queue if either you don't care when it
executes or if you do care and want to be sure it executes after any
already registered steps.
** A very common example of this is a `Stage.MODEL` handler adding a
step for its associated `Stage.RUNTIME` work. If there are multiple
model steps that will execute (e.g. at boot or as part of handling a
`composite`), each will want to add a runtime step, and likely the best
order for those runtime steps is the same as the order of the model
steps. So if each adds its runtime step at the end, the desired result
will be achieved.
** A more sophisticated but important scenario is when a step may or may
not be executing as part of a larger set of steps, i.e. it may be one
step in a `composite` or it may not. There is no way for the handler to
know. But it can assume that if it is part of a composite, the steps for
the other operations in the composite *are already registered in the
queue*. (The handler for the `composite` op guarantees this.) So, if it
wants to do some work (say validation of the relationship between
different attributes or resources) the input to which may be affected by
possible other already registered steps, instead of doing that work
itself, it should register a different step at the *end* of the queue
and have that step do the work. This will ensure that when the
validation step runs, the other steps in the `composite` will have had a
chance to do their work. *Rule of thumb: always doing any extra
validation work in an added step.*

[[passing-data-to-an-added-step]]
===== Passing Data to an Added Step

Often a handler author will want to share state between the handler for
a step it adds and the handler that added it. There are a number of ways
this can be done:

* Very often the `OperationStepHandler` for the added class is an inner
class of the handler that adds it. So here sharing state is easily done
using final variables in the outer class.
* The handler for the added step can accept values passed to its
constructor which can serve as shared state.
* The `OperationContext` includes an Attachment API which allows
arbitary data to be attached to the context and retrieved by any handler
that has access to the attachment key.
* The `OperationContext.addStep` methods include overloaded variants
where the caller can pass in an `operation` `ModelNode` that will in
turn be passed to the `execute` method of the handler for the added
step. So, state can be passed via this `ModelNode`. It's important to
remember though that the `address` field of the `operation` will govern
what the `OperationContext` sees as the target of operation when that
added step's handler executes.

[[controlling-output-from-an-added-step]]
===== Controlling Output from an Added Step

When an `OperationStepHandler` wants to report an operation result, it
calls the `OperationContext.getResult()` method and manipulates the
returned `ModelNode`. Similarly for failure messages it can call
`OperationContext.getFailureDescription()`. The usual assumption when
such a call is made is that the result or failure description being
modified is the one at the root of the response to the end user. But
this is not necessarily the case.

When an `OperationStepHandler` adds a step it can use one of the
overloaded `OperationContext.addStep` variants that takes a `response`
`ModelNode` parameter. If it does, whatever `ModelNode` it passes in
will be what is updated as a result of `OperationContext.getResult()`
and `OperationContext.getFailureDescription()` calls by the step's
handler. This node does not need to be one that is directly associated
with the response to the user.

How then does the handler that adds a step in this manner make use of
whatever results the added step produces, since the added step will not
run until the adding step completes execution? There are a couple of
ways this can be done.

The first is to add yet another step, and provide it a reference to the
`response` node used by the second step. It will execute after the
second step and can read its response and use it in formulating its own
response.

The second way involves using a `ResultHandler`. The `ResultHandler` for
a step will execute *after* any step that it adds executes. And, it is
legal for a `ResultHandler` to manipulate the "result" value for an
operation, or its "failure-description" in case of failure. So, the
handler that adds a step can provide to its `ResultHandler` a reference
to the `response` node it passed to `addStep`, and the `ResultHandler`
can in turn and use its contents to manipulate its own response.

This kind of handling wouldn't commonly be done by extension authors and
great care needs to be taken if it is done. It is often done in some of
the kernel handlers.

[[operationstephandler-use-of-the-operationcontext]]
=== OperationStepHandler use of the OperationContext

All useful work an `OperationStepHandler` performs is done by invoking
methods on the `OperationContext`. The `OperationContext` interface is
extensively javadoced, so this section will just provide a brief partial
overview. The OSH can use the `OperationContext` to:

* Learn about the environment in which it is executing (
`getProcessType`, `getRunningMode`, `isBooting`, `getCurrentStage`,
`getCallEnvironment`, `getSecurityIdentity`, `isDefaultRequiresRuntime`,
`isNormalServer`)
* Learn about the operation ( `getCurrentAddress`,
`getCurrentAddressValue`, `getAttachmentStream`,
`getAttachmentStreamCount`)
* Read the `Resource` tree ( `readResource`, `readResourceFromRoot`,
`getOriginalRootResource`)
* Manipulate the `Resource` tree ( `createResource`, `addResource`,
`readResourceForUpdate`, `removeResource`)
* Read the resource type information ( `getResourceRegistration`,
`getRootResourceRegistration`)
* Manipulate the resource type information (
`getResourceRegistrationForUpdate`)
* Read the MSC service container ( `getServiceRegistry(false)`)
* Manipulate the MSC service container ( `getServiceTarget`,
`getServiceRegistry(true)`, `removeService`)
* Manipulate the process state ( `reloadRequired`,
`revertReloadRequired`, `restartRequired`, `revertRestartRequired`
* Resolve expressions ( `resolveExpressions`)
* Manipulate the operation response ( `getResult`,
`getFailureDescription`, `attachResultStream`, `runtimeUpdateSkipped`)
* Force operation rollback ( `setRollbackOnly`)
* Add other steps ( `addStep`)
* Share data with other steps ( `attach`, `attachIfAbsent`,
`getAttachment`, `detach`)
* Work with capabilities (numerous methods)
* Emit notifications ( `emit`)
* Request a callback to a `ResultHandler` or `RollbackHandler` (
`completeStep`)

[[locking-and-change-visibility]]
=== Locking and Change Visibility

The `ModelController` and `OperationContext` work together to ensure
that only one operation at a time is modifying the state of the system.
This is done via an exclusive lock maintained by the `ModelController`.
Any operation that does not need to write never requests the lock and is
able to proceed without being blocked by an operation that holds the
lock (i.e. writes do not block reads.) If two operations wish to
concurrently write, one or the other will get the lock and the loser
will block waiting for the winner to complete and release the lock.

The `OperationContext` requests the exclusive lock the first time any of
the following occur:

* A step calls one of its methods that indicates a wish to modify the
resource tree ( `createResource`, `addResource`,
`readResourceForUpdate`, `removeResource`)
* A step calls one of its methods that indicates a wish to modify the
`ManagementResourceRegistration` tree (
`getResourceRegistrationForUpdate`)
* A step calls one of its methods that indicates a desire to change MSC
services ( `getServiceTarget`, `removeService` or `getServiceRegistry`
with the `modify` param set to `true`)
* A step calls one of its methods that manipulates the capability
registry (various)
* A step explicitly requests the lock by calling the
`acquireControllerLock` method (doing this is discouraged)

The step that acquired the lock is tracked, and the lock is released
when the `ResultHandler` added by that step has executed. (If the step
doesn't add a result handler, a default no-op one is automatically
added).

When an operation first expresses a desire to manipulate the `Resource`
tree or the capability registry, a private copy of the tree or registry
is created and thereafter the `OperationContext` works with that copy.
The copy is published back to the `ModelController` in `Stage.DONE` if
the operation commits. Until that happens any changes to the tree or
capability registry made by the operation are invisible to other
threads. If the operation does not commit, the private copies are simply
discarded.

However, the `OperationContext` does not make a private copy of the
`ManagementResourceRegistration` tree before manipulating it, nor is
there a private copy of the MSC service container. So, any changes made
by an operation to either of those are immediately visible to other
threads.

[[resource-interface]]
== Resource Interface

An instance of the `Resource` interface holds the state for a particular
instance of a type defined by a `ManagementResourceRegistration`.
Referring back to the analogy mentioned earlier the
`ManagementResourceRegistration` is analogous to a Java class while the
`Resource` is analogous to an instance of that class.

The `Resource` makes available state information, primarily

* Some descriptive metadata, such as its address, whether it is
runtime-only and whether it represents a proxy to a another primary
resource that resides on another process in a managed domain
* A `ModelNode` of `ModelType.OBJECT` whose keys are the resource's
attributes and whose values are the attribute values
* Links to child resources such that the resources form a tree

[[creating-resources]]
=== Creating Resources

Typically extensions create resources via `OperationStepHandler` calls
to the `OperationContext.createResource` method. However it is allowed
for handlers to use their own `Resource` implementations by
instantiating the resource and invoking `OperationContext.addResource`.
The `AbstractModelResource` class can be used as a base class.

[[runtime-only-and-synthetic-resources-and-the-placeholderresourceentry-class]]
=== Runtime-Only and Synthetic Resources and the PlaceholderResourceEntry Class

A runtime-only resource is one whose state is not persisted to the xml
configuration file. Many runtime-only resources are also "synthetic"
meaning they are not added or removed as a result of user initiated
management operations. Rather these resources are "synthesized" in order
to allow users to use the management API to examine some aspect of the
internal state of the process. A good example of synthetic resources are
the resources in the `/core-service=platform-mbeans` branch of the
resource tree. There are resources there that represent various aspects
of the JVM (classloaders, memory pools, etc) but which resources are
present entirely depends on what the JVM is doing, not on any management
action. Another example are resources representing "core queues" in the
WildFly messaging and messaging-artemismq subsystems. Queues are created
as a result of activity in the message broker which may not involve
calls to the management API. But for each such queue a management
resource is available to allow management users to perform management
operations against the queue.

It is a requirement of execution of a management operation that the
`OperationContext` can navigate through the resource tree to a
`Resource` object located at the address specified. This requirement
holds true even for synthetic resources. How can this be handled, given
the fact these resources are not created in response to management
operations?

The trick involves using special implementations of `Resource`. Let's
imagine a simple case where we have a parent resource which is fairly
normal (i.e. it holds persistent configuration and is added via a user's
`add` operation) except for the fact that one of its child types
represents synthetic resources (e.g. message queues). How would this be
handled?

First, the parent resource would require a custom implementation of the
`Resource` interface. The `OperationStepHandler` for the `add` operation
would instantiate it, providing it with access to whatever API is needed
for it to work out what items exist for which a synthetic resource
should be made available (e.g. an API provided by the message broker
that provides access to its queues). The `add` handler would use the
`OperationContext.addResource` method to tie this custom resource into
the overall resource tree.

The custom `Resource` implementation would use special implementations
of the various methods that relate to accessing children. For all calls
that relate to the synthetic child type (e.g. core-queue) the custom
implementation would use whatever API call is needed to provide the
correct data for that child type (e.g. ask the message broker for the
names of queues).

A nice strategy for creating such a custom resource is to use
delegation. Use `Resource.Factory.create}()` to create a standard
resource. Then pass it to the constructor of your custom resource type
for use as a delegate. The custom resource type's logic is focused on
the synthetic children; all other work it passes on to the delegate.

What about the synthetic resources themselves, i.e. the leaf nodes in
this part of the tree? These are created on the fly by the parent
resource in response to `getChild`, `requireChild`, `getChildren` and
`navigate` calls that target the synthetic resource type. These
created-on-the-fly resources can be very lightweight, since they store
no configuration model and have no children. The
`PlaceholderResourceEntry` class is perfect for this. It's a very
lightweight `Resource` implementation with minimal logic that only
stores the final element of the resource's address as state.

See `LoggingResource` in the WildFly Core logging subsystem for an
example of this kind of thing. Searching for other uses of
`PlaceholderResourceEntry` will show other examples.

[[deploymentunitprocessor-interface]]
== DeploymentUnitProcessor Interface

TODO

[[useful-classes-for-implementing-operationstephandler]]
== Useful classes for implementing OperationStepHandler

The WildFly Core `controller` module includes a number of
`OperationStepHandler` implementations that in some cases you can use
directly, and that in other cases can serve as the base class for your
own handler implementation. In all of these a general goal is to
eliminate the need for your code to do anything in `Stage.MODEL` while
providing support for whatever is appropriate for `Stage.RUNTIME`.

[[add-handlers]]
=== Add Handlers

`AbstractAddStepHandler` is a base class for handlers for `add`
operations. There are a number of ways you can configure its behavior,
the most commonly used of which are to:

* Configure its behavior in `Stage.MODEL` by passing to its constructor
`AttributeDefinition` and `RuntimeCapability` instances for the
attributes and capabilities provided by the resource. The handler will
automatically validate the operation parameters whose names match the
provided attributes and store their values in the model of the newly
added `Resource`. It will also record the presence of the given
capabilities.
* Control whether a `Stage.RUNTIME` step for the operation needs to be
added, by overriding the
`protected boolean requiresRuntime(OperationContext context)` method.
Doing this is atypical; the standard behavior in the base class is
appropriate for most cases.
* Implement the primary logic of the `Stage.RUNTIME` step by overriding
the
`protected void performRuntime(final OperationContext context, final ModelNode operation, final Resource resource)`
method. This is typically the bulk of the code in an
`AbstractAddStepHandler` subclass. This is where you read data from the
`Resource` model and use it to do things like configure and install MSC
services.
* Handle any unusual needs of any rollback of the `Stage.RUNTIME` step
by overriding
`protected void rollbackRuntime(OperationContext context, final ModelNode operation, final Resource resource)`.
Doing this is not typically needed, since if the rollback behavior
needed is simply to remove any MSC services installed in
`performRuntime`, the `OperationContext` will do this for you
automatically.

`AbstractBoottimeAddStepHandler` is a subclass of
`AbstractAddStepHandler` meant for use by `add` operations that should
only do their normal `Stage.RUNTIME` work in server, boot, with the
server being put in `reload-required` if executed later. Primarily this
is used for `add` operations that register `DeploymentUnitProcessor`
implementations, as this can only be done at boot.

Usage of `AbstractBoottimeAddStepHandler` is the same as for
`AbstractAddStepHandler` except that instead of overriding
`performRuntime` you override
`protected void performBoottime(OperationContext context, ModelNode operation, Resource resource)`.

A typical thing to do in `performBoottime` is to add a special step that
registers one or more `DeploymentUnitProcessor` s.

[source, java]
----
    @Override
    public void performBoottime(OperationContext context, ModelNode operation, final Resource resource)
            throws OperationFailedException {
 
        context.addStep(new AbstractDeploymentChainStep() {
            @Override
            protected void execute(DeploymentProcessorTarget processorTarget) {
 
                processorTarget.addDeploymentProcessor(RequestControllerExtension.SUBSYSTEM_NAME, Phase.STRUCTURE, Phase.STRUCTURE_GLOBAL_REQUEST_CONTROLLER, new RequestControllerDeploymentUnitProcessor());
            }
        }, OperationContext.Stage.RUNTIME);
   
        ... do other things
----

[[remove-handlers]]
=== Remove Handlers

TODO `AbstractRemoveStepHandler` `ServiceRemoveStepHandler`

[[write-attribute-handlers]]
=== Write attribute handlers

TODO `AbstractWriteAttributeHandler`

[[reload-required-handlers]]
=== Reload-required handlers

`ReloadRequiredAddStepHandler` `ReloadRequiredRemoveStepHandler`
`ReloadRequiredWriteAttributeHandler`

Use these for cases where, post-boot, the change to the configuration
model made by the operation cannot be reflected in the runtime until the
process is reloaded. These handle the mechanics of recording the need
for reload and reverting it if the operation rolls back.

[[restart-parent-resource-handlers]]
=== Restart Parent Resource Handlers

`RestartParentResourceAddHandler` `RestartParentResourceRemoveHandler`
`RestartParentWriteAttributeHandler`

Use these in cases where a management resource doesn't directly control
any runtime services, but instead simply represents a chunk of
configuration that a parent resource uses to configure services it
installs. (Really, this kind of situation is now considered to be a poor
management API design and is discouraged. Instead of using child
resources for configuration chunks, complex attributes on the parent
resource should be used.)

These handlers help you deal with the mechanics of the fact that,
post-boot, any change to the child resource likely requires a restart of
the service provided by the parent.

[[model-only-handlers]]
=== Model Only Handlers

`ModelOnlyAddStepHandler` `ModelOnlyRemoveStepHandler`
`ModelOnlyWriteAttributeHandler`

Use these for cases where the operation never affects the runtime, even
at boot. All it does is update the configuration model. In most cases
such a thing would be odd. These are primarily useful for legacy
subsystems that are no longer usable on current version servers and thus
will never do anything in the runtime. However, current version Domain
Controllers must be able to understand the subsystem's configuration
model to allow them to manage older Host Controllers running previous
versions where the subsystem is still usable by servers. So these
handlers allow the DC to maintain the configuration model for the
subsystem.

[[misc]]
=== Misc

`AbstractRuntimeOnlyHandler` is used for custom operations that don't
involve the configuration model. Create a subclass and implement the
`protected abstract void executeRuntimeStep(OperationContext context, ModelNode operation)`
method. The superclass takes care of adding a `Stage.RUNTIME` step that
calls your method.

`ReadResourceNameOperationStepHandler` is for cases where a resource
type includes a 'name' attribute whose value is simply the value of the
last element in the resource's address. There is no need to store the
value of such an attribute in the resource's model, since it can always
be determined from the resource address. But, if the value is not stored
in the resource model, when the attribute is registered with
`ManagementResourceRegistration.registerReadAttribute` an
`OperationStepHandler` to handle the `read-attribute` operation must be
provided. Use `ReadResourceNameOperationStepHandler` for this. (Note
that including such an attribute in your management API is considered to
be poor practice as it's just redundant data.)
<file_sep>/_docs/13/_high-availability/ha-singleton/Singleton_subsystem.adoc
[[Singleton_subsystem]]
== Singleton subsystem

WildFly 10 introduced a "singleton" subsystem, which defines a set of
policies that define how an HA singleton should behave. A singleton
policy can be used to instrument singleton deployments or to create
singleton MSC services.

[[singleton-configuration]]
== Configuration

The
https://github.com/wildfly/wildfly/blob/10.0.0.Final/clustering/singleton/extension/src/main/resources/schema/wildfly-singleton_1_0.xsd[default
subsystem configuration] from WildFly's ha and full-ha profile looks
like:

[source, xml]
----
<subsystem xmlns="urn:jboss:domain:singleton:1.0">
    <singleton-policies default="default">
        <singleton-policy name="default" cache-container="server">
            <simple-election-policy/>
        </singleton-policy>
    </singleton-policies>
</subsystem>
----

A singleton policy defines:

1. A unique name
2. A cache container and cache with which to register singleton provider candidates
3. An election policy
4. A quorum (optional)

One can add a new singleton policy via the following management
operation:

[source]
----
/subsystem=singleton/singleton-policy=foo:add(cache-container=server)
----

[[cache-configuration]]
=== Cache configuration

The cache-container and cache attributes of a singleton policy must
reference a valid cache from the Infinispan subsystem. If no specific
cache is defined, the default cache of the cache container is assumed.
This cache is used as a registry of which nodes can provide a given
service and will typically use a replicated-cache configuration.

[[election-policies]]
=== Election policies

WildFly includes two singleton election policy implementations:

* *simple* +
Elects the provider (a.k.a. master) of a singleton service based on a
specified position in a circular linked list of eligible nodes sorted by
descending age. Position=0, the default value, refers to the oldest
node, 1 is second oldest, etc. ; while position=-1 refers to the
youngest node, -2 to the second youngest, etc. +
e.g.
+
[source]
----
/subsystem=singleton/singleton-policy=foo/election-policy=simple:add(position=-1)
----

* *random* +
Elects a random member to be the provider of a singleton service +
e.g.
+
[source]
----
/subsystem=singleton/singleton-policy=foo/election-policy=random:add()
----

[[preferences]]
==== Preferences

Additionally, any singleton election policy may indicate a preference
for one or more members of a cluster. Preferences may be defined either
via node name or via outbound socket binding name. Node preferences
always take precedent over the results of an election policy. +
e.g.

[source]
----
/subsystem=singleton/singleton-policy=foo/election-policy=simple:list-add(name=name-preferences, value=nodeA)
/subsystem=singleton/singleton-policy=bar/election-policy=random:list-add(name=socket-binding-preferences, value=nodeA)
----

[[quorum]]
=== Quorum

Network partitions are particularly problematic for singleton services,
since they can trigger multiple singleton providers for the same service
to run at the same time. To defend against this scenario, a singleton
policy may define a quorum that requires a minimum number of nodes to be
present before a singleton provider election can take place. A typical
deployment scenario uses a quorum of N/2 + 1, where N is the anticipated
cluster size. This value can be updated at runtime, and will immediately
affect any active singleton services. +
e.g.

[source]
----
/subsystem=singleton/singleton-policy=foo:write-attribute(name=quorum, value=3)
----

[[non-ha-environments]]
== Non-HA environments

The singleton subsystem can be used in a non-HA profile, so long as the
cache that it references uses a local-cache configuration. In this
manner, an application leveraging singleton functionality (via the
singleton API or using a singleton deployment descriptor) will continue
function as if the server was a sole member of a cluster. For obvious
reasons, the use of a quorum does not make sense in such a
configuration.
<file_sep>/_docs/14/_testsuite/WildFly_Testsuite_Test_Developer_Guide.adoc
[[WildFly_Testsuite_Test_Developer_Guide]]
= Wild**Fly** Testsuite Test Developer Guide

*See also:* <<WildFly_Integration_Testsuite_User_Guide,WildFly
Integration Testsuite User Guide>>

[[pre-requisites]]
== Pre-requisites

Please be sure to read <<Pre-requisites_-_test_quality_standards,Pre-requisites - test quality
standards>> and follow those guidelines.

[[arquillian-container-configuration]]
== Arquillian container configuration

See
https://docs.jboss.org/author/display/ARQ/JBoss+AS+7.1%2C+JBoss+EAP+6.0+-+Managed[AS
7.1 managed container adapter refrence].

[[managementclient-and-modelnode-usage-example]]
== ManagementClient and ModelNode usage example

[source, java]
----
final ModelNode operation = new ModelNode();
operation.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.READ_RESOURCE_OPERATION);
operation.get(ModelDescriptionConstants.OP_ADDR).set(address);
operation.get(ModelDescriptionConstants.RECURSIVE).set(true);
 
final ModelNode result = managementClient.getControllerClient().execute(operation);
Assert.assertEquals(ModelDescriptionConstants.SUCCESS, result.get(ModelDescriptionConstants.OUTCOME).asString());
----

ManagementClient can be obtained as described below.

[[arquillian-features-available-in-tests]]
== Arquillian features available in tests

@ServerSetup

TBD

[source, java]
----
@ContainerResource private ManagementClient managementClient;
final ModelNode result = managementClient.getControllerClient().execute(operation);
----

TBD

[source, java]
----
@ArquillianResource private ManagementClient managementClient;
ModelControllerClient client = managementClient.getControllerClient();
----

[source, java]
----
@ArquillianResource ContainerController cc;
 
@Test
public void test() {
    cc.setup("test", ...properties..)
    cc.start("test")
}
----

[source, xml]
----
<arquillian>
    <container qualifier="test" mode="manual" />
</arquillian>
----

[source, java]
----
// Targeted containers HTTP context.
@ArquillianResource URL url;
----

[source, java]
----
// Targeted containers HTTP context where servlet is located.
@ArquillianResource(SomeServlet.class) URL url;
----

[source, java]
----
// Targeted containers initial context.
@ArquillianResource InitialContext|Context context;
----

[source, java]
----
// The manual deployer.
@ArquillianResource Deployer deployer;
----

See
https://docs.jboss.org/author/display/ARQ/Resource+injection[Arquillian's
Resource Injection docs] for more info,
https://github.com/arquillian/arquillian-examples for examples.

See also
https://docs.jboss.org/author/display/ARQ/Reference+Guide[Arquillian
Reference].

Note to @ServerSetup annotation: It works as expected only on non-manual
containers. In case of manual mode containers it calls setup() method
after each server start up which is right (or actually before
deployment), but the tearDown() method is called only at AfterClass
event, i.e. usually after your manual shutdown of the server. Which
limits you on the ability to revert some configuration changes on the
server and so on. I cloned the annotation and changed it to fit the
manual mode, but it is still in my github branch :)

[[properties-available-in-tests]]
== Properties available in tests

[[directories]]
=== Directories

* jbosssa.project.dir - Project's root dir (where ./build.sh is).
* jbossas.ts.dir - Testsuite dir.
* jbossas.ts.integ.dir - Testsuite's integration module dir.
* jboss.dist - Path to AS distribution, either built
(build/target/jboss-as-...) or user-provided via -Djboss.dist
* jboss.inst - (Arquillian in-container only) Path to the AS instance in
which the test is running (until ARQ-650 is possibly done)

* [line-through]*jboss.home* - Deprecated as it's name is unclear and
confusing. Use jboss.dist or jboss.inst.

[[networking]]
=== Networking

* node0
* node1
* 172.16.31.10

[[time-related-coefficients-ratios]]
=== Time-related coefficients (ratios)

In case some of the following causes timeouts, you may prolong the
timeouts by setting value >= 100:

100 = leave as is, +
150 = 50 % longer, etc.

* timeout.ratio.gen - General ratio - can be used to adjust all
timeouts.When this and specific are defined, both apply.

* timeout.ratio.fs- Filesystem IO
* timeout.ratio.net - Network IO
* timeout.ratio.mem - Memory IO
* timeout.ratio.cpu - Processor
* timeout.ratio.db - Database

Time ratios will soon be provided by
`org.jboss.as.test.shared.time.TimeRatio.for*()` methods.

[[negative-tests]]
== Negative tests

To test invalid deployment handling: @ShouldThrowException

Currently doesn't work due to
https://issues.jboss.org/browse/WFLY-673[WFLY-673].

optionally you might be able to catch it using the manual deployer

[source, java]
----
@Deployment(name = "X", managed = false) ...
 
@Test
public void shouldFail(@ArquillianResource Deployer deployer) throws Exception {
  try {
    deployer.deploy("X")
  }
  catch(Exception e) {
   // do something
  }
}
----

[[clustering-tests-wfly-616]]
== Clustering tests (WFLY-616)

You need to deploy the same thing twice, so two deployment methods that
just return the same thing. +
And then you have tests that run against each.

[source, java]
----
@Deployment(name = "deplA", testable = false)
    @TargetsContainer("serverB")
    public static Archive<?> deployment()
 
    @Deployment(name = "deplB", testable = false)
    @TargetsContainer("serverA")
    public static Archive<?> deployment(){ ... }
 
    @Test
    @OperateOnDeployment("deplA")
    public void testA(){ ... }
 
    @Test
    @OperateOnDeployment("deplA")
    public void testA() {...}
----

[[how-to-get-the-tests-to-master]]
== How to get the tests to master

* First of all, *be sure to read the "Before you add a test" section*.
* *Fetch* the newest mater:
`git fetch upstream # Provided you have the jbossas/jbossas GitHub repo`
`as a remote called 'upstream'.`
* *Rebase* your branch: git checkout WFLY-1234-your-branch; git rebase
upstream/master
* *Run* *_whole_* *testsuite* (integration-tests -DallTests). You may
use
https://jenkins.mw.lab.eng.bos.redhat.com/hudson/job/wildfly-as-testsuite-RHEL-matrix-openJDK7/lastCompletedBuild/testReport/.
** If any tests fail and they do not fail in master, fix it and go back
to the "Fetch" step.
* *Push* to a new branch in your GitHub repo:
`git push origin WFLY-1234-new-XY-tests`
* *Create a pull-request* on GitHub. Go to your branch and click on
"Pull Request".
** If you have a jira, start the title with it, like - WFLY-1234 New
tests for XYZ.
** If you don't, write some apposite title. In the description, describe
in detail what was done and why should it be merged. Keep in mind that
the diff will be visible under your description.
* *Keep the branch rebased daily* until it's merged (see the Fetch
step). If you don't, you're dramatically decreasing chance to get it
merged.
* There's a mailing list, jbossas-pull-requests, which is notified of
every pull-request.
* You might have someone with merge privileges to cooperate with you, so
they know what you're doing, and expect your pull request.
* When your pull request is reviewed and merged, you'll be notified by
mail from GitHub.
* You may also check if it was merged by the following:
`git fetch upstream; git cherry` `<branch> ## Or` git branch
--contains\{\{<branch> - see}} `here`
* Your commits will appear in master. They will have the same hash as in
your branch.
** You are now safe to delete both your local and remote branches:
`git branch -D WFLY-1234-your-branch; git push origin :WFLY-1234-your-branch`


include::How_to_Add_a_Test_Case.adoc[]

include::Pre-requisites_-_test_quality_standards.adoc[]

include::Shared_Test_Classes_and_Resources.adoc[]

<file_sep>/_docs/14/_developer-guide/JNDI_Local_Reference.adoc
[[JNDI_Local_Reference]]
= Local JNDI

The Java EE platform specification defines the following JNDI contexts:

* `java:comp` - The namespace is scoped to the current component (i.e.
EJB)
* `java:module` - Scoped to the current module
* `java:app` - Scoped to the current application
* `java:global` - Scoped to the application server

In addition to the standard namespaces, Wild**Fly** also provides the
following two global namespaces:

* java:jboss
* java:/

[IMPORTANT]

Only entries within the `java:jboss/exported` context are accessible
over remote JNDI.

[IMPORTANT]

For web deployments `java:comp` is aliased to `java:module`, so EJB's
deployed in a war do not have their own comp namespace.

[[binding-entries-to-jndi]]
== Binding entries to JNDI

There are several methods that can be used to bind entries into JNDI in
Wild**Fly**.

[[using-a-deployment-descriptor]]
=== Using a deployment descriptor

For Java EE applications the recommended way is to use a
<<Deployment_Descriptors_used_In_WildFly,deployment descriptor>> to create the binding. For
example the following `web.xml` binds the string `"Hello World"` to
`java:global/mystring` and the string `"Hello Module"` to
`java:comp/env/hello` (any non absolute JNDI name is relative to
`java:comp/env` context).

[source, java]
----
<web-app 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"
         version="3.1">
    <env-entry>
        <env-entry-name>java:global/mystring</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
        <env-entry-value>Hello World</env-entry-value>
    </env-entry>
    <env-entry>
        <env-entry-name>hello</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
        <env-entry-value>Hello Module</env-entry-value>
    </env-entry>
</web-app>
----

For more details, see the http://jcp.org/en/jsr/detail?id=342[Java EE
Platform Specification].

[[programatically]]
=== Programatically

[[java-ee-applications]]
==== Java EE Applications

Standard Java EE applications may use the standard JNDI API, included
with Java SE, to bind entries in the global namespaces (the standard
`java:comp`, `java:module` and `java:app` namespaces are read-only, as
mandated by the Java EE Platform Specification).

[source, java]
----
  InitialContext initialContext = new InitialContext();
  initialContext.bind("java:global/a", 100);
----

[IMPORTANT]

There is no need to unbind entries created programatically, since
Wild**Fly** tracks which bindings belong to a deployment, and the bindings
are automatically removed when the deployment is undeployed.

[[wildfly-modules-and-extensions]]
==== Wild**Fly** Modules and Extensions

With respect to code in Wild**Fly** Modules/Extensions, which is executed
out of a Java EE application context, using the standard JNDI API may
result in a UnsupportedOperationException if the target namespace uses a
WritableServiceBasedNamingStore. To work around that, the bind()
invocation needs to be wrapped using Wild**Fly** proprietary APIs:

[source, java]
----
  InitialContext initialContext = new InitialContext();
  WritableServiceBasedNamingStore.pushOwner(serviceTarget);
  try {
    initialContext.bind("java:global/a", 100);
  } finally {
    WritableServiceBasedNamingStore.popOwner();
  }
----

[IMPORTANT]

The ServiceTarget removes the bind when uninstalled, thus using one out
of the module/extension domain usage should be avoided, unless entries
are removed using unbind().

[[naming-subsystem-configuration]]
=== Naming Subsystem Configuration

It is also possible to bind to one of the three global namespaces using
configuration in the naming subsystem. This can be done by either
editing the `standalone.xml/domain.xml` file directly, or through the
management API.

Four different types of bindings are supported:

* Simple - A primitive or java.net.URL entry (default is
`java.lang.String`).
* Object Factory - This allows to to specify the
`javax.naming.spi.ObjectFactory` that is used to create the looked up
value.
* External Context - An external context to federate, such as an LDAP
Directory Service
* Lookup - The allows to create JNDI aliases, when this entry is looked
up it will lookup the target and return the result.

An example standalone.xml might look like:

[source, java]
----
<subsystem xmlns="urn:jboss:domain:naming:2.0" >
  <bindings>
    <simple name="java:global/a" value="100" type="int" />
    <simple name="java:global/jbossDocs" value="https://docs.jboss.org" type="java.net.URL" />
    <object-factory name="java:global/b" module="com.acme" class="org.acme.MyObjectFactory" />
    <external-context name="java:global/federation/ldap/example" class="javax.naming.directory.InitialDirContext" cache="true">
      <environment>
        <property name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory" />
        <property name="java.naming.provider.url" value="ldap://ldap.example.com:389" />
        <property name="java.naming.security.authentication" value="simple" />
        <property name="java.naming.security.principal" value="uid=admin,ou=system" />
        <property name="java.naming.security.credentials" value="secret" />
      </environment>
    </external-context>
    <lookup name="java:global/c" lookup="java:global/b" />
 </bindings>
</subsystem>
----

The CLI may also be used to bind an entry. As an example:

[source, java]
----
/subsystem=naming/binding=java\:global\/mybinding:add(binding-type=simple, type=long, value=1000)
----

[IMPORTANT]

Wild**Fly**'s Administrator Guide includes a section describing in detail
the Naming subsystem configuration.

[[retrieving-entries-from-jndi]]
== Retrieving entries from JNDI

[[resource-injection]]
=== Resource Injection

For Java EE applications the recommended way to lookup a JNDI entry is
to use `@Resource` injection:

[source, java]
----
  @Resource(lookup = "java:global/mystring")
  private String myString;
 
  @Resource(name = "hello")
  private String hello;
 
  @Resource
  ManagedExecutorService executor;
----

Note that `@Resource` is more than a JNDI lookup, it also binds an entry
in the component's JNDI environment. The new bind JNDI name is defined
by `@Resource`'s `name` attribute, which value, if unspecified, is the
Java type concatenated with `/` and the field's name, for instance
`java.lang.String/myString`. More, similar to when using deployment
descriptors to bind JNDI entries. unless the name is an absolute JNDI
name, it is considered relative to `java:comp/env`. For instance, with
respect to the field named `myString` above, the `@Resource`'s `lookup`
attribute instructs Wild**Fly** to lookup the value in
`java:global/mystring`, bind it in
`java:comp/env/java.lang.String/myString`, and then inject such value
into the field.

With respect to the field named `hello`, there is no `lookup` attribute
value defined, so the responsibility to provide the entry's value is
delegated to the deployment descriptor. Considering that the deployment
descriptor was the `web.xml` previously shown, which defines an
environment entry with same `hello` name, then Wild**Fly** inject the valued
defined in the deployment descriptor into the field.

The `executor` field has no attributes specified, so the bind's name
would default to
`java:comp/env/javax.enterprise.concurrent.ManagedExecutorService/executor`,
but there is no such entry in the deployment descriptor, and when that
happens it's up to Wild**Fly** to provide a default value or null, depending
on the field's Java type. In this particular case Wild**Fly** would inject
the default instance of a managed executor service, the value in
`java:comp/DefaultManagedExecutorService`, as mandated by the EE
Concurrency Utilities 1.0 Specification (JSR 236).

[[standard-java-se-jndi-api]]
=== Standard Java SE JNDI API

Java EE applications may use, without any additional configuration
needed, the standard JNDI API to lookup an entry from JNDI:

[source, java]
----
  String myString = (String) new InitialContext().lookup("java:global/mystring");
----

or simply

[source, java]
----
  String myString = InitialContext.doLookup("java:global/mystring");
----
<file_sep>/_docs/13/_developer-guide/wsconsume.adoc
[[wsconsume]]
== wsconsume

_wsconsume_ is a command line tool and ant task that "consumes" the
abstract contract (WSDL file) and produces portable JAX-WS service and
client artifacts.

[[command-line-tool]]
== Command Line Tool

The command line tool has the following usage:

....
usage: wsconsume [options] <wsdl-url>
options:
  -h, --help                  Show this help message
  -b, --binding=<file>        One or more JAX-WS or JAXB binding files
  -k, --keep                  Keep/Generate Java source
  -c  --catalog=<file>        Oasis XML Catalog file for entity resolution
  -j  --clientjar=<name>      Create a jar file of the generated artifacts for calling the webservice
  -p  --package=<name>        The target package for generated source
  -w  --wsdlLocation=<loc>    Value to use for @WebServiceClient.wsdlLocation
  -o, --output=<directory>    The directory to put generated artifacts
  -s, --source=<directory>    The directory to put Java source
  -t, --target=<2.0|2.1|2.2>  The JAX-WS specification target
  -q, --quiet                 Be somewhat more quiet
  -v, --verbose               Show full exception stack traces
  -l, --load-consumer         Load the consumer and exit (debug utility)
  -e, --extension             Enable SOAP 1.2 binding extension
  -a, --additionalHeaders     Enables processing of implicit SOAP headers
  -n, --nocompile             Do not compile generated sources
....

[IMPORTANT]

The wsdlLocation is used when creating the Service to be used by clients
and will be added to the @WebServiceClient annotation, for an endpoint
implementation based on the generated service endpoint interface you
will need to manually add the wsdlLocation to the @WebService annotation
on your web service implementation and not the service endpoint
interface.

[[examples]]
=== Examples

Generate artifacts in Java class form only:

....
wsconsume Example.wsdl
....

Generate source and class files:

....
wsconsume -k Example.wsdl
....

Generate source and class files in a custom directory:

....
wsconsume -k -o custom Example.wsdl
....

Generate source and class files in the org.foo package:

....
wsconsume -k -p org.foo Example.wsdl
....

Generate source and class files using multiple binding files:

....
wsconsume -k -b wsdl-binding.xml -b schema1-binding.xml -b schema2-binding.xml
....

[[maven-plugin]]
== Maven Plugin

The wsconsume tools is included in the
*org.jboss.ws.plugins:jaxws-tools-maven-plugin* plugin. The plugin has
two goals for running the tool, _wsconsume_ and _wsconsume-test_, which
basically do the same during different maven build phases (the former
triggers the sources generation during _generate-sources_ phase, the
latter during the _generate-test-sources_ one).

The _wsconsume_ plugin has the following parameters:

[cols=",,",options="header"]
|=======================================================================
|Attribute |Description |Default

|bindingFiles |JAXWS or JAXB binding file |true

|classpathElements |Each classpathElement provides alibrary file to be
added to classpath
|$\{project.compileClasspathElements}or$\{project.testClasspathElements}

|catalog |Oasis XML Catalog file for entity resolution |none

|targetPackage |The target Java package for generated code. |generated

|bindingFiles |One or more JAX-WS or JAXB binding file |none

|wsdlLocation |Value to use for @WebServiceClient.wsdlLocation
|generated

|outputDirectory |The output directory for generated artifacts.
|$\{project.build.outputDirectory}or$\{project.build.testOutputDirectory}

|sourceDirectory |The output directory for Java source.
|$\{project.build.directory}/wsconsume/java

|verbose |Enables more informational output about command progress.
|false

|wsdls |The WSDL files or URLs to consume |n/a

|extension |Enable SOAP 1.2 binding extension. |false

|encoding |The charset encoding to use for generated sources.
|$\{project.build.sourceEncoding}

|argLine |An optional additional argline to be used when running in fork
mode;can be used to set endorse dir, enable debugging,
etc.Example<argLine>-Djava.endorsed.dirs=...</argLine> |none

|fork |Whether or not to run the generation task in a separate VM.
|false

|target |A preference for the JAX-WS specification target |Depends on
the underlying stack and endorsed dirs if any
|=======================================================================

[[examples-1]]
=== Examples

You can use _wsconsume_ in your own project build simply referencing the
_jaxws-tools-maven-plugin_ in the configured plugins in your pom.xml
file.

The following example makes the plugin consume the test.wsdl file and
generate SEI and wrappers' java sources. The generated sources are then
compiled together with the other project classes.

[source,xml]
----
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Beta1</version>
      <configuration>
        <wsdls>
          <wsdl>${basedir}/test.wsdl</wsdl>
        </wsdls>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsconsume</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
----

You can also specify multiple wsdl files, as well as force the target
package, enable SOAP 1.2 binding and turn the tool's verbose mode on:

[source,xml]
----
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Beta1</version>
      <configuration>
       <wsdls>
        <wsdl>${basedir}/test.wsdl</wsdl>
        <wsdl>${basedir}/test2.wsdl</wsdl>
       </wsdls>
       <targetPackage>foo.bar</targetPackage>
       <extension>true</extension>
       <verbose>true</verbose>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsconsume</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
----

Finally, if the wsconsume invocation is required for consuming a wsdl to
be used in your testsuite only, you might want to use the
_wsconsume-test_ goal as follows:

[source,xml]
----
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Beta1</version>
      <configuration>
        <wsdls>
          <wsdl>${basedir}/test.wsdl</wsdl>
        </wsdls>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsconsume-test</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
----

Plugin stack dependencyThe plugin itself does not have an explicit
dependency to a JBossWS stack, as it's meant for being used with
implementations of any supported version of the _JBossWS SPI_. So the
user is expected to set a dependency in his own `pom.xml` to the desired
_JBossWS_ stack version. The plugin will rely on the that for using the
proper tooling.

[source,xml]
----
<dependencies>
  <dependency>
    <groupId>org.jboss.ws.cxf</groupId>
    <artifactId>jbossws-cxf-client</artifactId>
    <version>4.0.0.GA</version>
  </dependency>
</dependencies>
----

[TIP]

Be careful when using this plugin with the Maven War Plugin as that
include any project dependency into the generated application war
archive. You might want to set `<scope>provided</scope>` for the
_JBossWS_ stack dependency to avoid that.

[IMPORTANT]

Up to version 1.1.2.Final, the _artifactId_ of the plugin was
*maven-jaxws-tools-plugin*.

[[ant-task]]
== Ant Task

The _wsconsume_ Ant task ( _org.jboss.ws.tools.ant.WSConsumeTask_) has
the following attributes:

[cols=",,",options="header"]
|=======================================================================
|Attribute |Description |Default

|fork |Whether or not to run the generation task in a separate VM. |true

|keep |Keep/Enable Java source code generation. |false

|catalog |Oasis XML Catalog file for entity resolution |none

|package |The target Java package for generated code. |generated

|binding |A JAX-WS or JAXB binding file |none

|wsdlLocation |Value to use for @WebServiceClient.wsdlLocation
|generated

|encoding |The charset encoding to use for generated sources |n/a

|destdir |The output directory for generated artifacts. |"output"

|sourcedestdir |The output directory for Java source. |value of destdir

|target |The JAX-WS specification target. Allowed values are 2.0, 2.1
and 2.2 | 

|verbose |Enables more informational output about command progress.
|false

|wsdl |The WSDL file or URL |n/a

|extension |Enable SOAP 1.2 binding extension. |false

|additionalHeaders |Enables processing of implicit SOAP headers |false
|=======================================================================

[NOTE]

Users also need to put streamBuffer.jar and stax-ex.jar to the classpath
of the ant task to generate the appropriate artefacts.

[NOTE]

The wsdlLocation is used when creating the Service to be used by clients
and will be added to the @WebServiceClient annotation, for an endpoint
implementation based on the generated service endpoint interface you
will need to manually add the wsdlLocation to the @WebService annotation
on your web service implementation and not the service endpoint
interface.

Also, the following nested elements are supported:

[cols=",,",options="header"]
|=================================================
|Element |Description |Default
|binding |A JAXWS or JAXB binding file |none
|jvmarg |Allows setting of custom jvm arguments | 
|=================================================

[[examples-2]]
=== Examples

Generate JAX-WS source and classes in a separate JVM with separate
directories, a custom wsdl location attribute, and a list of binding
files from foo.wsdl:

[source,xml]
----
<wsconsume
  fork="true"
  verbose="true"
  destdir="output"
  sourcedestdir="gen-src"
  keep="true"
  wsdllocation="handEdited.wsdl"
  wsdl="foo.wsdl">
  <binding dir="binding-files" includes="*.xml" excludes="bad.xml"/>
</wsconsume>
----
<file_sep>/_docs/13/_high-availability/Subsystem_Support.adoc
[[Subsystem_Support]]
== Subsystem Support


////
todo look into moving this into admin guide!
////


include::subsystem-support/Infinispan_Subsystem.adoc[]
include::subsystem-support/Offloading_session_state_to_remote_Infinispan_server_cluster.adoc[]
include::subsystem-support/JGroups_Subsystem.adoc[]
include::subsystem-support/Kubernetes.adoc[]
include::subsystem-support/mod_cluster_Subsystem.adoc[]<file_sep>/_docs/13/_high-availability/Clustering_and_Domain_Setup_Walkthrough.adoc
[[Clustering_and_Domain_Setup_Walkthrough]]
= Clustering and Domain Setup Walkthrough
ifdef::env-github[:imagesdir: ../]

In this article, I'd like to show you how to setup WildFly in domain
mode and enable clustering so we could get HA and session replication
among the nodes. It's a step to step guide so you can follow the
instructions in this article and build the sandbox by yourself.

[[preparation-scenario]]
== Preparation & Scenario

[[preparation]]
=== Preparation

We need to prepare two hosts (or virtual hosts) to do the experiment. We
will use these two hosts as following:

* Install Fedora on them (Other linux version may also fine but I'll
use Fedora in this article)

* Make sure that they are in same local network

* Make sure that they can access each other via different TCP/UDP
ports (better turn off firewall and disable SELinux during the experiment
or they will cause network problems).

[[scenario]]
=== Scenario

Here are some details on what we are going to do:

* Let's call one host as 'master', the other one as 'slave'.

* Both master and slave will run WildFly, and master will run as
domain controller, slave will under the domain management of master.

* Apache httpd will be run on master, and in httpd we will enable the
mod_cluster module. The WildFly on master and slave will form a
cluster and discovered by httpd.

image:images/clustering/Clustering.jpg[images/clustering/Clustering.jpg]

* We will deploy a demo project into domain, and verify that the project
is deployed into both master and slave by domain controller. Thus we
could see that domain management provide us a single point to manage the
deployments across multiple hosts in a single domain.

* We will access the cluster URL and verify that httpd has distributed
the request to one of the WildFly host. So we could see the cluster is
working properly.

* We will try to make a request on cluster, and if the request is
forwarded to master, we then kill the WildFly process on master. After
that we will go on requesting cluster and we should see the request is
forwarded to slave, but the session is not lost. Our goal is to verify
the HA is working and sessions are replicated.

* After previous step finished, we reconnect the master by restarting
it. We should see the master is registered back into cluster, also we
should see slave sees master as domain controller again and connect to
it.

image:images/clustering/test_scenario.jpg[images/clustering/test_scenario.jpg]

Please don't worry if you cannot digest so many details currently. Let's
move on and you will get the points step by step.

[[download-wildfly]]
== Download WildFly

First we should download WildFly from the http://wildfly.org/downloads/[WildFly website].

Then I unzipped the package to master and try to make a test run:

[source, bash, subs="verbatim,attributes"]
----
unzip wildfly-{wildflyVersion}.0.0.Final.zip
cd wildfly-{wildflyVersion}.0.0.Final/bin
./domain.sh
----

If everything ok we should see WildFly successfully startup in domain
mode:

[source, bash, subs="verbatim,attributes"]
----
wildfly-{wildflyVersion}.0.0.Final/bin$ ./domain.sh
=========================================================================
 
  JBoss Bootstrap Environment
 
  JBOSS_HOME: /Users/weli/Downloads/wildfly-{wildflyVersion}.0.0.Final
 
  JAVA: /Library/Java/Home/bin/java
 
  JAVA_OPTS: -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true
 
=========================================================================
...
 
[Server:server-two] 14:46:12,375 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly {wildflyVersion}.0.0.Final "Kenny" started in 8860ms - Started 210 of 258 services (8{wildflyVersion} services are lazy, passive or on-demand)
----

Now exit master and let's repeat the same steps on slave host. Finally
we get WildFly run on both master and slave, then we could move on to
next step.

[[domain-configuration]]
== Domain Configuration

[[interface-config-on-master]]
=== Interface config on master

In this section we'll setup both master and slave for them to run in
domain mode. And we will configure master to be the domain controller.

First open the host.xml in master for editing:

[source, bash]
----
vi domain/configuration/host.xml
----

The default settings for interface in this file is like:

[source, xml]
----
<interfaces>
    <interface name="management">
        <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
    </interface>
    <interface name="public">
       <inet-address value="${jboss.bind.address:127.0.0.1}"/>
    </interface>
    <interface name="unsecured">       
       <inet-address value="127.0.0.1" />    
    </interface>
</interfaces>
----

We need to change the address to the management interface so slave could
connect to master. The public interface allows the application to be
accessed by non-local HTTP, and the unsecured interface allows remote
RMI access. My master's ip address is 10.211.55.7, so I change the
config to:

[source, xml]
----
<interfaces>
    <interface name="management"
        <inet-address value="${jboss.bind.address.management:10.211.55.7}"/>
    </interface>
    <interface name="public">
       <inet-address value="${jboss.bind.address:10.211.55.7}"/>
    </interface>    
    <interface name="unsecured">
       <inet-address value="10.211.55.7" />    
    </interface>
</interfaces> 
----

[[interface-config-on-slave]]
=== Interface config on slave

Now we will setup interfaces on slave. Let's edit host.xml. Similar to
the steps on master, open host.xml first:

[source, bash]
----
vi domain/configuration/host.xml
----

The configuration we'll use on slave is a little bit different, because
we need to let slave connect to master. First we need to set the
hostname. We change the name property from:

[source, xml]
----
<host name="master" xmlns="urn:jboss:domain:3.0">
----

to:

[source, xml]
----
<host name="slave" xmlns="urn:jboss:domain:3.0">
----

Then we need to modify domain-controller section so slave can connect to
master's management port:

[source, xml]
----
<domain-controller>
   <remote protocol="remote" host="10.211.55.7" port="9999" />
</domain-controller>
----

As we know, 10.211.55.7 is the ip address of master.
You may use discovery options to define multiple mechanisms to connect
to the remote domain controller :

[source, xml]
----
<domain-controller>
 <remote security-realm="ManagementRealm" >
   <discovery-options>
     <static-discovery name="master-native" protocol="remote"  host="10.211.55.7" port=9999" />
     <static-discovery name="master-https" protocol="https-remoting" host="10.211.55.7" port="9993" security-realm="ManagementRealm"/>
     <static-discovery name="master-http" protocol="http-remoting" host="10.211.55.7" port="9990" />
   </discovery-options>
 </remote>
</domain-controller>
----

Finally, we also need to configure interfaces section and expose the
management ports to public address:

[source, xml]
----
<interfaces>
    <interface name="management">
        <inet-address value="${jboss.bind.address.management:10.211.55.2}"/>
    </interface>
    <interface name="public">
       <inet-address value="${jboss.bind.address:10.211.55.2}"/>
    </interface>
    <interface name="unsecured">       
       <inet-address value="10.211.55.2" />    
    </interface>
</interfaces>
----

10.211.55.2 is the ip address of the slave. Refer to the domain
controller configuration above for an explanation of the management,
public, and unsecured interfaces.

[TIP]

It is easier to turn off all firewalls for testing, but in production,
you need to enable the firewall and allow access to the following ports:
9999.

[[security-configuration]]
=== Security Configuration

If you start WildFly on both master and slave now, you will see the
slave cannot be started with following error:

[source]
----
[Host Controller] 20:31:24,575 ERROR [org.jboss.remoting.remote] (Remoting "endpoint" read-1) JBREM000200: Remote connection failed: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed
[Host Controller] 20:31:24,579 WARN  [org.jboss.as.host.controller] (Controller Boot Thread) JBAS010900: Could not connect to remote domain controller 10.211.55.7:9999
[Host Controller] 20:31:24,582 ERROR [org.jboss.as.host.controller] (Controller Boot Thread) JBAS010901: Could not connect to master. Aborting. Error was: java.lang.IllegalStateException: JBAS010942: Unable to connect due to authentication failure.
----

Because we haven't properly set up the authentication between master and
slave. Now let's work on it:

[[master]]
==== Master

In bin directory there is a script called add-user.sh, we'll use it to
add new users to the properties file used for domain management
authentication:

[source, bash, subs="verbatim,attributes"]
----
./add-user.sh
 
Enter the details of the new user to add.
Realm (ManagementRealm) :
Username : admin
Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.
 - The password should not be one of the following restricted values {root, admin, administrator}
 - The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
 - The password should be different from the username
Password : <PASSWORD>!
Re-enter Password : <PASSWORD>!
The username 'admin' is easy to guess
Are you sure you want to add user 'admin' yes/no? yes
About to add user 'admin' for realm 'ManagementRealm'
Is this correct yes/no? yes
Added user 'admin' to file '/home/weli/projs/wildfly-{wildflyVersion}.0.0.Final/standalone/configuration/mgmt-users.properties'
Added user 'admin' to file '/home/weli/projs/wildfly-{wildflyVersion}.0.0.Final/domain/configuration/mgmt-users.properties'
----

As shown above, we have created a user named 'admin' and its password is
'<PASSWORD>!'. Then we add another user called 'slave':

[source, bash, subs="verbatim,attributes"]
----
./add-user.sh
 
Enter the details of the new user to add.
Realm (ManagementRealm) :
Username : slave
Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.
 - The password should not be one of the following restricted values {root, admin, administrator}
 - The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
 - The password should be different from the username
Password : <PASSWORD>!
Re-enter Password : <PASSWORD>!
What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[  ]:
About to add user 'slave' for realm 'ManagementRealm'
Is this correct yes/no? yes
Added user 'slave' to file '/home/weli/projs/wildfly-{wildflyVersion}.0.0.Final/standalone/configuration/mgmt-users.properties'
Added user 'slave' to file '/home/weli/projs/wildfly-{wildflyVersion}.0.0.Final/domain/configuration/mgmt-users.properties'
Added user 'slave' with groups  to file '/home/weli/projs/wildfly-{wildflyVersion}.0.0.Final/standalone/configuration/mgmt-groups.properties'
Added user 'slave' with groups  to file '/home/weli/projs/wildfly-{wildflyVersion}.0.0.Final/domain/configuration/mgmt-groups.properties'
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition <secret value="cGFzc3cwcmQh" />
----

We will use this user for slave host to connect to master. The
add-user.sh will let you choose the type of the user. Here we need to
choose 'Management User' type for both 'admin' and 'slave' account.

[[slave]]
==== Slave

In slave we need to configure host.xml for authentication. We should
change the security-realms section as following:

[source, java]
----
<security-realms>
   <security-realm name="ManagementRealm">
       <server-identities>
           <secret value="cGFzc3cwcmQh" />
           <!-- This is required for SSL remoting -->
           <ssl>
             <keystore path="server.keystore" relative-to="jboss.domain.config.dir" keystore-password="<PASSWORD>" alias="jboss" key-password="<PASSWORD>"/>
           </ssl>
       </server-identities>
       <authentication>
           <properties path="mgmt-users.properties" relative-to="jboss.domain.config.dir"/>
       </authentication>
   </security-realm>
</security-realms>
----

We've added server-identities into security-realm, which is used for
authentication host when slave tries to connect to master. In secret
value property we have 'cGFzc3cwcmQh', which is the base64 code for
'passw0rd!'. You can generate this value by using a base64 calculator
such as the one at http://www.webutils.pl/index.php?idx=base64.

Then in domain controller section we also need to add security-realm
property:

[source, xml]
----
<domain-controller>
   <remote protocol="remote" host="10.211.55.7" port="9999" username="slave" security-realm="ManagementRealm"  />
</domain-controller>
----

So the slave host could use the authentication information we provided
in 'ManagementRealm'.

[[dry-run]]
==== Dry Run

Now everything is set for the two hosts to run in domain mode. Let's
start them by running domain.sh on both hosts. If everything goes fine,
we could see from the log on master:

[source, java]
----
[Host Controller] 21:30:52,042 INFO  [org.jboss.as.domain] (management-handler-threads - 1) JBAS010918: Registered remote slave host slave
----

That means all the configurations are correct and two hosts are run in
domain mode now as expected. Hurrah!

[[deployment]]
== Deployment

Now we can deploy a demo project into the domain. I have created a
simple project located at:

[source, java]
----
https://github.com/liweinan/cluster-demo
----

We can use git command to fetch a copy of the demo:

[source, java]
----
git clone git://github.com/liweinan/cluster-demo.git
----

In this demo project we have a very simple web application. In web.xml
we've enabled session replication by adding following entry:

[source, xml]
----
<distributable/>
----

And it contains a jsp page called put.jsp which will put current time to
a session entry called 'current.time':

[source, java]
----
<%
    session.setAttribute("current.time", new java.util.Date());
%>
----

Then we could fetch this value from get.jsp:

[source, java]
----
The time is <%= session.getAttribute("current.time") %>
----

It's an extremely simple project but it could help us to test the
cluster later: We will access put.jsp from cluster and see the request
are distributed to master, then we disconnect master and access get.jsp.
We should see the request is forwarded to slave but the 'current.time'
value is held by session replication. We'll cover more details on this
one later.

Let's go back to this demo project. Now we need to create a war from it.
In the project directory, run the following command to get the war:

[source]
----
mvn package
----

It will generate cluster-demo.war. Then we need to deploy the war into
domain. First we should access the http management console on
master(Because master is acting as domain controller):

[source]
----
http://10.211.55.7:9990
----

It will popup a windows ask you to input account name and password, we
can use the 'admin' account we've added just now. After logging in we
could see the 'Server Instances' window. By default there are three
servers listed, which are:

* server-one

* server-two

* server-three

We could see server-one and server-two are in running status and they
belong to main-server-group; server-three is in idle status, and it
belongs to other-server-group.

All these servers and server groups are set in domain.xml on master as7.
What we are interested in is the 'other-server-group' in domain.xml:

[source, xml]
----
<server-group name="other-server-group" profile="ha">
   <jvm name="default">
       <heap size="64m" max-size="512m"/>
   </jvm>
   <socket-binding-group ref="ha-sockets"/>
</server-group>
----

We could see this server-group is using 'ha' profile, which then uses
'ha-sockets' socket binding group. It enable all the modules we need to
establish cluster later(including infinispan, jgroup and mod_cluster
modules). So we will deploy our demo project into a server that belongs
to 'other-server-group', so 'server-three' is our choice.

[IMPORTANT]

In newer version of WildFly, the profile 'ha' changes to 'full-ha':

[source, xml]
----
<server-group name="other-server-group" profile="full-ha">
----

Let's go back to domain controller's management console:

[source]
----
http://10.211.55.7:9990
----

Now server-three is not running, so let's click on 'server-three' and
then click the 'start' button at bottom right of the server list. Wait a
moment and server-three should start now.

Now we should also enable 'server-three' on slave: From the top of menu
list on left side of the page, we could see now we are managing master
currently. Click on the list, and click 'slave', then choose
'server-three', and we are in slave host management page now.

Then repeat the steps we've done on master to start 'server-three' on
slave.

[TIP]

server-three on master and slave are two different hosts, their names
can be different.

After server-three on both master and slave are started, we will add our
cluster-demo.war for deployment. Click on the 'Manage Deployments' link
at the bottom of left menu list.

image:images/clustering/JBoss_Management.png[images/clustering/JBoss_Management.png] +
(We should ensure the server-three should be started on both master and
slave)

After enter 'Manage Deployments' page, click 'Add Content' at top right
corner. Then we should choose our cluster-demo.war, and follow the
instruction to add it into our content repository.

Now we can see cluster-demo.war is added. Next we click 'Add to Groups'
button and add the war to 'other-server-group' and then click 'save'.

Wait a few seconds, management console will tell you that the project is
deployed into 'other-server-group'.：

image:images/clustering/JBoss_Management_2.png[images/clustering/JBoss_Management_2.png]

Please note we have two hosts participate in this server group, so the
project should be deployed in both master and slave now - that's the
power of domain management.

Now let's verify this, trying to access cluster-demo from both master
and slave, and they should all work now:

[source]
----
http://10.211.55.7:8330/cluster-demo/
----

image:images/clustering/http---10.211.55.7-8330-cluster-demo-.png[images/clustering/http---10.211.55.7-8330-cluster-demo-.png]

[source]
----
http://10.211.55.2:8330/cluster-demo/
----

image:images/clustering/http---10.211.55.2-8330-cluster-demo-.png[images/clustering/http---10.211.55.2-8330-cluster-demo-.png]

Now that we have finished the project deployment and see the usages of
domain controller, we will then head up for using these two hosts to
establish a cluster icon:smile-o[role="yellow"]

[IMPORTANT]

Why is the port number 8330 instead of 8080? Please check the settings
in host.xml on both master and slave:

[source, xml]
----
<server name="server-three" group="other-server-group" auto-start="false">
    <!-- server-three avoids port conflicts by incrementing the ports in
         the default socket-group declared in the server-group -->
    <socket-bindings port-offset="250"/>
</server>
----

The port-offset is set to 250, so 8080 + 250 = 8330

Now we quit the WildFly process on both master and slave. We have some
work left on host.xml configurations. Open the host.xml of master, and
do some modifications the servers section from:

[source, xml]
----
<server name="server-three" group="other-server-group" auto-start="false">
    <!-- server-three avoids port conflicts by incrementing the ports in
         the default socket-group declared in the server-group -->
    <socket-bindings port-offset="250"/>
</server>
----

to:

[source, xml]
----
<server name="server-three" group="other-server-group" auto-start="true">
    <!-- server-three avoids port conflicts by incrementing the ports in
         the default socket-group declared in the server-group -->
    <socket-bindings port-offset="250"/>
</server>
----

We've set auto-start to true so we don't need to enable it in management
console each time WildFly restart. Now open slave's host.xml, and modify
the server-three section:

[source, xml]
----
<server name="server-three-slave" group="other-server-group" auto-start="true">
    <!-- server-three avoids port conflicts by incrementing the ports in
         the default socket-group declared in the server-group -->
    <socket-bindings port-offset="250"/>
</server>
----

Besides setting auto-start to true, we've renamed the 'server-three' to
'server-three-slave'. We need to do this because mod_cluster will fail
to register the hosts with same name in a single server group. It will
cause name conflict.

After finishing the above configuration, let's restart two as7 hosts and
go on cluster configuration.

[[cluster-configuration]]
== Cluster Configuration

We will use mod_cluster + apache httpd on master as our cluster
controller here. Because WildFly has been configured to support
mod_cluster out of box so it's the easiest way.

[IMPORTANT]

The WildFly domain controller and httpd are not necessary to be on
same host. But in this article I just install them all on master for
convenience.

First we need to ensure that httpd is installed:

[source, bash]
----
sudo yum install httpd
----

And then we need to download newer version of mod_cluster from its
website:

[source]
----
http://www.jboss.org/mod_cluster/downloads
----

The version I downloaded is:

[source]
----
http://downloads.jboss.org/mod_cluster/1.1.3.Final/mod_cluster-1.1.3.Final-linux2-x86-so.tar.gz
----

[TIP]

Jean-Frederic has suggested to use mod_cluster 1.2.x. Because 1.1.x it
is affected by CVE-2011-4608

With mod_cluster-1.2.0 you need to add EnableMCPMReceive in the
VirtualHost.

Then we extract it into:

[source]
----
/etc/httpd/modules
----

Then we edit httpd.conf:

[source, bash]
----
sudo vi /etc/httpd/conf/httpd.conf
----

We should add the modules:

[source]
----
LoadModule slotmem_module modules/mod_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule advertise_module modules/mod_advertise.so
----

Please note we should comment out:

[source, java]
----
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
----

This is conflicted with cluster module. And then we need to make httpd
to listen to public address so we could do the testing. Because we
installed httpd on master host so we know the ip address of it:

[source]
----
Listen 10.211.55.7:80
----

Then we do the necessary configuration at the bottom of httpd.conf:

[source]
----
# This Listen port is for the mod_cluster-manager, where you can see the status of mod_cluster.
# Port 10001 is not a reserved port, so this prevents problems with SELinux.
Listen 10.211.55.7:10001
# This directive only applies to Red Hat Enterprise Linux. It prevents the temmporary
# files from being written to /etc/httpd/logs/ which is not an appropriate location.
MemManagerFile /var/cache/httpd
 
<VirtualHost 10.211.55.7:10001>
 
  <Directory />
    Order deny,allow
    Deny from all
    Allow from 10.211.55.
  </Directory>
 
 
  # This directive allows you to view mod_cluster status at URL http://10.211.55.4:10001/mod_cluster-manager
  <Location /mod_cluster-manager>
   SetHandler mod_cluster-manager
   Order deny,allow
   Deny from all
   Allow from 10.211.55.
  </Location>
 
  KeepAliveTimeout 60
  MaxKeepAliveRequests 0
 
  ManagerBalancerName other-server-group
  AdvertiseFrequency 5
 
</VirtualHost>
----

[IMPORTANT]

For more details on mod_cluster configurations please see this document:

[source, java]
----
http://docs.jboss.org/mod_cluster/1.1.0/html/Quick_Start_Guide.html
----

[[testing]]
== Testing

If everything goes fine we can start httpd service now:

[source, bash]
----
service httpd start
----

Now we access the cluster:

[source]
----
http://10.211.55.7/cluster-demo/put.jsp
----

image:images/clustering/http---10.211.55.7-cluster-demo-put.jsp.png[images/clustering/http---10.211.55.7-cluster-demo-put.jsp.png]

We should see the request is distributed to one of the hosts(master or
slave) from the WildFly log. For me the request is sent to master:

[source]
----
[Server:server-three] 16:06:22,256 INFO  [stdout] (http-10.211.55.7-10.211.55.7-8330-4) Putting date now
----

Now I disconnect master by using the management interface. Select
'runtime' and the server 'master' in the upper corners.

Select 'server-three' and kick the stop button, the active-icon should
change.

Killing the server by using system commands will have the effect that
the Host-Controller restart the instance immediately!

Then wait for a few seconds and access cluster:

[source]
----
http://10.211.55.7/cluster-demo/get.jsp
----

image:images/clustering/http---10.211.55.7-cluster-demo-get.jsp.png[images/clustering/http---10.211.55.7-cluster-demo-get.jsp.png]

Now the request should be served by slave and we should see the log from
slave:

[source, bash]
----
[Server:server-three-slave] 16:08:29,860 INFO  [stdout] (http-10.211.55.2-10.211.55.2-8330-1) Getting date now
----

And from the get.jsp we should see that the time we get is the same
we've put by 'put.jsp'. Thus it's proven that the session is correctly
replicated to slave.

Now we restart master and should see the host is registered back to
cluster.

[TIP]

It doesn't matter if you found the request is distributed to slave at
first time. Then just disconnect slave and do the testing, the request
should be sent to master instead. The point is we should see the request
is redirect from one host to another and the session is held.

[[special-thanks]]
== Special Thanks

https://community.jboss.org/people/wdfink[<NAME>] has
contributed the updated add-user.sh usages and configs in host.xml from
7.1.0.Final. +
https://community.jboss.org/people/jfclere[<NAME>] provided
the mod_cluster 1.2.0 usages. +
<NAME> has given a lot of suggestions and helps to make
this document readable.
<file_sep>/_docs/13/_high-availability/subsystem-support/mod_cluster_Subsystem.adoc
[[mod_cluster_Subsystem]]
== mod_cluster Subsystem

The mod_cluster integration is done via the `mod_cluster` subsystem.

[[configuration]]
== Configuration

[[instance-id-or-jvmroute]]
=== Instance ID or JVMRoute

The instance-id or JVMRoute defaults to `jboss.node.name` property passed
on server startup (e.g. via `-Djboss.node.name=XYZ`).

[source]
----
[standalone@localhost:9990 /] /subsystem=undertow/:read-attribute(name=instance-id)
{
    "outcome" => "success",
    "result" => expression "${jboss.node.name}"
}
----

To configure instance-id statically, configure the corresponding
property in Undertow subsystem:

[source]
----
[standalone@localhost:9990 /] /subsystem=undertow/:write-attribute(name=instance-id,value=myroute)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
----

[[proxies]]
=== Proxies

By default, mod_cluster is configured for multicast-based discovery. To
specify a static list of proxies, create a remote-socket-binding for
each proxy and then reference them in the 'proxies' attribute. See the
following example for configuration in the domain mode:

[source]
----
[domain@localhost:9990 /] /socket-binding-group=ha-sockets/remote-destination-outbound-socket-binding=proxy1:add(host=10.21.152.86, port=6666)
{
    "outcome" => "success",
    "result" => undefined,
    "server-groups" => undefined
}
[domain@localhost:9990 /] /socket-binding-group=ha-sockets/remote-destination-outbound-socket-binding=proxy2:add(host=10.21.152.87, port=6666)
{
    "outcome" => "success",
    "result" => undefined,
    "server-groups" => undefined
}
[domain@localhost:9990 /] /profile=ha/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=proxies, value=[proxy1, proxy2])
{
    "outcome" => "success",
    "result" => undefined,
    "server-groups" => undefined
}
[domain@localhost:9990 /] :reload-servers
{
    "outcome" => "success",
    "result" => undefined,
    "server-groups" => undefined
}
----

[[runtime-operations]]
== Runtime Operations

The modcluster subsystem supports several operations:

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :read-operation-names
{
    "outcome" => "success",
    "result" => [
        "add",
        "add-custom-metric",
        "add-metric",
        "add-proxy",
        "disable",
        "disable-context",
        "enable",
        "enable-context",
        "list-proxies",
        "read-attribute",
        "read-children-names",
        "read-children-resources",
        "read-children-types",
        "read-operation-description",
        "read-operation-names",
        "read-proxies-configuration",
        "read-proxies-info",
        "read-resource",
        "read-resource-description",
        "refresh",
        "remove-custom-metric",
        "remove-metric",
        "remove-proxy",
        "reset",
        "stop",
        "stop-context",
        "validate-address",
        "write-attribute"
    ]
}
----

The operations specific to the modcluster subsystem are divided in 3
categories the ones that affects the configuration and require a restart
of the subsystem, the one that just modify the behaviour temporarily and
the ones that display information from the httpd part.

[[operations-displaying-httpd-informations]]
=== operations displaying httpd information

There are 2 operations that display how Apache httpd sees the node:

[[read-proxies-configuration]]
==== read-proxies-configuration

Send a DUMP message to all Apache httpd the node is connected to and
display the message received from Apache httpd.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :read-proxies-configuration
{
    "outcome" => "success",
    "result" => [
        "neo3:6666",
        "balancer: [1] Name: mycluster Sticky: 1 [JSESSIONID]/[jsessionid] remove: 0 force: 1 Timeout: 0 Maxtry: 1
node: [1:1],Balancer: mycluster,JVMRoute: 498bb1f0-00d9-3436-a341-7f012bc2e7ec,Domain: [],Host: 127.0.0.1,Port: 8080,Type: http,flushpackets: 0,flushwait: 10,ping: 10,smax: 26,ttl: 60,timeout: 0
host: 1 [example.com] vhost: 1 node: 1
host: 2 [localhost] vhost: 1 node: 1
host: 3 [default-host] vhost: 1 node: 1
context: 1 [/myapp] vhost: 1 node: 1 status: 1
context: 2 [/] vhost: 1 node: 1 status: 1
",
        "jfcpc:6666",
        "balancer: [1] Name: mycluster Sticky: 1 [JSESSIONID]/[jsessionid] remove: 0 force: 1 Timeout: 0 maxAttempts: 1
node: [1:1],Balancer: mycluster,JVMRoute: 498bb1f0-00d9-3436-a341-7f012bc2e7ec,LBGroup: [],Host: 127.0.0.1,Port: 8080,Type: http,flushpackets: 0,flushwait: 10,ping: 10,smax: 26,ttl: 60,timeout: 0
host: 1 [default-host] vhost: 1 node: 1
host: 2 [localhost] vhost: 1 node: 1
host: 3 [example.com] vhost: 1 node: 1
context: 1 [/] vhost: 1 node: 1 status: 1
context: 2 [/myapp] vhost: 1 node: 1 status: 1
"
    ]
}
----

[[read-proxies-info]]
==== read-proxies-info

Send a INFO message to all Apache httpd the node is connected to and
display the message received from Apache httpd.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :read-proxies-info
{
    "outcome" => "success",
    "result" => [
        "neo3:6666",
        "Node: [1],Name: 498bb1f0-00d9-3436-a341-7f012bc2e7ec,Balancer: mycluster,Domain: ,Host: 127.0.0.1,Port: 8080,Type: http,Flushpackets: Off,Flushwait: 10000,Ping: 10000000,Smax: 26,Ttl: 60000000,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: -1
Vhost: [1:1:1], Alias: example.com
Vhost: [1:1:2], Alias: localhost
Vhost: [1:1:3], Alias: default-host
Context: [1:1:1], Context: /myapp, Status: ENABLED
Context: [1:1:2], Context: /, Status: ENABLED
",
        "jfcpc:6666",
        "Node: [1],Name: 498bb1f0-00d9-3436-a341-7f012bc2e7ec,Balancer: mycluster,LBGroup: ,Host: 127.0.0.1,Port: 8080,Type: http,Flushpackets: Off,Flushwait: 10,Ping: 10,Smax: 26,Ttl: 60,Elected: 0,Read: 0,Transfered: 0,Connected: 0,Load: 1
Vhost: [1:1:1], Alias: default-host
Vhost: [1:1:2], Alias: localhost
Vhost: [1:1:3], Alias: example.com
Context: [1:1:1], Context: /, Status: ENABLED
Context: [1:1:2], Context: /myapp, Status: ENABLED
"
    ]
}
----

[[operations-that-handle-the-proxies-the-node-is-connected-too]]
==== operations that handle the proxies the node is connected too

There are 3 operation that could be used to manipulate the list of
Apache httpd the node is connected to.

[[list-proxies]]
==== list-proxies

Displays the httpd that are connected to the node. The httpd could be
discovered via the Advertise protocol or via the proxy-list attribute.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :list-proxies
{
    "outcome" => "success",
    "result" => [
        "proxy1:6666",
        "proxy2:6666"
    ]
}
----

[[remove-proxy]]
==== remove-proxy

Remove a proxy from the discovered proxies or temporarily from the
proxy-list attribute.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :remove-proxy(host=jfcpc, port=6666)
{"outcome" => "success"}
----

[[add-proxy]]
==== add-proxy

Add a proxy to the discovered proxies or temporarily to the proxy-list
attribute.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :add-proxy(host=jfcpc, port=6666)
{"outcome" => "success"}
----

[[context-related-operations]]
=== Context related operations

Those operations allow to send context related commands to Apache httpd.
They are send automatically when deploying or undeploying webapps.

[[enable-context]]
==== enable-context

Tell Apache httpd that the context is ready receive requests.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :enable-context(context=/myapp, virtualhost=default-host)
{"outcome" => "success"}
----

[[disable-context]]
==== disable-context

Tell Apache httpd that it shouldn't send new session requests to the
context of the virtualhost.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :disable-context(context=/myapp, virtualhost=default-host)
{"outcome" => "success"}
----

[[stop-context]]
==== stop-context

Tell Apache httpd that it shouldn't send requests to the context of the
virtualhost.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :stop-context(context=/myapp, virtualhost=default-host, waittime=50)
{"outcome" => "success"}
----

[[node-related-operations]]
=== Node related operations

Those operations are like the context operation but they apply to all
webapps running on the node and operation that affect the whole node.

[[refresh]]
==== refresh

Refresh the node by sending a new CONFIG message to Apache httpd.

[[reset]]
==== reset

Reset the connection between Apache httpd and the node.

[[configuration-1]]
=== Configuration

[[metric-configuration]]
==== Metric configuration

There are 4 metric operations corresponding to add and remove load
metrics to the dynamic-load-provider. Note that when nothing is defined
a simple-load-provider is use with a fixed load factor of one.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :read-resource(name=mod-cluster-config)
{
    "outcome" => "success",
    "result" => {"simple-load-provider" => {"factor" => "1"}}
}
----

that corresponds to the following configuration:

[source, xml]
----
<subsystem xmlns="urn:jboss:domain:modcluster:1.0">
            <mod-cluster-config>
                <simple-load-provider factor="1"/>
            </mod-cluster-config>
 </subsystem>
----

[[add-metric]]
===== add-metric

Add a metric to the dynamic-load-provider, the dynamic-load-provider in
configuration is created if needed.

[source, ruby]
----
[standalone@localhost:9999 subsystem=modcluster] :add-metric(type=cpu)
{"outcome" => "success"}
[standalone@localhost:9999 subsystem=modcluster] :read-resource(name=mod-cluster-config)
{
    "outcome" => "success",
    "result" => {
        "dynamic-load-provider" => {
            "history" => 9,
            "decay" => 2,
            "load-metric" => [{
                "type" => "cpu"
            }]
        }
    }
}
----

[[remove-metric]]
===== remove-metric

Remove a metric from the dynamic-load-provider.

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :remove-metric(type=cpu)
{"outcome" => "success"}
----

[[add-custom-metric-remove-custom-metric]]
===== add-custom-metric / remove-custom-metric

like the add-metric and remove-metric except they require a class
parameter instead the type. Usually they needed additional properties
which can be specified

[source]
----
[standalone@localhost:9999 subsystem=modcluster] :add-custom-metric(class=myclass, property=[("pro1" => "value1"), ("pro2" => "value2")]
{"outcome" => "success"}
----

which corresponds the following in the xml configuration file:

[source, xml]
----
<subsystem xmlns="urn:jboss:domain:modcluster:1.0">
            <mod-cluster-config>
                <dynamic-load-provider history="9" decay="2">
                    <custom-load-metric class="myclass">
                        <property name="pro1" value="value1"/>
                        <property name="pro2" value="value2"/>
                    </custom-load-metric>
                </dynamic-load-provider>
            </mod-cluster-config>
</subsystem>
----

include::SSL_Configuration_using_Elytron_Subsystem.adoc[leveloffset=+1]<file_sep>/_docs/13/_high-availability/subsystem-support/SSL_Configuration_using_Elytron_Subsystem.adoc
[[SSL_Configuration_using_Elytron_Subsystem]]
== SSL Configuration using Elytron Subsystem

[abstract]

This document provides information how to configure mod_cluster
subsystem to protect communication between mod_cluster and load balancer
using SSL/TLS using link:WildFly_Elytron_Security{outfilesuffix}#Elytron_Subsystem[Elytron Subsystem].

== Overview

Elytron subsystem provides a powerful and flexible model to configure
different security aspects for applications and the application server
itself. At its core, Elytron subsystem exposes different capabilities to
the application server in order centralize security related
configuration in a single place and to allow other subsystems to consume
these capabilities. One of the security capabilities exposed by Elytron
subsystem is a Client `ssl-context` that can be used to configure
mod_cluster subsystem to communicate with a load balancer using SSL/TLS.

When protecting the communication between the application server and the
load balancer, you need do define a Client `ssl-context` in order to:

* Define a trust store holding the certificate chain that will be used
to validate load balancer's certificate
* Define a trust manager to perform validations against the load
balancer's certificate

[[defining-a-trust-store-with-the-trusted-certificates]]
== Defining a Trust Store with the Trusted Certificates

To define a trust store in Elytron you can execute the following CLI
command:

[source]
----
[standalone@localhost:9990 /] /subsystem=elytron/key-store=default-trust-store:add(type=JKS, relative-to=jboss.server.config.dir, path=application.truststore, credential-reference={clear-text=password})
----

In order to successfully execute the command above you must have a
*application.truststore* file inside your
*JBOSS_HOME/standalone/configuration* directory. Where the trust store
is protected by a password with a value *password*. The trust store must
contain the certificates associated with the load balancer or a
certificate chain in case the load balancer's certificate is signed by a
CA.

We strongly recommend you to avoid using self-signed certificates with
your load balancer. Ideally, certificates should be signed by a CA and
your trust store should contain a certificate chain representing your
ROOT and Intermediary CAs.

[[defining-a-trust-manager-to-validate-certificates]]
== Defining a Trust Manager To Validate Certificates

To define a trust manager in Elytron you can execute the following CLI
command:

[source]
----
[standalone@localhost:9990 /] /subsystem=elytron/trust-managers=default-trust-manager:add(algorithm=PKIX, key-store=default-trust-store)
----

Here we are setting the *default-trust-store* as the source of the
certificates that the application server trusts.

[[defining-a-client-ssl-context-and-configuring-mod_cluster-subsystem]]
== Defining a Client SSL Context and Configuring mod_cluster Subsystem

Finally, you can create the Client SSL Context that is going to be used
by the mod_cluster subsystem when connecting to the load balancer using
SSL/TLS:

[source]
----
[standalone@localhost:9990 /] /subsystem=elytron/client-ssl-context=modcluster-client-ssl-context:add(trust-managers=default-trust-manager)
----

Now that the Client `ssl-context` is defined you can configure
mod_cluster subsystem as follows:

[source]
----
[standalone@localhost:9990 /] /subsystem=modcluster/mod-cluster-config=configuration:write-attribute(name=ssl-context, value=modcluster-client-ssl-context)
----

Once you execute the last command above, reload the server:

[source]
----
[standalone@localhost:9990 /] reload
----

[[using-a-certificate-revocation-list]]
== Using a Certificate Revocation List

In case you want to validate the load balancer certificate against a
Certificate Revocation List (CRL), you can configure the `trust-manager`
in Elytron subsystem as follows:

[source]
----
[standalone@localhost:9990 /] /subsystem=elytron/trust-managers=default-trust-manager:write-attribute(name=certificate-revocation-list.path, value=intermediate.crl.pem)
----

To use a CRL your trust store must contain the certificate chain in
order to check validity of both CRL list and the load balancer`s
certificate.

A different way to configure a CRL is using the _Distribution Points_
embedded in your certificates. For that, you need to configure a
`certificate-revocation-list` as follows:

[source]
----
/subsystem=elytron/trust-managers=default-trust-manager:write-attribute(name=certificate-revocation-list)
----
<file_sep>/_docs/14/Developer_Guide.adoc
[[Developer_Guide]]
= Developer Guide
WildFly developer team;
:revnumber: {version}
:revdate: {localdate}
:toc: macro
:toclevels: 2
:toc-title: WildFly Developer guide
:doctype: book
:icons: font
:source-highlighter: coderay
:wildflyVersion: 14

ifndef::ebook-format[:leveloffset: 1]

(C) 2017 The original authors.

:numbered:


.Target Audience

Java Developers

:leveloffset: 1

include::_developer-guide/Class_Loading_in_WildFly.adoc[]

include::_developer-guide/Implicit_module_dependencies_for_deployments.adoc[]

include::_developer-guide/Deployment_Descriptors_used_In_WildFly.adoc[]

include::_developer-guide/Development_Guidelines_and_Recommended_Practices.adoc[]

include::_developer-guide/Application_Client_Reference.adoc[]

include::_developer-guide/Embedded_API.adoc[]

include::_developer-guide/CDI_Reference.adoc[]

include::_developer-guide/EE_Concurrency_Utilities.adoc[]

include::_developer-guide/EJB3_Reference_Guide.adoc[]

include::_developer-guide/JPA_Reference_Guide.adoc[]

include::_developer-guide/JNDI_Reference.adoc[]

include::_developer-guide/JAX-RS_Reference_Guide.adoc[]

include::_developer-guide/Web_(Undertow)_Reference_Guide.adoc[]

include::_developer-guide/JAX-WS_Reference_guide.adoc[]

include::_developer-guide/Scoped_EJB_client_contexts.adoc[]

include::_developer-guide/EJB_invocations_from_a_remote_client_using_JNDI.adoc[]

include::_developer-guide/EJB_invocations_from_a_remote_server_instance.adoc[]

include::_developer-guide/Remote_EJB_invocations_via_JNDI_-_EJB_client_API_or_remote-naming_project.adoc[]

include::_developer-guide/Migrated_to_WildFly_Example_Applications.adoc[]

include::_developer-guide/Spring_applications_development_and_migration_guide.adoc[]

include::_developer-guide/How_do_I_migrate_my_application_from_AS7_to_WildFly.adoc[]

include::_developer-guide/How_do_I_migrate_my_application_from_WebLogic_to_WildFly.adoc[]

include::_developer-guide/How_do_I_migrate_my_application_from_WebSphere_to_WildFly.adoc[]

<file_sep>/_docs/13/_developer-guide/JNDI_Remote_Reference.adoc
[[JNDI_Remote_Reference]]
== Remote JNDI Access

WildFly supports two different types of remote JNDI.

[[http-remoting]]
== http-remoting:

The `http-remoting:` protocol implementation is provided by JBoss Remote
Naming project, and uses http upgrade to lookup items from the servers
local JNDI. To use it, you must have the appropriate jars on the class
path, if you are maven user can be done simply by adding the following
to your `pom.xml` dependencies:

[source, xml]
----
<dependency>
  <groupId>org.wildfly</groupId>
  <artifactId>wildfly-ejb-client-bom</artifactId>
  <version>11.0.0.Final</version>
  <type>pom</type>
</dependency>
----

If you are not using maven a shaded jar that contains all required
classes +
can be found in the `bin/client` directory of WildFly's distribution.

[source, java]
----
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
// the property below is required ONLY if there is no ejb client configuration loaded (such as a
// jboss-ejb-client.properties in the class path) and the context will be used to lookup EJBs
env.put("jboss.naming.client.ejb.context", true);
InitialContext remoteContext = new InitialContext(env);
RemoteCalculator ejb = (RemoteCalculator) remoteContext.lookup("wildfly-http-remoting-ejb/CalculatorBean!"
                + RemoteCalculator.class.getName());
----

[IMPORTANT]

The http-remoting client assumes JNDI names in remote lookups are
relative to java:jboss/exported namespace, a lookup of an absolute JNDI
name will fail.

[[ejb]]
== ejb:

The ejb: namespace implementation is provided by the jboss-ejb-client
library, and allows the lookup of EJB's using their application name,
module name, ejb name and interface type. To use it, you must have the
appropriate jars on the class path, if you are maven user can be done
simply by adding the following to your `pom.xml` dependencies:

[source, xml]
----
<dependency>
  <groupId>org.wildfly</groupId>
  <artifactId>wildfly-ejb-client-bom</artifactId>
  <version>11.0.0.Final</version>
  <type>pom</type>
</dependency>
----

If you are not using maven a shaded jar that contains all required
classes +
can be found in the `bin/client` directory of WildFly's distribution.

This is a client side JNDI implementation. Instead of looking up an EJB
on the server the lookup name contains enough information for the client
side library to generate a proxy with the EJB information. When you
invoke a method on this proxy it will use the current EJB client context
to perform the invocation. If the current context does not have a
connection to a server with the specified EJB deployed then an error
will occur. Using this protocol it is possible to look up EJB's that do
not actually exist, and no error will be thrown until the proxy is
actually used. The exception to this is stateful session beans, which
need to connect to a server when they are created in order to create the
session bean instance on the server.

[source, java]
----
final Properties env = new Properties();
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext remoteContext = new InitialContext(env);
MyRemoteInterface myRemote = (MyRemoteInterface) remoteContext.lookup("ejb:myapp/myejbjar/MyEjbName\!com.test.MyRemoteInterface");
MyStatefulRemoteInterface myStatefulRemote = (MyStatefulRemoteInterface) remoteContext.lookup("ejb:myapp/myejbjar/MyStatefulName\!comp.test.MyStatefulRemoteInterface?stateful");
----

The first example is a lookup of a singleton, stateless or EJB 2.x home
interface. This lookup will not hit the server, instead a proxy will be
generated for the remote interface specified in the name. The second
example is for a stateful session bean, in this case the JNDI lookup
will hit the server, in order to tell the server to create the SFSB
session.

[IMPORTANT]

For more details on how the server connections are configured, including
the *required* jboss ejb client setup, please see
<<EJB_invocations_from_a_remote_client_using_JNDI,EJB invocations from a remote client using JNDI>>.
<file_sep>/_docs/13/_high-availability/ha-singleton/Singleton_deployments.adoc
[[Singleton_deployments]]
== Singleton deployments

WildFly 10 resurrected the ability to start a given deployment on a
single node in the cluster at any given time. If that node shuts down,
or fails, the application will automatically start on another node on
which the given deployment exists. Long time users of JBoss AS will
recognize this functionality as being akin to the
https://docs.jboss.org/jbossclustering/cluster_guide/5.1/html/deployment.chapt.html#d0e1220[HASingletonDeployer],
a.k.a. "
https://docs.jboss.org/jbossclustering/cluster_guide/5.1/html/deployment.chapt.html#d0e1220[deploy-hasingleton]",
feature of AS6 and earlier.

[[usage]]
== Usage

A deployment indicates that it should be deployed as a singleton via a
deployment descriptor. This can either be a standalone
`/META-INF/singleton-deployment.xml` file or embedded within an existing
jboss-all.xml descriptor. This descriptor may be applied to any
deployment type, e.g. JAR, WAR, EAR, etc., with the exception of a
subdeployment within an EAR. +
e.g.

[source, xml]
----
<singleton-deployment xmlns="urn:jboss:singleton-deployment:1.0" policy="foo"/>
----

The singleton deployment descriptor defines which
<<Singleton_subsystem,singleton policy>> should be used to deploy the
application. If undefined, the default singleton policy is used, as
defined by the singleton subsystem.

Using a standalone descriptor is often preferable, since it may be
overlaid onto an existing deployment archive. +
e.g.

[source]
----
deployment-overlay add --name=singleton-policy-foo --content=/META-INF/singleton-deployment.xml=/path/to/singleton-deployment.xml --deployments=my-app.jar --redeploy-affected
----
<file_sep>/_docs/13/_admin-guide/Core_management_concepts.adoc
[[Core_management_concepts]]
= Core management concepts
:toclevels: 2
:toc-title: Core management concepts
:toc: macro
:leveloffset: +1

:numbered:


include::Operating_modes.adoc[]

include::General_configuration_concepts.adoc[]

include::Management_resources.adoc[]

:leveloffset: -1
<file_sep>/_docs/13/_testsuite/Shortened_Maven_Run_Overview.adoc
[[Shortened_Maven_Run_Overview]]
== Shortened Maven Run Overview

[[how-to-get-it]]
== How to get it

[source, bash]
----
./integration-tests.sh clean install -DallTests | tee TS.txt | testsuite/tools/runSummary.sh
----

[[how-its-done]]
== How it's done

Run this script on the output of the AS7 testsuite run:

[source, bash]
----
##  Cat the file or stdin if no args,
##  filter only interesting lines - plugin executions and modules separators,
##  plus Test runs summaries,
##  and remove the boring plugins like enforcer etc.
 
cat $1 \
 | egrep ' --- |Building| ---------|Tests run: | T E S T S' \
 | grep -v 'Time elapsed'
 | sed 's|Tests run:|                Tests run:|' \
 | grep -v maven-clean-plugin \
 | grep -v maven-enforcer-plugin \
 | grep -v buildnumber-maven-plugin \
 | grep -v maven-help-plugin \
 | grep -v properties-maven-plugin:.*:write-project-properties \
;
----

You'll get an overview of the run.

[[example-output-with-comments.]]
== Example output with comments.

[source, bash]
----
ondra@ondra-redhat: ~/work/AS7/ozizka-as7 $  ./integration-tests.sh clean install -DallTests | tee TS.txt | testsuite/tools/runSummary.sh
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Aggregator 7.1.0.CR1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite ---
              Copies org.jboss.spec.javax.annotation:jboss-annotations-api_1.1_spec to ${project.build.directory}/endorsed .
              Inherited - needed for compilation of all submodules.
 
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite ---
              Copies ${jboss.home} to target/jbossas .  TODO: Should be jboss.dist.
 
[INFO] --- xml-maven-plugin:1.0:transform (update-ip-addresses-jbossas.server) @ jboss-as-testsuite ---
              Changes IP addresses used in server config files -
              applies ${xslt.scripts.dir}/changeIPAddresses.xsl on ${basedir}/target/jbossas/standalone/configuration/standalone-*.xml
              Currently inherited, IMO should not be.
 
[INFO] --- maven-source-plugin:2.1.2:jar-no-fork (attach-sources) @ jboss-as-testsuite ---
              TODO: Remove
 
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite ---
 
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Integration Aggregator 7.1.0.CR1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-agg ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-agg ---
              TODO: Remove
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas) @ jboss-as-testsuite-integration-agg ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas.groups) @ jboss-as-testsuite-integration-agg ---
[INFO] --- xml-maven-plugin:1.0:transform (update-ip-addresses-jbossas.server) @ jboss-as-testsuite-integration-agg ---
              TODO: Remove
[INFO] --- maven-source-plugin:2.1.2:jar-no-fork (attach-sources) @ jboss-as-testsuite-integration-agg ---
              TODO: Remove
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-integration-agg ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss AS Test Suite: Integration - Smoke 7.1.0.CR1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-integration-smoke ---
              TODO: Remove
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas.groups) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- xml-maven-plugin:1.0:transform (update-ip-addresses-jbossas.server) @ jboss-as-testsuite-integration-smoke ---
              TODO: Remove
 
[INFO] --- maven-antrun-plugin:1.6:run (build-smoke.server) @ jboss-as-testsuite-integration-smoke ---
     [echo] Building AS instance "smoke" from /home/ondra/work/EAP/EAP6-DR9 to /home/ondra/work/AS7/ozizka-as7/testsuite/integration/smoke/target
              TODO: Should be running one level above!
 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-surefire-plugin:2.10:test (smoke-full.surefire) @ jboss-as-testsuite-integration-smoke ---
 T E S T S
                Tests run: 4, Failures: 0, Errors: 4, Skipped: 0
----

[[example-output-unchanged]]
== Example output, unchanged

[source, bash]
----
ondra@lenovo:~/work/AS7/ozizka-git$ ./integration-tests.sh clean install -DallTests | tee TS.txt | testsuite/tools/runSummary.sh
SSCmeetingWestfordJan     [copy] Warning: /home/ondra/work/AS7/ozizka-git/testsuite/integration/src/test/resources/test-configs/smoke does not exist.
     [copy] Warning: /home/ondra/work/AS7/ozizka-git/testsuite/integration/src/test/resources/test-configs/clustering-udp-0 does not exist.
     [copy] Warning: /home/ondra/work/AS7/ozizka-git/testsuite/integration/src/test/resources/test-configs/clustering-udp-1 does not exist.
     [copy] Warning: /home/ondra/work/AS7/ozizka-git/testsuite/integration/src/test/resources/test-configs/iiop-client does not exist.
     [copy] Warning: /home/ondra/work/AS7/ozizka-git/testsuite/integration/src/test/resources/test-configs/iiop-server does not exist.
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Aggregator 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-antrun-plugin:1.6:run (banner) @ jboss-as-testsuite ---
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite ---
[INFO] --- xml-maven-plugin:1.0:transform (update-ip-addresses-jbossas.server) @ jboss-as-testsuite ---
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Integration 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-agg ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-agg ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas) @ jboss-as-testsuite-integration-agg ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas.groups) @ jboss-as-testsuite-integration-agg ---
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-integration-agg ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Integration - Smoke 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas.groups) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-antrun-plugin:1.6:run (build-smoke.server) @ jboss-as-testsuite-integration-smoke ---
     [echo] Building AS instance "smoke" from /home/ondra/work/AS7/ozizka-git/testsuite/integration/smoke/../../../build/target/jboss-as-7.1.0.Final-SNAPSHOT to /home/ondra/work/AS7/ozizka-git/testsuite/integration/smoke/target
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-integration-smoke ---
[INFO] --- maven-surefire-plugin:2.10:test (smoke-full.surefire) @ jboss-as-testsuite-integration-smoke ---
 T E S T S
                Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-surefire-plugin:2.10:test (smoke-web.surefire) @ jboss-as-testsuite-integration-smoke ---
 T E S T S
                Tests run: 116, Failures: 0, Errors: 0, Skipped: 6
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ jboss-as-testsuite-integration-smoke ---
[INFO] Building jar: /home/ondra/work/AS7/ozizka-git/testsuite/integration/smoke/target/jboss-as-testsuite-integration-smoke-7.1.0.Final-SNAPSHOT.jar
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-integration-smoke ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Integration - Basic 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas.groups) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-antrun-plugin:1.6:run (prepare-jars-basic-integration.server) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-integration-basic ---
[INFO] --- maven-surefire-plugin:2.10:test (basic-integration-default-full.surefire) @ jboss-as-testsuite-integration-basic ---
 T E S T S
                Tests run: 323, Failures: 0, Errors: 4, Skipped: 30
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Integration - Clustering 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-clust ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-integration-clust ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-integration-clust ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-clust ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas.groups) @ jboss-as-testsuite-integration-clust ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-integration-clust ---
[INFO] --- maven-antrun-plugin:1.6:run (build-clustering.server) @ jboss-as-testsuite-integration-clust ---
     [echo] Building config clustering-udp-0
     [echo] Building AS instance "clustering-udp-0" from /home/ondra/work/AS7/ozizka-git/testsuite/integration/clust/../../../build/target/jboss-as-7.1.0.Final-SNAPSHOT to /home/ondra/work/AS7/ozizka-git/testsuite/integration/clust/target
     [echo] Building config clustering-udp-1
     [echo] Building AS instance "clustering-udp-1" from /home/ondra/work/AS7/ozizka-git/testsuite/integration/clust/../../../build/target/jboss-as-7.1.0.Final-SNAPSHOT to /home/ondra/work/AS7/ozizka-git/testsuite/integration/clust/target
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-integration-clust ---
[INFO] --- maven-surefire-plugin:2.10:test (tests-clustering-multi-node-unmanaged.surefire) @ jboss-as-testsuite-integration-clust ---
 T E S T S
                Tests run: 9, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-surefire-plugin:2.10:test (tests-clustering-single-node.surefire) @ jboss-as-testsuite-integration-clust ---
 T E S T S
                Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-surefire-plugin:2.10:test (tests-clustering-multi-node.surefire) @ jboss-as-testsuite-integration-clust ---
 T E S T S
                Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ jboss-as-testsuite-integration-clust ---
[INFO] Building jar: /home/ondra/work/AS7/ozizka-git/testsuite/integration/clust/target/jboss-as-testsuite-integration-clust-7.1.0.Final-SNAPSHOT.jar
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-integration-clust ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Integration - IIOP 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-iiop ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-integration-iiop ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-integration-iiop ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-iiop ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (ts.copy-jbossas.groups) @ jboss-as-testsuite-integration-iiop ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-integration-iiop ---
[INFO] --- maven-antrun-plugin:1.6:run (build-clustering.server) @ jboss-as-testsuite-integration-iiop ---
     [echo] Building config iiop-client
     [echo] Building AS instance "iiop-client" from /home/ondra/work/AS7/ozizka-git/testsuite/integration/iiop/../../../build/target/jboss-as-7.1.0.Final-SNAPSHOT to /home/ondra/work/AS7/ozizka-git/testsuite/integration/iiop/target
     [echo] Building config iiop-server
     [echo] Building AS instance "iiop-server" from /home/ondra/work/AS7/ozizka-git/testsuite/integration/iiop/../../../build/target/jboss-as-7.1.0.Final-SNAPSHOT to /home/ondra/work/AS7/ozizka-git/testsuite/integration/iiop/target
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-integration-iiop ---
[INFO] --- maven-surefire-plugin:2.10:test (tests-iiop-multi-node.surefire) @ jboss-as-testsuite-integration-iiop ---
 T E S T S
                Tests run: 12, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ jboss-as-testsuite-integration-iiop ---
[INFO] Building jar: /home/ondra/work/AS7/ozizka-git/testsuite/integration/iiop/target/jboss-as-testsuite-integration-iiop-7.1.0.Final-SNAPSHOT.jar
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-integration-iiop ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Compatibility Tests 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-compat ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-integration-compat ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-integration-compat ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-compat ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-integration-compat ---
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-integration-compat ---
[INFO] --- maven-antrun-plugin:1.6:run (build-jars) @ jboss-as-testsuite-integration-compat ---
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ jboss-as-testsuite-integration-compat ---
 T E S T S
                Tests run: 7, Failures: 0, Errors: 4, Skipped: 3
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Domain Mode Integration Tests 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-integration-domain ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-integration-domain ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-integration-domain ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-integration-domain ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-integration-domain ---
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-integration-domain ---
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ jboss-as-testsuite-integration-domain ---
 T E S T S
                Tests run: 89, Failures: 0, Errors: 0, Skipped: 4
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ jboss-as-testsuite-integration-domain ---
[INFO] Building jar: /home/ondra/work/AS7/ozizka-git/testsuite/domain/target/jboss-as-testsuite-integration-domain-7.1.0.Final-SNAPSHOT.jar
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-integration-domain ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Benchmark Tests 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-benchmark ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-benchmark ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-benchmark ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-benchmark ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-benchmark ---
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-benchmark ---
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ jboss-as-testsuite-benchmark ---
 T E S T S
                Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ jboss-as-testsuite-benchmark ---
[INFO] Building jar: /home/ondra/work/AS7/ozizka-git/testsuite/benchmark/target/jboss-as-testsuite-benchmark-7.1.0.Final-SNAPSHOT.jar
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-benchmark ---
[INFO] ------------------------------------------------------------------------
[INFO] Building JBoss Application Server Test Suite: Stress Tests 7.1.0.Final-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (copy-annotations-endorsed) @ jboss-as-testsuite-stress ---
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ jboss-as-testsuite-stress ---
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ jboss-as-testsuite-stress ---
[INFO] --- maven-resources-plugin:2.5:copy-resources (build-jbossas.server) @ jboss-as-testsuite-stress ---
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ jboss-as-testsuite-stress ---
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ jboss-as-testsuite-stress ---
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ jboss-as-testsuite-stress ---
 T E S T S
                Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ jboss-as-testsuite-stress ---
[INFO] Building jar: /home/ondra/work/AS7/ozizka-git/testsuite/stress/target/jboss-as-testsuite-stress-7.1.0.Final-SNAPSHOT.jar
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ jboss-as-testsuite-stress ---
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
----
<file_sep>/_docs/13/_developer-guide/wsprovide.adoc
[[wsprovide]]
== wsprovide

_wsprovide_ is a command line tool, Maven plugin and Ant task that
generates portable JAX-WS artifacts for a service endpoint
implementation. It also has the option to "provide" the abstract
contract for offline usage.

[[command-line-tool]]
== Command Line Tool

The command line tool has the following usage:

....
usage: wsprovide [options] <endpoint class name>
options:
  -h, --help                  Show this help message
  -k, --keep                  Keep/Generate Java source
  -w, --wsdl                  Enable WSDL file generation
  -a, --address The generated port soap:address in wsdl
  -c. --classpath=<path>      The classpath that contains the endpoint
  -o, --output=<directory>    The directory to put generated artifacts
  -r, --resource=<directory>  The directory to put resource artifacts
  -s, --source=<directory>    The directory to put Java source
  -e, --extension             Enable SOAP 1.2 binding extension
  -q, --quiet                 Be somewhat more quiet
  -t, --show-traces           Show full exception stack traces
....

[[examples]]
=== Examples

Generating wrapper classes for portable artifacts in the "generated"
directory:

....
wsprovide -o generated foo.Endpoint
....

Generating wrapper classes and WSDL in the "generated" directory

....
wsprovide -o generated -w foo.Endpoint
....

Using an endpoint that references other jars

....
wsprovide -o generated -c application1.jar:application2.jar foo.Endpoint
....

[[maven-plugin]]
== Maven Plugin

The _wsprovide_ tools is included in the
*org.jboss.ws.plugins:jaxws-tools-* *maven-* *plugin* plugin. The plugin
has two goals for running the tool, _wsprovide_ and _wsprovide-test_,
which basically do the same during different Maven build phases (the
former triggers the sources generation during _process-classes_ phase,
the latter during the _process-test-classes_ one).

The _wsprovide_ plugin has the following parameters:

[cols=",,",options="header"]
|=======================================================================
|Attribute |Description |Default

|testClasspathElements |Each classpathElement provides alibrary file to
be added to classpath
|$\{project.compileClasspathElements}or$\{project.testClasspathElements}

|outputDirectory |The output directory for generated artifacts.
|$\{project.build.outputDirectory}or$\{project.build.testOutputDirectory}

|resourceDirectory |The output directory for resource artifacts
(WSDL/XSD). |$\{project.build.directory}/wsprovide/resources

|sourceDirectory |The output directory for Java source.
|$\{project.build.directory}/wsprovide/java

|extension |Enable SOAP 1.2 binding extension. |false

|generateWsdl |Whether or not to generate WSDL. |false

|verbose |Enables more informational output about command progress.
|false

|portSoapAddress |The generated port soap:address in the WSDL | 

|endpointClass |Service Endpoint Implementation. | 
|=======================================================================

[[examples-1]]
=== Examples

You can use _wsprovide_ in your own project build simply referencing the
_maven-jaxws-tools-plugin_ in the configured plugins in your _pom.xml_
file.

The following example makes the plugin provide the wsdl file and
artifact sources for the specified endpoint class:

[source,xml]
----
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Beta1</version>
      <configuration>
        <verbose>true</verbose>
        <endpointClass>org.jboss.test.ws.plugins.tools.wsprovide.TestEndpoint</endpointClass>
        <generateWsdl>true</generateWsdl>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsprovide</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
----

The following example does the same, but is meant for use in your own
testsuite:

[source,xml]
----
<build>
  <plugins>
    <plugin>
      <groupId>org.jboss.ws.plugins</groupId>
      <artifactId>jaxws-tools-maven-plugin</artifactId>
      <version>1.2.0.Beta1</version>
      <configuration>
        <verbose>true</verbose>
        <endpointClass>org.jboss.test.ws.plugins.tools.wsprovide.TestEndpoint2</endpointClass>
        <generateWsdl>true</generateWsdl>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>wsprovide-test</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
----

Plugin stack dependencyThe plugin itself does not have an explicit
dependency to a JBossWS stack, as it's meant for being used with
implementations of any supported version of the _JBossWS SPI_. So the
user is expected to set a dependency in his own `pom.xml` to the desired
_JBossWS_ stack version. The plugin will rely on the that for using the
proper tooling.

[source,xml]
----
<dependencies>
  <dependency>
    <groupId>org.jboss.ws.cxf</groupId>
    <artifactId>jbossws-cxf-client</artifactId>
    <version>5.0.0.CR1</version>
  </dependency>
</dependencies>
----

[TIP]

Be careful when using this plugin with the Maven War Plugin as that
include any project dependency into the generated application war
archive. You might want to set `<scope>provided</scope>` for the
_JBossWS_ stack dependency to avoid that.

[IMPORTANT]

Up to version 1.1.2.Final, the _artifactId_ of the plugin was
*maven-jaxws-tools-plugin*.

[[ant-task]]
== Ant Task

The wsprovide ant task ( _org.jboss.ws.tools.ant.WSProvideTask_) has the
following attributes:

[cols=",,",options="header"]
|=======================================================================
|Attribute |Description |Default

|fork |Whether or not to run the generation task in a separate VM. |true

|keep |Keep/Enable Java source code generation. |false

|destdir |The output directory for generated artifacts. |"output"

|resourcedestdir |The output directory for resource artifacts
(WSDL/XSD). |value of destdir

|sourcedestdir |The output directory for Java source. |value of destdir

|extension |Enable SOAP 1.2 binding extension. |false

|genwsdl |Whether or not to generate WSDL. |false

|address |The generated port soap:address in wsdl. | 

|verbose |Enables more informational output about command progress.
|false

|sei |Service Endpoint Implementation. | 

|classpath |The classpath that contains the service endpoint
implementation. |"."
|=======================================================================

[[examples-2]]
=== Examples

Executing wsprovide in verbose mode with separate output directories for
source, resources, and classes:

[source,xml]
----
<target name="test-wsproivde" depends="init">
  <taskdef name="wsprovide" classname="org.jboss.ws.tools.ant.WSProvideTask">
    <classpath refid="core.classpath"/>
  </taskdef>
  <wsprovide
    fork="false"
    keep="true"
    destdir="out"
    resourcedestdir="out-resource"
    sourcedestdir="out-source"
    genwsdl="true"
    verbose="true"
    sei="org.jboss.test.ws.jaxws.jsr181.soapbinding.DocWrappedServiceImpl">
    <classpath>
      <pathelement path="${tests.output.dir}/classes"/>
    </classpath>
  </wsprovide>
</target>
----
<file_sep>/_docs/14/_testsuite/WildFly_Integration_Testsuite_User_Guide.adoc
[[WildFly_Integration_Testsuite_User_Guide]]
= Wild**Fly** Integration Testsuite User Guide

*See also:* <<WildFly_Testsuite_Test_Developer_Guide,WildFly
Testsuite Test Developer Guide>>

*Target Audience:* Those interested in running the testsuite or a subset
thereof, with various configuration options.

[[running-the-testsuite]]
== Running the testsuite

The tests can be run using:

* `build.sh` or `build.bat`, as a part of WildFly build.
** By default, only smoke tests are run. To run all tests, run build.sh
install -DallTests.
* `integration-tests.sh` or `integration-tests.bat`, a convenience
script which uses bundled Maven (currently 3.0.3), and runs all parent
testsuite modules (which configure the AS server).
* pure maven run, using `mvn install`.

The scripts are wrappers around Maven-based build. Their arguments are
passed to Maven (with few exceptions described below). This means you
can use:

* build.sh (defaults to install)
* build.sh install
* build.sh clean install
* integration-tests.sh install
* ...etc.

[[supported-maven-phases]]
=== Supported Maven phases

Testsuite actions are bounds to various Maven phases up to `verify`.
Running the build with earlier ﻿phases may fail in the submodules due to
missed configuration steps. Therefore, the only Maven phases you may
safely run, are:

* clean
* install
* site

The `test` phase is not recommended to be used for scripted jobs as we
are planning to switch to the `failsafe` plugin bound to the
`integration-test` and `verify` phases. See
https://issues.jboss.org/browse/WFLY-625[WFLY-625] and
https://issues.jboss.org/browse/WFLY-228[WFLY-228].

[[testsuite-structure]]
=== Testsuite structure

testsuite +
integration +
smoke +
basic +
clust +
iiop +
multinode +
xts +
compat +
domain +
mixed-domain +
stress +
benchmark

[[test-groups]]
=== Test groups

To define groups of tests to be run, these properties are available:

* `-DallTests` - Runs all subgroups.
* `-DallInteg` - Runs all integration tests. Same as
`cd testsuite/integration; mvn clean install -DallTests`
* `-Dts.integ` - Basic integration + clustering tests.
* `-Dts.clust` - Clustering tests.
* `-Dts.iiop` - IIOP tests.
* `-Dts.multinode `- Tests with many nodes.
* `-Dts.manualmode` - Tests with manual mode Arquillian containers.
* `-Dts.bench` - Benchmark tests.
* `-Dts.stress` - Stress tests.
* `-Dts.domain` - Domain mode tests.
* `-Dts.compat` - Compatibility tests.

[[examples]]
== Examples

* `integration-tests.sh [install] ` `` `-- Runs smoke tests.`
* `integration-tests.sh clean install -- Cleans the target directory, then runs smoke tests.`
* `integration-tests.sh install -Dts.smoke ` `` `-- Same as above.`
* `integration-tests.sh install -DallTests ` ``
`-- Runs all testsuite tests.`
* `integration-tests.sh install -Dts.stress -- Runs smoke tests and stress tests.`
* `integration-tests.sh install -Dts.stress -Dts.noSmoke -- Runs stress tests only.`

*Pure maven* - if you prefer not to use scripts, you may achieve the
same result with:

* `mvn ... -rf testsuite`

The `-rf ...` parameter stands for "resume from" and causes Maven to run
the specified module _and all successive_.

It's possible to run only a single module (provided the ancestor modules
were already run to create the AS copies) :

* `mvn ... -pl testsuite/integration/cluster`

The `-pl ...` parameter stands for "project list" and causes Maven to
run the specified module _only_.

[[output-to-console]]
=== Output to console

[source, java]
----
-DtestLogToFile
----

[[other-options]]
=== Other options

`-DnoWebProfile` - Run all tests with the _full_ profile (
`standalone-full.xml`). By default, most tests are run under _web_
profile ( `standalone.xml`).

`-Dts.skipTests` - Skip testsuite's tests. Defaults to the value of
`-DskipTests`, which defaults to `false`. To build AS, skip unit tests
and run testsuite, use `-DskipTests -Dts.skipTests=false`.

[[timeouts]]
=== Timeouts

[[surefire-execution-timeout]]
==== Surefire execution timeout

Unfortunatelly, no math can be done in Maven, so instead of applying a
timeout ratio, you need to specify timeout manually for Surefire.

[source, java]
----
-Dsurefire.forked.process.timeout=900
----

[[in-test-timeout-ratios]]
==== In-test timeout ratios

Ratio in prercent - 100 = default, 200 = two times longer timeouts for
given category.

Currently we have five different ratios. Later, it could be replaced
with just one generic, one for database and one for deployment
operations.

[source, java]
----
-Dtimeout.ratio.fsio=100
-Dtimeout.ratio.netio=100
-Dtimeout.ratio.memio=100
-Dtimeout.ratio.proc=100
-Dtimeout.ratio.db=100
----

[[running-a-single-test-or-specified-tests]]
=== Running a single test (or specified tests)

Single test is run using *-Dtest=...* . Examples:

* `./integration-tests.sh install -Dtest='` `*` `Clustered` `*`
`' -Dintegration.module` `-Dts.clust`
* `./integration-tests.sh clean install -Dtest=org` `/` `jboss` `/` `as`
`/` `test` `/` `integration` `/` `ejb/async/*TestCase.java`
`-Dintegration.module` `-Dts.basic`
* `cd testsuite; mvn install` `-Dtest='` `*Clustered` `*` `'`
`-Dts.basic #`
`No need for -Dintegration.module - integration module is active by default.`

The same shortcuts listed in "Test groups" may be used to activate the
module and group profile.

Note that `-Dtest=` overrides `<includes>` and `<exludes>` defined in
pom.xml, so do not rely on them when using wildcards - all compiled test
classes matching the wildcard will be run.

*Which Surefire execution is used?*

Due to Surefire's design flaw, tests run multiple times if there are
multiple surefire executions. +
To prevent this, if `-Dtest=`... is specified, non-default executions
are disabled, and standalone-full is used for all tests. +
If you need it other way, you can overcome that need:

* `basic-integration-web.surefire with standalone.xml - Configure standalone.xml to be used as server config.`
* `basic-integration-non-web.surefire - For tests included here, technically nothing changes.`
* `basic-integration-2nd.surefire - Simply run the second test in another invocation of Maven.`

[[running-against-existing-as-copy-not-the-one-from-buildtargetjboss-as-]]
=== Running against existing AS copy (not the one from
build/target/jboss-as-*)

*-Djboss.dist=<path/to/jboss-as>* will tell the testsuite to copy that
AS into submodules to run the tests against.

For example, you might want to run the testsuite against AS located in
`/opt/wildfly-8` :

[source, java]
----
./integration-tests.sh -DallTests -Djboss.dist=/opt/wildfly-8
----

The difference between jboss.dist and jboss.home:

jboss.dist is the location of the tested binaries. It gets copied to
testsuite submodules.

jboss.home is internally used and points to those copied AS instances
(for multinode tests, may be even different for each AS started by
Arquillian).

[[running-against-a-running-jboss-as-instance]]
==== Running against a running JBoss AS instance

Arquillian's WildFly {wildflyVersion} container adapter allows specifying
`allowConnectingToRunningServer` in `arquillian.xml`, which makes it
check whether AS is listening at `managementAddress:managementPort`, and
if so, it uses that server instead of launching a new one, and doesn't
shut it down at the end.

All arquillian.xml's in the testsuite specify this parameter. Thus, if
you have a server already running, it will be re-used.

[[running-against-jboss-enterprise-application-platform-eap-6.0]]
==== Running against JBoss Enterprise Application Platform (EAP) 6.0

To run the testsuite against AS included JBoss Enterprise Application
Platform 6.x (EAP), special steps are needed.

Assuming you already have the sources available, and the distributed EAP
maven repository unzipped in e.g. `/opt/jboss/eap6-maven-repo/` :

1) Configure maven in settings.xml to use only the EAP repository. This
repo contains all artifacts necessary for building EAP, including maven
plugins. +
The build (unlike running testsuite) may be done offline. +
The recommended way of configuring is to use special settings.xml, not
your local one (typically in .m2/settings.xml).

[source, xml]
----
   <mirror>
      <id>eap6-mirror-setting</id>
      <mirrorOf>
         *,!central-eap6,!central-eap6-plugins,!jboss-public-eap6,!jboss-public-eap6-plugins
      </mirrorOf>
      <name>Mirror Settings for EAP 6 build</name>
      <url>file:///opt/jboss/eap6-maven-repo</url>
    </mirror>
  </mirrors>
----

\2) Build EAP. You won't use the resulting EAP build, though. The
purpose is to get the artifacts which the testsuite depends on.

[source, java]
----
mvn clean install -s settings.xml -Dmaven.repo.local=local-repo-eap
----

\3) Run the testsuite. Assuming that EAP is located in `/opt/eap6`, you
would run:

[source, java]
----
./integration-tests.sh -DallTests -Djboss.dist=/opt/eap6
----

For further information on building EAP and running the testsuite
against it, see the official EAP documentation (link to be added)
https://docspace.corp.redhat.com/docs/DOC-86875[.]

How-to for EAP QA can be found
https://docspace.corp.redhat.com/docs/DOC-89200[here] (Red Hat internal
only).

[[running-with-a-debugger]]
=== Running with a debugger

[cols=",,,",options="header"]
|=======================================================================
|Argument |What will start with debugger |Default port |Port change arg.

|-Ddebug |AS instances run by Arquillian |8787 |-Das.debug.port=...

|-Djpda |alias for -Ddebug |  | 

|-DdebugClient |Test JVMs (currently Surefire) |5050
|-Ddebug.port.surefire=...

|-DdebugCLI |AS CLI |5051 |-Ddebug.port.cli=...
|=======================================================================

[[examples-1]]
==== Examples

[source, java]
----
./integration-tests.sh install -DdebugClient -Ddebug.port.surefire=4040
 
...
 
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Listening for transport dt_socket at address: 4040
----

[source, bash]
----
./integration-tests.sh install -DdebugClient -Ddebug.port.surefire
 
...
 
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Listening for transport dt_socket at address: 5050
----

[source, java]
----
./integration-tests.sh install -Ddebug
----

[source, java]
----
./integration-tests.sh install -Ddebug -Das.debug.port=5005
----

[IMPORTANT]

JBoss AS is started by Arquillian, when the first test which requires
given instance is run. Unless you pass *-DtestLogToFile=false,* *there's
(currently) no challenge text in the console*; it will look like the
first test is stuck. This is being solved in
http://jira.codehaus.org/browse/SUREFIRE-781.

[IMPORTANT]

Depending on which test group(s) you run, multiple AS instances may be
started. In that case, you need to attach the debugger multiple times.

[[running-tests-with-custom-database]]
=== Running tests with custom database

To run with different database, specify the `-Dds` and use these
properties (with the following defaults):

[source, java]
----
-Dds.jdbc.driver=
-Dds.jdbc.driver.version=
-Dds.jdbc.url=
-Dds.jdbc.user=test
-Dds.jdbc.pass=<PASSWORD>
-Dds.jdbc.driver.jar=${ds.db}-jdbc-driver.jar
----

`driver` is JDBC driver class. JDBC `url`, `user` and `pass` is as
expected.

`driver.version` is used for automated JDBC driver downloading. Users
can set up internal Maven repository hosting JDBC drivers, with
artifacts with

GAV = `jdbcdrivers:${ds.db}:${ds.jdbc.driver.version`}

Internally, JBoss has such repo at
http://nexus.qa.jboss.com:8081/nexus/content/repositories/thirdparty/jdbcdrivers/
.

The `ds.db` value is set depending on ds. E.g. `-Dds=mssql2005` sets
`ds.db=mssql` (since they have the same driver). `-Dds.db` may be
overriden to use different driver.

[line-through]*In case you don't want to use such driver, set just
-Dds.db= (empty) and provide the driver to the AS manually.* +
_Not supported; work in progress on parameter to provide JDBC Driver
jar._

[[default-values]]
==== Default values

For WildFly continuous integration, there are some predefined values for
some of databases, which can be set using:

[source, java]
----
-Dds.db=<database-identifier>
----

Where database-identifier is one of: `h2`, `mysql51`

[[running-tests-with-ipv6]]
=== Running tests with IPv6

`-Dipv6` - Runs AS with
`-Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true`

and the following defaults, overridable by respective parameter:

[cols=",,,",options="header"]
|=======================================================================
|Parameter |IPv4 default |IPv6 default | 

|-Dnode0 |127.0.0.1 |::1 |Single-node tests.

|-Dnode1 |127.0.0.1 |::1 |Two-node tests (e.g. cluster) use this for the
2nd node.

|-Dmcast |192.168.3.11 |fd00:c2b6:b24b:be67:2827:688d:e6a1:6a3b |fd00:c2b6:b24b:be67:2827:688d:e6a1:6a3b is IPv6 Node-Local scope mcast
addr.

|-Dmcast.jgroupsDiag |192.168.3.11 |fdf8:f53e:61e4::18 |JGroups diagnostics
multicast address.

|-Dmcast.modcluster |172.16.31.10 |fc00:e968:6179::de52:7100 |mod_cluster multicast
address.
|=======================================================================

Values are set in AS configuration XML, replaced in resources (like
ejb-jar.xml) and used in tests.

[[running-tests-with-security-manager-custom-security-policy]]
=== Running tests with security manager / custom security policy

`-Dsecurity.manager` - Run with default policy.

`-Dsecurity.policy=<path>` - Run with the given policy.

`-Dsecurity.manager.other=<set of Java properties>` - Run with the given
properties. Whole set is included in all server startup parameters.

Example:

[source, java]
----
./integration-tests.sh clean install -Dintegration.module -DallTests \
\"-Dsecurity.manager.other=-Djava.security.manager \
-Djava.security.policy==$(pwd)/testsuite/shared/src/main/resources/secman/permitt_all.policy \
-Djava.security.debug=access:failure \"
----

Notice the \" quotes delimiting the whole `-Dsecurity.manager.other`
property.

[[creating-test-reports]]
=== Creating test reports

Test reports are created in the form known from EAP 5. To create them,
simply run the testsuite, which will create Surefire XML files.

Creation of the reports is bound to the `site` Maven phase, so it must
be run separatedly afterwards. Use one of these:

[source, bash]
----
./integration-tests.sh site
cd testsuite; mvn site
mvn -pl testsuite site
----

Note that it will take all test results under `testsuite/integration/` -
the pattern is `**/*TestCase.xml`, without need to specify `-DallTests`.

[[creating-coverage-reports]]
=== Creating coverage reports

*Jira:* https://issues.jboss.org/browse/WFLY-585

Coverage reports are created by
http://www.eclemma.org/jacoco/trunk/index.html[JaCoCo].

During the integration tests, Arquillian is passed a JVM argument which
makes it run with JaCoCo agent, which records the executions into
`${basedir}/target/jacoco` .

In the `site` phase, a HTML, XML and CSV reports are generated. That is
done using `jacoco:report` Ant task in `maven-ant-plugin` since JaCoCo's
maven report goal doesn't support getting classes outside
target/classes.

[[usage]]
==== Usage

[source, bash]
----
./build.sh clean install -DskipTests
./integration-tests.sh clean install -DallTests -Dcoverage
./integration-tests.sh site -DallTests -Dcoverage ## Must run in separatedly.
----

Alternative:

[source, bash]
----
mvn clean install -DskipTests
mvn -rf testsuite clean install -DallTests -Dcoverage
mvn -rf testsuite site -DallTests -Dcoverage
----

[[cleaning-the-project]]
=== Cleaning the project

To have most stable build process, it should start with:

* clean target directories
* only central Maven repo configured
* clean local repository or at least:
** free of artefacts to be built
** free of dependencies to be used (especially snapshots)

To use , you may use these commands:

[source, java]
----
mvn clean install -DskipTests -DallTests  ## ...to clean all testsuite modules.
mvn dependency:purge-local-repository build-helper:remove-project-artifact -Dbuildhelper.removeAll
----

In case the build happens in a shared environment (e.g. network disk),
it's recommended to use local repository:

[source, java]
----
cp /home/hudson/.m2/settings.xml .
sed "s|<settings>|<settings><localRepository>/home/ozizka/hudson-repos/$JOBNAME</localRepository>|" -i settings.xml
----

Or:

[source, java]
----
mvn clean install ... -Dmaven.repo.local=localrepo
----

See also https://issues.jboss.org/browse/WFLY-628.
<file_sep>/_docs/13/Client_Guide.adoc
[[Client_Guide]]
= Wild**Fly** Client Configuration
:revnumber: {version}
:revdate: {localdate}
:toc: macro
:toclevels: 2
:toc-title: WildFly Client Configuration Guide
:doctype: book
:icons: font
:source-highlighter: coderay
:wildflyVersion: 13
:numbered:

ifndef::ebook-format[:leveloffset: 1]

:leveloffset: 0


== Introduction

As of Wild**Fly** 11 a common configuration framework has been introduced for use by the client libraries to define configuration, this allows for the configuration to be shared across multiple clients rather than relying on their own configuration files.  As an example the configuration used by an EJB client can be shared with the JBoss CLI, if both of these required SSL configuration this can now be defined once and re-used.

Programmatic APIs are also available for many of the options however this document is focusing on the configuration available within the common `wildfly-config.xml` configuration file.

== wildfly-config.xml Discovery

At the time a client requires access to its configuration, the class path is scanned for a `wildfly-config.xml` or `META-INF/wildfly-config.xml` file. Once the file is located the configuration will be parsed to be made available for that client.


Alternatively, the `wildfly.config.url` system property can also be specified to identify the location of the configuration that should be used.

== Configuration Sections

:leveloffset: +2

include::_client-guide/authentication-client.adoc[]

include::_client-guide/jboss-ejb-client.adoc[]

include::_client-guide/Remoting_Client_Configuration.adoc[]

include::_client-guide/XNIO_Client_Configuration.adoc[]

:leveloffset: -2
<file_sep>/_docs/13/_developer-guide/Migrate_Order_Application_from_EAP5.1_to_WildFly.adoc
[[Migrate_Order_Application_from_EAP5]]
== Porting the Order Application from EAP 5.1 to WildFly {wildflyVersion}

<NAME> ported an example Order application that was used for
performance testing from EAP 5.1 to WildFly {wildflyVersion}. These are the notes he
made during the migration process.

[[overview-of-the-application]]
== Overview of the application

The application is relatively simple. it contains three servlets, some
stateless session beans, a stateful session bean, and some entities.

In addition to application code changes, modifications were made to the
way the EAR was packaged. This is because WildFly removed support of
some proprietary features that were available in EAP 5.1.

[[summary-of-changes]]
== Summary of changes

[[code-changes]]
=== Code Changes

[[modify-jndi-lookup-code]]
==== Modify JNDI lookup code

Since this application was first written for EAP 4.2/4.3, which did not
support EJB reference injection, the servlets were using pre-EE 5
methods for looking up stateless and stateful session bean interfaces.
While migrating to WildFly, it seemed a good time to change the code to
use the @EJB annotation, although this was not a required change.

The real difference is in the lookup name. WildFly only supports the new
EE 6 portable JNDI names rather than the old EAR structure based names.
The JNDI lookup code changed as follows:

Example of code in the EAP 5.1 version:

[source, java]
----
try {
    context = new InitialContext();
    distributionCenterManager = (DistributionCenterManager) context.lookup("OrderManagerApp/DistributionCenterManagerBean/local");
} catch(Exception lookupError) {
    throw new ServletException("Couldn't find DistributionCenterManager bean", lookupError);
}
try {
    customerManager = (CustomerManager) context.lookup("OrderManagerApp/CustomerManagerBean/local");
} catch(Exception lookupError) {
    throw new ServletException("Couldn't find CustomerManager bean", lookupError);
}
 
try {
    productManager = (ProductManager) context.lookup("OrderManagerApp/ProductManagerBean/local");
} catch(Exception lookupError) {
    throw new ServletException("Couldn't find the ProductManager bean", lookupError);
}
----

Example of how this is now coded in WildFly:

[source, java]
----
@EJB(lookup="java:app/OrderManagerEJB/DistributionCenterManagerBean!services.ejb.DistributionCenterManager")
private DistributionCenterManager distributionCenterManager;
 
@EJB(lookup="java:app/OrderManagerEJB/CustomerManagerBean!services.ejb.CustomerManager")
private CustomerManager customerManager;
 
@EJB(lookup="java:app/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager")
private ProductManager productManager;
----

In addition to the change to injection, which was supported in EAP
5.1.0, the lookup name changed from:

[source, java]
----
OrderManagerApp/DistributionCenterManagerBean/local
----

to:

[source, java]
----
java:app/OrderManagerEJB/DistributionCenterManagerBean!services.ejb.DistributionCenterManager
----

All the other beans were changed in a similar manner. They are now based
on the portable JNDI names described in EE 6.

[[modify-logging-code]]
=== Modify logging code

The next major change was to logging within the application. The old
version was using the commons logging infrastructure and Log4J that is
bundled in the application server. Rather than bundling third-party
logging, the application was modified to use the new WildFly Logging
infrastructure.

The code changes themselves are rather trivial, as this example
illustrates:

Old JBoss Commons Logging/Log4J:

[source, java]
----
private static Log log = LogFactory.getLog(CustomerManagerBean.class);
----

New WildFly Logging

[source, java]
----
private static Logger logger = Logger.getLogger(CustomerManagerBean.class.toString());
----

Old JBoss Commons Logging/Log4J:

[source, java]
----
if(log.isTraceEnabled()) {
    log.trace("Just flushed " + batchSize + " rows to the database.");
    log.trace("Total rows flushed is " + (i+1));
}
----

New WildFly Logging:

[source, java]
----
if(logger.isLoggable(Level.TRACE)) {
    logger.log(Level.TRACE, "Just flushed " + batchSize + " rows to the database.");
    logger.log(Level.TRACE, "Total rows flushed is " + (i+1));
}
----

In addition to the code changes made to use the new AS7 JBoss log
manager module, you must add this dependency to the `MANIFEST.MF` file
as follows:

[source, java]
----
Manifest-Version: 1.0
Dependencies: org.jboss.logmanager
----

[[modify-the-code-to-use-infinispan-for-2nd-level-cache]]
=== Modify the code to use Infinispan for 2nd level cache

Jboss Cache has been replaced by Infinispan for 2nd level cache. This
requires modification of the `persistence.xml` file.

This is what the file looked like in EAP 5.1:

[source, java]
----
<properties>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/>
<property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="false"/>
<property name="hibernate.cache.use_minimal_puts" value="true"/>
<property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/>
<property name="hibernate.cache.region_prefix" value="services"/>
</properties>
----

This is how it was modified to use Infinispan for the same
configuration:

[source, java]
----
<properties>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_minimal_puts" value="true"/>
</properties>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
----

Most of the properties are removed since they will default to the
correct values for the second level cache. See
https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide#JPAReferenceGuide-UsingtheInfinispansecondlevelcache["Using
the Infinispan second level cache"] for more details.

That was the extent of the code changes required to migrate the
application to AS7.

[[ear-packaging-changes]]
=== EAR Packaging Changes

Due to modular class loading changes, the structure of the existing EAR
failed to deploy successfully in WildFly.

The old structure of the EAR was as follows:

[source, java]
----
$ jar tf OrderManagerApp.ear
META-INF/MANIFEST.MF
META-INF/application.xml
OrderManagerWeb.war
OrderManagerEntities.jar
OrderManagerEJB.jar
META-INF/
----

In this structure, the entities and the `persistence.xml` were in one
jar file, `OrderManagerEntities.jar`, and the stateless and stateful
session beans were in another jar file, `OrderManagerEJB.jar`. This did
not work due to modular class loading changes in WildFly. There are a
couple of ways to resolve this issue:

1.  Modify the class path in the `MANIFEST.MF`
2.  Flatten the code and put all the beans in one JAR file.

The second approach was selected because it simplified the EAR
structure:

[source, java]
----
$ jar tf OrderManagerApp.ear
META-INF/application.xml
OrderManagerWeb.war
OrderManagerEJB.jar
META-INF/
----

Since there is no longer an `OrderManagerEntities.jar` file, the
`applcation.xml` file was modified to remove the entry.

An entry was added to the `MANIFEST.MF` file in the
`OrderManagerWeb.war` to resolve another class loading issue resulting
from the modification to use EJB reference injection in the servlets.

[source, java]
----
Manifest-Version: 1.0
Dependencies: org.jboss.logmanager
Class-Path: OrderManagerEJB.jar
----

The `Class-Path` entry tells the application to look in the
`OrderManagerEJB.jar` file for the injected beans.

[[summary]]
=== Summary

Although the existing EAR structure could have worked with additional
modifications to the `MANIFEST.MF` file, this approach seemed more
appealing because it simplified the structure while maintaining the web
tier in its own WAR.

The source files for both versions is attached so you can view the
changes that were made to the application.
