Professional Documents
Culture Documents
Wildfly Swarm Users Guide
Wildfly Swarm Users Guide
Table of Contents
Introduction 0
License 1
Getting Started 2
Introducing WildFly Swarm 2.1
Concepts and Terminology 2.1.1
System Requirements 2.2
Developing your first application 2.3
Maven pom.xml 2.3.1
Adding application code 2.3.2
Running the application 2.3.3
Using WildFly Swarm 3
Build System 3.1
Maven 3.1.1
Advanced 3.1.1.1
Gradle 3.1.2
Application Bootstrap 3.1.3
Container 3.1.3.1
Deployments using ShrinkWrap 3.1.3.2
Packaging Types 3.1.3.3
WAR 3.1.3.3.1
JAR 3.1.3.3.2
Configuration 3.1.4
System Properties 3.1.4.1
Command line arguments 3.1.4.2
Using the Java API 3.1.4.3
Project Stages 3.1.4.4
Using XML 3.1.4.5
Testing your application 3.1.5
Using Arquillian 3.1.5.1
Features (Fractions) 4
2
WildFly Swarm User's Guide
Logging 4.1
Logging 4.1.1
Logstash 4.1.2
FluentD 4.1.3
Data Access 4.2
JPA 4.2.1
Datasources 4.2.2
Flyway 4.2.3
NoSQL 4.2.4
REST/HTTP 4.3
JAX-RS 4.3.1
Swagger 4.3.2
Dependency Injection 4.4
Messaging 4.5
Web 4.6
JSF 4.6.1
Security 4.7
Security Realms 4.7.1
Single Sign On 4.7.2
Keycloak Server 4.7.3
Stability Patterns 4.8
Circuit Breaker 4.8.1
Reactive 4.9
Integration with Vert.x 4.9.1
Service Discovery 4.10
Multicast discovery 4.10.1
Integration with Consul 4.10.2
Javascript API 4.10.3
Transactions 4.11
JTA/JTS 4.11.1
STM 4.11.2
Spring 4.12
Management 4.13
Remote Access 4.13.1
3
WildFly Swarm User's Guide
Jolokia 4.13.2
Monitoring 4.14
Health Checks 4.14.1
Distributed Tracing 4.14.2
Clustering 4.15
JGroups 4.15.1
Infinispan 4.15.2
Tools 5
Forge Add-on 5.1
SwarmTool 5.2
Pre-built Servers 6
MicroProfile 6.1
Keycloak Server 6.2
Swagger UI 6.3
Management Console 6.4
Additional Reading 7
Getting Involved 8
Contributing to WildFly Swarm 8.1
Implementation Details 8.2
Fraction Authoring 8.3
4
WildFly Swarm User's Guide
http://wildfly-swarm.io/
Introduction 5
WildFly Swarm User's Guide
License
WildFly Swarm itself is licensed under the Apache Licence, version 2.0.
http://www.apache.org/licenses/
1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner
that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control,
are controlled by, or are under common control with that entity. For the purposes of this
definition, "control" means (i) the power, direct or indirect, to cause the direction or
management of such entity, whether by contract or otherwise, or (ii) ownership of fifty
percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such
entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted
by this License.
"Source" form shall mean the preferred form for making modifications, including but not
limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included in or
attached to the work (an example is provided in the Appendix below).
License 6
WildFly Swarm User's Guide
"Derivative Works" shall mean any work, whether in Source or Object form, that is
based on (or derived from) the Work and for which the editorial revisions, annotations,
elaborations, or other modifications represent, as a whole, an original work of
authorship. For the purposes of this License, Derivative Works shall not include works
that remain separable from, or merely link (or bind by name) to the interfaces of, the
Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the
Work and any modifications or additions to that Work or Derivative Works thereof, that is
intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by
an individual or Legal Entity authorized to submit on behalf of the copyright owner. For
the purposes of this definition, "submitted" means any form of electronic, verbal, or
written communication sent to the Licensor or its representatives, including but not
limited to communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for the
purpose of discussing and improving the Work, but excluding communication that is
conspicuously marked or otherwise designated in writing by the copyright owner as "Not
a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom
a Contribution has been received by Licensor and subsequently incorporated within the
Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each
Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each
Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
royalty-free, irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where such
license applies only to those patent claims licensable by such Contributor that are
necessarily infringed by their Contribution(s) alone or by combination of their
Contribution(s) with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a cross-claim or counterclaim in a
lawsuit) alleging that the Work or a Contribution incorporated within the Work
constitutes direct or contributory patent infringement, then any patent licenses granted
to You under this License for that Work shall terminate as of the date such litigation is
filed.
License 7
WildFly Swarm User's Guide
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative
Works thereof in any medium, with or without modifications, and in Source or Object
form, provided that You meet the following conditions:
i. You must give any other recipients of the Work or Derivative Works a copy of this
License; and
ii. You must cause any modified files to carry prominent notices stating that You
changed the files; and
iii. You must retain, in the Source form of any Derivative Works that You distribute, all
copyright, patent, trademark, and attribution notices from the Source form of the
Work, excluding those notices that do not pertain to any part of the Derivative
Works; and
iv. If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the attribution
notices contained within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one of the following places:
within a NOTICE text file distributed as part of the Derivative Works; within the
Source form or documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and wherever such third-party
notices normally appear. The contents of the NOTICE file are for informational
purposes only and do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside or as an addendum to
the NOTICE text from the Work, provided that such additional attribution notices
cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
6. Trademarks. This License does not grant permission to use the trade names,
trademarks, service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and reproducing the
License 8
WildFly Swarm User's Guide
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including
negligence), contract, or otherwise, unless required by applicable law (such as
deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental, or
consequential damages of any character arising as a result of this License or out of the
use or inability to use the Work (including but not limited to damages for loss of
goodwill, work stoppage, computer failure or malfunction, or any and all other
commercial damages or losses), even if such Contributor has been advised of the
possibility of such damages.
License 9
WildFly Swarm User's Guide
terms and conditions, and the Licensor grants You such rights in consideration of benefits
the Licensor receives from making the Licensed Material available under these terms and
conditions.
Section 1 — Definitions.
1. Adapted Material means material subject to Copyright and Similar Rights that is derived
from or based upon the Licensed Material and in which the Licensed Material is
translated, altered, arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the Licensor. For purposes
of this Public License, where the Licensed Material is a musical work, performance, or
sound recording, Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
2. Adapter’s License means the license You apply to Your Copyright and Similar Rights in
Your contributions to Adapted Material in accordance with the terms and conditions of
this Public License.
4. Copyright and Similar Rights means copyright and/or similar rights closely related to
copyright including, without limitation, performance, broadcast, sound recording, and
Sui Generis Database Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-
(2) are not Copyright and Similar Rights.
5. Effective Technological Measures means those measures that, in the absence of proper
authority, may not be circumvented under laws fulfilling obligations under Article 11 of
the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international
agreements.
6. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or
limitation to Copyright and Similar Rights that applies to Your use of the Licensed
Material.
7. License Elements means the license attributes listed in the name of a Creative
Commons Public License. The License Elements of this Public License are Attribution
and ShareAlike.
8. Licensed Material means the artistic or literary work, database, or other material to
which the Licensor applied this Public License.
License 10
WildFly Swarm User's Guide
9. Licensed Rights means the rights granted to You subject to the terms and conditions of
this Public License, which are limited to all Copyright and Similar Rights that apply to
Your use of the Licensed Material and that the Licensor has authority to license.
10. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
11. Share means to provide material to the public by any means or process that requires
permission under the Licensed Rights, such as reproduction, public display, public
performance, distribution, dissemination, communication, or importation, and to make
material available to the public including in ways that members of the public may access
the material from a place and at a time individually chosen by them.
12. Sui Generis Database Rights means rights other than copyright resulting from Directive
96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
13. You means the individual or entity exercising the Licensed Rights under this Public
License. Your has a corresponding meaning.
Section 2 — Scope.
1. License grant.
i. Subject to the terms and conditions of this Public License, the Licensor hereby
grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable
license to exercise the Licensed Rights in the Licensed Material to:
ii. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and
Limitations apply to Your use, this Public License does not apply, and You do not
need to comply with its terms and conditions.
iii. Term. The term of this Public License is specified in Section 6(a).
iv. Media and formats; technical modifications allowed. The Licensor authorizes You to
exercise the Licensed Rights in all media and formats whether now known or
hereafter created, and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or authority to forbid You from
making technical modifications necessary to exercise the Licensed Rights,
License 11
WildFly Swarm User's Guide
v. Downstream recipients.
iii. No downstream restrictions. You may not offer or impose any additional or
different terms or conditions on, or apply any Effective Technological Measures
to, the Licensed Material if doing so restricts exercise of the Licensed Rights
by any recipient of the Licensed Material.
2. Other rights.
i. Moral rights, such as the right of integrity, are not licensed under this Public
License, nor are publicity, privacy, and/or other similar personality rights; however,
to the extent possible, the Licensor waives and/or agrees not to assert any such
rights held by the Licensor to the limited extent necessary to allow You to exercise
the Licensed Rights, but not otherwise.
ii. Patent and trademark rights are not licensed under this Public License.
iii. To the extent possible, the Licensor waives any right to collect royalties from You
for the exercise of the Licensed Rights, whether directly or through a collecting
society under any voluntary or waivable statutory or compulsory licensing scheme.
In all other cases the Licensor expressly reserves any right to collect such royalties.
License 12
WildFly Swarm User's Guide
1. Attribution.
i. If You Share the Licensed Material (including in modified form), You must:
i. retain the following if it is supplied by the Licensor with the Licensed Material:
ii. indicate if You modified the Licensed Material and retain an indication of any
previous modifications; and
iii. indicate the Licensed Material is licensed under this Public License, and
include the text of, or the URI or hyperlink to, this Public License.
ii. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based
on the medium, means, and context in which You Share the Licensed Material. For
example, it may be reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required information.
iii. If requested by the Licensor, You must remove any of the information required by
Section 3(a)(1)(A) to the extent reasonably practicable.
2. ShareAlike. In addition to the conditions in Section 3(a), if You Share Adapted Material
You produce, the following conditions also apply.
i. The Adapter’s License You apply must be a Creative Commons license with the
same License Elements, this version or later, or a BY-SA Compatible License.
ii. You must include the text of, or the URI or hyperlink to, the Adapter’s License You
apply. You may satisfy this condition in any reasonable manner based on the
medium, means, and context in which You Share Adapted Material.
iii. You may not offer or impose any additional or different terms or conditions on, or
apply any Effective Technological Measures to, Adapted Material that restrict
exercise of the rights granted under the Adapter’s License You apply.
License 13
WildFly Swarm User's Guide
1. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse,
reproduce, and Share all or a substantial portion of the contents of the database;
3. You must comply with the conditions in Section 3(a) if You Share all or a substantial
portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not replace Your
obligations under this Public License where the Licensed Rights include other Copyright and
Similar Rights.
License 14
WildFly Swarm User's Guide
2. Where Your right to use the Licensed Material has terminated under Section 6(a), it
reinstates:
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor
may have to seek remedies for Your violations of this Public License.
3. For the avoidance of doubt, the Licensor may also offer the Licensed Material under
separate terms or conditions or stop distributing the Licensed Material at any time;
however, doing so will not terminate this Public License.
Section 8 — Interpretation.
1. For the avoidance of doubt, this Public License does not, and shall not be interpreted to,
reduce, limit, restrict, or impose conditions on any use of the Licensed Material that
could lawfully be made without permission under this Public License.
License 15
WildFly Swarm User's Guide
2. To the extent possible, if any provision of this Public License is deemed unenforceable,
it shall be automatically reformed to the minimum extent necessary to make it
enforceable. If the provision cannot be reformed, it shall be severed from this Public
License without affecting the enforceability of the remaining terms and conditions.
3. No term or condition of this Public License will be waived and no failure to comply
consented to unless expressly agreed to by the Licensor.
License 16
WildFly Swarm User's Guide
Terminology
Fraction
A well-defined collection of capabilities to add. In some cases, a fraction maps directly to
a subsystem from WildFly, but in other cases (e.g. Jolokia) a fraction may involve
different functionality.
Uberjar
A self-contained, executable Java archive. In the case of WildFly Swarm uberjars, it is a
single .jar file containing your application, the portions of WildFly required to support
it, an internal Maven repository of dependencies, plus a shim to bootstrap it all.
Hollow Uberjar
A self-contained, executable Java archive that contains no application code. Somewhat
contradictory term. It is a container capable of deploying a particular type of application.
Default Deployment
The primary application artifact created by your Maven or Gradle build. This may be a
.war in many cases or a .jar , depending on the <packaging> in your pom.xml
System Requirements
At a bare minimum you need at least the following:
JDK 8
Maven 3.3.x
Java 8
WildFly leverages the Java 8 API’s, in particular lambdas and the collection enhancements.
Therefore the JDK 8 is required to build and run WildFly Swarm applications:
Download JDK 8
Maven 3.3.x
The Maven Plugin, that performs most of the work when packaging WildFly Swarm
applications requires at maven 3.3.x:
If running WildFly Swarm from within the IDE, especially mvn wildfly-swarm:run ,
you will need to verify that the IDE uses this Maven version. Typically IDEs will be
running a Maven version less than 3.2.x which will cause issues
System Requirements 20
WildFly Swarm User's Guide
In this example we build a simple restful HTTP endpoint using WildFly Swarm. The project
uses maven and follows a typical maven project layout:
|-pom.xml
|-src
|-main
|-java
Click Generate and save the resulting zip file on your machine
Unpack the zip and you’ve code everything we use in this simple example
Maven POM
The most simple pom.xml to be used with WildFly Swarm looks like the following. As you
can see, it contains three notable elements:
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>restful-endpoint</artifactId>
<name>Wildfly Swarm Example</name>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<version.wildfly.swarm>2017.11.0-SNAPSHOT</version.wildfly.swarm>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>bom</artifactId>
<version>${version.wildfly.swarm}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>restful-endpoint</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<version>${version.wildfly.swarm}</version>
Maven pom.xml 22
WildFly Swarm User's Guide
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Java EE 7 dependency -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- Wildfly Swarm Fractions -->
</dependencies>
</project>
Maven pom.xml 23
WildFly Swarm User's Guide
package com.example.rest;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
@Path("/hello")
public class HelloWorldEndpoint {
@GET
@Produces("text/plain")
public Response doGet() {
return Response.ok("Hello from WildFly Swarm!").build();
}
}
package com.example.rest;
import javax.ws.rs.core.Application;
import javax.ws.rs.ApplicationPath;
@ApplicationPath("/rest")
public class RestApplication extends Application {
}
In the next step, we are going to package the application and run it.
mvn wildfly-swarm:run
[INFO] ------------------------------------------------------------------------
[INFO] Building Wildfly Swarm Example 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[....]
[INFO] --- maven-war-plugin:2.2:war (default-war) @ restful-endpoint ---
[INFO] Packaging webapp
[INFO] Assembling webapp [restful-endpoint] in [/Users/hbraun/Downloads/restful-endpoint/target/restf
[INFO] Processing war project
[INFO] Webapp assembled in [28 msecs]
[INFO] Building war: /Users/hbraun/Downloads/restful-endpoint/target/restful-endpoint.war
[INFO]
[INFO] --- wildfly-swarm-plugin:2017.11.0-SNAPSHOT:package (default) @ restful-endpoint ---
[INFO] Scanning for needed WildFly Swarm fractions with mode: when_missing
[INFO] Detected fractions: jaxrs:2017.11.0-SNAPSHOT
[INFO] Adding fractions: container:2017.11.0-SNAPSHOT, ee:2017.11.0-SNAPSHOT, io:2017.11.
[....]
mvn package
[INFO] ------------------------------------------------------------------------
[INFO] Building Wildfly Swarm Example 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[....]
[INFO] --- maven-war-plugin:2.2:war (default-war) @ restful-endpoint ---
[INFO] Packaging webapp
[INFO] Assembling webapp [restful-endpoint] in [/Users/hbraun/Downloads/restful-endpoint/target/restf
[INFO] Processing war project
[INFO] Webapp assembled in [26 msecs]
[INFO] Building war: /Users/hbraun/Downloads/restful-endpoint/target/restful-endpoint.war
[INFO]
[INFO] --- wildfly-swarm-plugin:2017.11.0-SNAPSHOT:package (default) @ restful-endpoint ---
[INFO] Scanning for needed WildFly Swarm fractions with mode: when_missing
[INFO] Detected fractions: jaxrs:2017.11.0-SNAPSHOT
[INFO] Adding fractions: container:2017.11.0-SNAPSHOT, ee:2017.11.0-SNAPSHOT, io:2017.11.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.779 s
[INFO] Finished at: 2016-07-07T13:38:26+02:00
[INFO] Final Memory: 54M/1161M
[INFO] ------------------------------------------------------------------------
The resulting uberJar carries the -swarm.jar suffix and can be found in the ./target
directory:
ll target/
-rw-r--r-- 1 hbraun staff 41943061 Jul 7 13:38 restful-endpoint-swarm.jar
-rw-r--r-- 1 hbraun staff 3591 Jul 7 13:38 restful-endpoint.war
curl http://localhost:8080/rest/hello
Congratulations!
You’ve just build your first application using WildFly Swarm.
Maven Plugin
To assist in building WildFly Swarm projects, a Maven plugin is available. This plugin creates
the -swarm.jar uberjar which contains your application along with the necessary parts of
WildFly to support it.
Configuration
To use the plugin, you must add it to your pom.xml :
<build>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
mvn package
Hollow uberjar
Maven 29
WildFly Swarm User's Guide
To produce a hollow uberjar, the same mvn package method is used, but either set the
property -Dswarm.hollow=true or configure the plugin with <hollow>true</hollow> from
within your pom.xml .
A hollow uberjar will have the suffix of -hollow-swarm.jar and will not include the actual
application deployment. This may be useful if you are targetting layered Linux containers,
where you wish to place the runtime on a lower layer, and the more frequently changing
deployment on a higher layer.
If using the hollow functionality, the command-line arguments to the uberjar should point to
one or more deployments that should be used.
An example of the hollow jar functionality may be seen in the MicroProfile standalone server.
mvn wildfly-swarm:run
This will execute your application within the WildFly Swarm runtime directly from the Maven
command-line, and wait for it to exit.
Both of these goals will perform the same type of fraction detection as the package task if
no WildFly Swarm dependencies are found.
Fraction detection
If the plugin doesn’t detect any WildFly Swarm dependencies in your pom.xml , it will attempt
to auto-detect needed fractions by scanning the application. This is mostly useful for WAR-
based applications that you are migrating to WildFly Swarm - you only need to add the
plugin to your configuration, and not any other WildFly Swarm dependencies. You can
control fraction detection by setting <fractionDetectMode> . See the configuration options
below for more details.
Maven 30
WildFly Swarm User's Guide
A properties-style list of
environment variables to
environment none
use when running the
application
A .properties file of
environment variables to
environmentFile swarm.environmentFile
use when running the
application
Maven 31
WildFly Swarm User's Guide
A list of <jvmArgument>
elements specifying
jvmArguments swarm.jvmArguments
additional JVM arguments
(such as -Xmx32m )
Paths to a directory
modules none containing additional ./modules
module definitions
Application configurations to
processes none start (see multistart section
above)
Maven 32
WildFly Swarm User's Guide
Properties
Many properties may be used to configure execution and affect the packaging or running of
your application.
Any properties added to the uberjar can of course be overridden at runtime using the
traditional -Dname=value mechanism of java .
Maven 33
WildFly Swarm User's Guide
<executionId> (useful if you need to launch multiple copies of the same application). Each
<process> can also include any configuration that is valid for the wildfly-swarm:start goal.
Example
Maven 34
WildFly Swarm User's Guide
<build>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<executions>
<execution>
<id>multistart</id>
<phase>pre-integration-test</phase>
<goals>
<goal>multistart</goal>
</goals>
<configuration>
<processes>
<process>
<artifactId>my-frontend-app</artifactId>
</process>
<process>
<artifactId>my-auth-app</artifactId>
<properties>
<swarm.http.port>8081</swarm.http.port>
</properties>
<mainClass>com.example.auth.Main</mainClass>
</process>
<process>
<artifactId>my-indexing-app</artifactId>
<properties>
<swarm.http.port>8082</swarm.http.port>
</properties>
<environment>
<ENV>test</ENV>
</environment>
</process>
</processes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Stopping applications
If you have started any applications with either wildfly-swarm:start or wildfly-
swarm:multistart , they can be stopped by executing the wildfly-swarm:stop goal.
Maven 35
WildFly Swarm User's Guide
Gradle Plugin
To assist in building WildFly Swarm projects, a Gradle plugin is available. This plugin creates
the -swarm.jar uberjar which contains your application along with the necessary parts of
WildFly to support it.
Gradle doesn’t get the same attention by the core developers as Maven. If you want
to be on the safe side, use Maven. If you are interested in contributing to the Gradle
build system, please let us know!
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.wildfly.swarm:wildfly-swarm-gradle-plugin:1.0.0.Alpha9-SNAPSHOT"
}
}
Gradle 36
WildFly Swarm User's Guide
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
classpath "org.wildfly.swarm:wildfly-swarm-gradle-plugin:2017.11.0-SNAPSHOT"
}
}
repositories {
mavenLocal()
mavenCentral()
}
dependencyManagement {
imports {
mavenBom "org.wildfly.swarm:bom:2017.11.0-SNAPSHOT"
}
}
dependencies {
compile "org.wildfly.swarm:jaxrs"
}
Configuration
You can optionally provide configuration to the plugin.
Configuration Options
The plugin accepts the following options:
Gradle 37
WildFly Swarm User's Guide
If true, dependencies
will be included in the -
swarm.jar. Otherwise,
bundleDependencies true
they will be resolved
from $M2_REPO or the
network.
A class to execute as
the main. If not set, the
plugin will check for
mainClassName mainClassName from org.wildfly.swarm.bootstrap.Main
the application
plugin before using the
default.
Paths to a directory
modules containing additional ./modules
module definitions
A Jar-Task which
should be wrapped
instead of the JAR-
archiveTask
Task (Java-Plugin) or
WAR-Task (WAR-
Plugin)
Properties
Many properties may be used to configure execution and affect the packaging or running of
your application.
If you set a properties map or the propertiesFile field in the swarm block in your build
script, the properties will be added to your myapp-swarm.jar to affect subsequent executions
of the uberjar. Any properties loaded from propertiesFile will override same-named
properties from properties .
Any properties added to the uberjar can of course be overridden at runtime using the
traditional -Dname=value mechanism of java .
Gradle 38
WildFly Swarm User's Guide
Only properties specified outside of properties or propertiesFile that start with jboss. ,
wildfly. , or swarm. , or override a property specified in properties or propertiesFile
Example
swarm {
properties {
swarm.http.port = 8181
my.app.property = 'biscuits'
}
bundleDependencies = false
moduleDirs = [new File(buildDir, 'resources/main/modules')]
propertiesFile = new File(buildDir, "resources/main/some.properties")
}
Gradle 39
WildFly Swarm User's Guide
Container ( Swarm )
At the root of every WildFly Swarm application is the container.
The container provides an API for instantiating an embedded WildFly Swarm container,
starting and stopping it, and deploying.
The container can either be instantiated inside your own main(…) , or if you don’t provide a
main(…) , then WildFly Swarm will handle the construction of the container and subsequent
User-Provided main(…)
If you provide a main(…) and configure it in using the Maven Plugin or Gradle Plugin, it
should simply be a regular Java main(…) method.
Because of some initialization timing issues, you should construct the Swarm prior to
working with any deployments using the ShrinkWrap API.
It’s also recommended that the Swarm is constructed prior to any other code in the main(…
) . This is to prevent any issues of JBoss Logging not being able to initialize the logging
subsystem if another framework or class has used JUL, or another logger, first.
swarm.start();
swarm.deploy(deployment);
}
}
Gradle 40
WildFly Swarm User's Guide
If you only need to do some configuration of the container without needing to manipulate the
deployment archive, you can call deploy() with no arguments to have it deploy the default
archive. For example, here we configure an h2 datasource, then deploy the default archive:
No User-Provided main(…)
If you choose not to provide a main, org.wildfly.swarm.Swarm#main(…) will be used by
default. It boots the default container (based upon your dependencies) and deploys your
project artifact.
The org.wildfly.swarm.Swarm class is also suitable for executing directly from your IDE if
you have no requirement of providing a customized main(…) .
In the event a user-provided main(…) exists, it can still optionally provide support for the
above-mentioned command-line arguments. A constructor of Swarm takes the String…args
provided to the main(…) and will process all relevant arguments.
Gradle 41
WildFly Swarm User's Guide
In this case, be aware that if the -swarm.jar is invoked with --help , a call to
System.exit(0) will occur, abruptly terminating the application.
Gradle 42
WildFly Swarm User's Guide
ShrinkWrap Basics
The primary entry-point into ShrinkWrap is the ShrinkWrap class and its create(class)
method. You can create simple Java or Web archives ( .jar and .war , respectively) by
passing JavaArchive.class or WebArchive.class to the create(…) method.
WildFly Swarm additionally makes other types of archives available, depending on which
fractions you include in your application. While they all ultimately produce a Java archive,
they provide additional logic to make building certain types of archives easier.
The types of archives that WildFly Swarm makes available includes, but is not limited to:
Type Description
An enhanced version of .jar which
JARArchive provides easy methods for adding
dependencies.
Secured
Archive type which injects keycloak.json
and sets up security constraints
RibbonArchive
Archive which can register Ribbon-based
services or clients
Gradle 43
WildFly Swarm User's Guide
Each ShrinkWrap archive type is effectively a view onto the underlying archive. Using the
archive’s own .as(class) method, the view can be changed several times while
constructing it.
// Then, view it as a RibbonArchive, and set its service name for discovery
deployment.as( RibbonArchive.class ).setApplicationName( "my-service" );
Gradle 44
WildFly Swarm User's Guide
WAR Packaging
If you have an existing WAR-based application, you can construct a self-contained myapp-
swarm.jar from it with ease. By using the plugin of your choice (Maven or Gradle), the
resulting uberjar will contain your application along with enough of the application-server to
support it.
Maven
For a Maven project, you already have a pom.xml with
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
</plugin>
</plugins>
</build>
When you perform a typical Maven build using mvn package , your target directory will
include a myapp-swarm.jar version of your application.
If you don’t specify any WildFly Swarm fractions as dependencies, the maven plugin will
auto-detect the fractions your application needs. See the Maven chapter for more details.
Gradle 45
WildFly Swarm User's Guide
JAR Packaging
If you desire to move away from traditionally-packaged .war applications, more options are
available to you with WildFly Swarm. Though a fluent API, you can fully configure the
facilities brought to your application and control what gets deployed.
The main(…) method should exactly match the typical requirements of a main method in
Java, and is executable from your IDE.
Within the main method, you can work with the org.wildfly.swarm.Swarm API to configure
fractions into the system and deploy components.
Name Description
fraction(…) Add an explicitly-configured fraction
Default Configuration
Gradle 46
WildFly Swarm User's Guide
When you add dependencies to your project, they automatically activate the related fraction.
For instance, simply having the logging dependency adds the logging fraction to the
container and initializes it.
You only need to call .fraction(new LoggingFraction()) if you want to change the
configuration to be different from the default. Any fraction that has been brought in through
the dependency mechanism but has not been explicitly configured will be added with its
default configuration.
Deployments
Once a container is created, one or more deployments may be created using ShrinkWrap
and deployed into the container. Please see the chapter on ShrinkWrap for general details
on how to create deployments.
Gradle 47
WildFly Swarm User's Guide
System Properties
Below is a non-exhaustive set of useful properties, which may be available depending on
which fractions your application uses.
For a full set of supported options, please consult the documentation for each
fraction and the javadocs on class SwarmProperties.java
General
Name Description Default
swarm.bind.address Interface to bind servers 0.0.0.0
Timeout, in seconds, to
swarm.deployment.timeout wait for a deployment to 300
occur
Undertow
Gradle 48
WildFly Swarm User's Guide
If true,
generates a
swarm.https.certificate.generate
Enables HTTPS and generates a self-signed
self-signed certificate certificate for
development
purposes
Databases
For the H2, MySQL and Postgres database fractions, the follow properties are supported to
configure the datasource.
swarm.ds.name
Name of the datasource ExampleDS
(e.g. ExampleDS )
Gradle 49
WildFly Swarm User's Guide
Location of a Java
-P<file-or-url> .properties file to use as none
system properties.
Specify an XML
configuration file (such as
-c <file-or-url> none
standalone.xml or a
fragment of such).
project-defaults.yml
-s <file-or-url> Specify a project- from the application
defaults.yml
classpath, if available.
Gradle 50
WildFly Swarm User's Guide
new DatasourcesFraction()
.jdbcDriver("h2", (d) -> {
d.driverClassName("org.h2.Driver");
d.xaDatasourceClass("org.h2.jdbcx.JdbcDataSource");
d.driverModuleName("com.h2database.h2");
})
.dataSource("ExampleDS", (ds) -> {
ds.driverName("h2");
ds.connectionUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
ds.userName("sa");
ds.password("sa");
});
The complete Javadocs for the config API are available here
In this example we configure the datasource fraction with an additional datasource and a
corresponding JDBC driver.
All of the fractions that represent WildFly subsystems can be configured this way. The
configuration model is an equivalent to the WildFly XML schema. In fact it is actually
generated from it.
Gradle 51
WildFly Swarm User's Guide
project-defaults.yml
Default configuration is represented in an external YAML file:
logger:
level: DEBUG
swarm:
port:
offset: 10
---
project:
stage: development
logger:
level: DEBUG
swarm:
port:
offset: 50
---
project:
stage: production
logger:
level: INFO
swarm:
port:
offset: 100
project-development.yml
logger:
level: DEBUG
swarm:
port:
offset: 50
project-production.yml
Gradle 52
WildFly Swarm User's Guide
logger:
level: INFO
swarm:
port:
offset: 100
Container Bootstrap
ClassLoader cl = Main.class.getClassLoader();
URL stageConfig = cl.getResource("project-defaults.yml");
- Allows to reference a
swarm.project.stage.file Dswarm.project.stage.file= different project-
<URL> defaults.yml file
YAML Internal
swarm: port: offset: swarm.port.offset
Gradle 53
WildFly Swarm User's Guide
Internally there are three ways to get hold of stage configuration values.
Using Expressions
The fist case is useful when you work with standalone.xml and still need to extract
environment specific properties. In this cases you can make use of regular WildFly
expressions in XML:
<subsystem xmlns="urn:jboss:domain:logging:3.0">
<console-handler name="CONSOLE">
<level name="${logger.level:INFO}"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<root-logger>
<level name="${logger.level:INFO}"/>
<handlers>
<handler name="CONSOLE"/>
</handlers>
</root-logger>
[...]
</subsystem>
Here the stage configuration logger.level is referenced using the expression syntax
${logger.level:INFO} (INFO is the fallback value).
Using StageConfig
StageConfig is the java type representing the former YAML file. It allows you to access
named properties following the standard java properties name syntax (i.e. logger.level )
2. From Swarm
The first case is intended to be used by Fraction authors if they need to hook into the stage
configuration for the default configuration of a fraction itself.
The later case is intended for users to combine stage and fraction configuration in a custom
Main() :
Gradle 54
WildFly Swarm User's Guide
swarm.fraction(
new DatasourcesFraction()
.jdbcDriver("h2", (d) -> {
d.driverClassName("org.h2.Driver");
d.xaDatasourceClass("org.h2.jdbcx.JdbcDataSource");
d.driverModuleName("com.h2database.h2");
})
.dataSource("ExampleDS", (ds) -> {
ds.driverName("h2");
ds.connectionUrl(
// referencing stage configuration values
swarm
.stageConfig()
.resolve("database.connection.url")
.getValue()
);
ds.userName("sa");
ds.password("sa");
})
);
Gradle 55
WildFly Swarm User's Guide
To make use of such a file, you’d need to bootstrap the Container with a reference to an
XML configuration:
ClassLoader cl = Main.class.getClassLoader();
URL xmlConfig = cl.getResource("standalone.xml");
[...]
In this case, you would still need to declare explicit maven dependencies on Swarm
fractions, but the Container would just use those subsystem configurations for which a
corresponding fraction can be found, i.e.:
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
<datasources>
<drivers>
<driver name="h2" module="com.h2database.h2">
<driver-class>org.h2.Driver</driver-class>
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
</drivers>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
</datasources>
</subsystem>
Gradle 56
WildFly Swarm User's Guide
Under traditional usage, Arquillian first launches the application server, then deploys an
archive created within your unit test to it. When used with WildFly Swarm, there is obviously
no separate launch the application server phase.
Instead, your test-case creates your application, and the Arquillian adapter wraps it with the
WildFly Swarm bits and executes the resulting uberjar.
Once it is running, test code may run outside of the uberjar or within it, reporting the test
results back to the testing framework.
Configuring
To use the WildFly Swarm Arquillian adapter, you need to add the following into your
pom.xml :
Gradle 57
WildFly Swarm User's Guide
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.10.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Brought in via WildFly Swarm `bom` -->
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>arquillian</artifactId>
<scope>test</scope>
</dependency>
<!-- Brought in via Arquillian BOM, see dependencyManagement section above -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Writing a Test
To integrate Arquillian into your test, you need to use the JUnit @RunWith annotation and the
Arquillian.class test-runner:
@RunWith(Arquillian.class)
public class MyTest {
...
}
Next, you need to specify the deployment that should be wrapped up in the WildFly Swarm
mechanism. This is accomplished by using the @Deployment Arquillian annotation on a
public static method that returns a ShrinkWrap archive.
@Deployment
public static Archive createDeployment() {
...
}
Gradle 58
WildFly Swarm User's Guide
The contents of this method is similar to whatever you would do within your main(…)
method.
For instance:
@Deployment
public static Archive createDeployment() {
JAXRSArchive deployment = ShrinkWrap.create( JAXRSArchive.class );
deployment.addResource( MyResource.class );
return deployment;
}
By default, all methods annotated with @Test will run inside the application. Depending on
the functionality you include, you can use annotations such as @Inject (if you’re using CDI)
to inject components into your test-case class.
If you wish to test your application from outside (for instance, with a web client), you can use
the @RunAsClient annotation on your method.
@RunWith(Arquillian.class)
public class MyTest {
@Inject
private MyComponent component;
@Test
public void testMyComponent() {
// Runs within the application, CDI injects MyComponent
@Deployment
public static Archive createDeployment() {
JARArchive archive = ShrinkWrap.create( JARArchive.class );
return archive;
}
}
Gradle 59
WildFly Swarm User's Guide
If the swarm container has to be configured (e.g. to configure the DataSource fraction) then
this can be done by implementing the ContainerFactory interface.
@RunWith(Arquillian.class)
public class MyTest {
@Deployment(testable = false)
public static Archive createDeployment() {
JARArchive deployment = ShrinkWrap.create(JARArchive.class);
// ... set up archive ...
return deployment;
}
@CreateSwarm
public static Swarm newContainer() throws Exception {
Swarm swarm = new Swarm();
// ... configure Swarm ...
return swarm;
}
@Test
@RunAsClient
public void testNothing() {
}
}
Default Deployment
In a world of microservices, this tends to not be the case, and the entire "application"
represents one small microservice component.
@RunWith(Arquillian.class)
@DefaultDeployment
public class InContainerTest {
The @DefaultDeployment annotation looks at the package of the test, and it uses heuristics
to include all of your other application classes residing in that package or deeper within the
Java packaging hierarchy.
Gradle 60
WildFly Swarm User's Guide
Gradle 61
WildFly Swarm User's Guide
Logging
Logging is supported by WildFly Swarm using the typical JBoss-Logging systems. By
default, logging occurs to the console. Advanced configuration can adjust the amount of
information logged and where the log ends up (files or console or other locations).
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>logging</artifactId>
</dependency>
Configuration
Including the above dependency will automatically configure reasonable INFO-level logging
to the console. You can control the logging level with the swarm.logging sysprop: -
Dswarm.logging=DEBUG .
If you wish to perform more advanced configuration, please see the JavaDocs for the
Logging API.
Logging to a file
In order to log to a file, you’d need to specifiy a file handler and link it to the root logger. A full
example for the configuration of a log file handler looks like this:
Logging 62
WildFly Swarm User's Guide
})
.rootLogger(Level.INFO, "FILE")
);
container.start();
[...]
Logging 63
WildFly Swarm User's Guide
Logstash
The Logstash project from Elastic provides for a centralized server to accumulate logs from
a multitude of applications. WildFly Swarm makes it easy to have each of your applications
or services dump their logs into it.
Configure
Dependency
To add Logstash integration to your WildFly Swarm application, you need to add a
dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>logstash</artifactId>
</dependency>
Configuration
While the above dependency adds the capability of logging to Logstash, until the Logstash
server’s hostname and port is set, the integration remains inactive.
To configure where the Logstash server is running, the following two properties need to be
set, either through plugin configuration or on the command-line using -D…
Name Description
Logstash 64
WildFly Swarm User's Guide
FluentD
The FluentD project from http://www.fluentd.org/ provides for an open source data collector
for a unified logging layer. The fluentd fraction installs a custom log handler that’s capable of
logging to a fluentd daemon, which filter, buffer and route logging information according to
your needs. == Configure
Dependency
To add FluentD integration to your WildFly Swarm application, you need to add a
dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>fluentd</artifactId>
</dependency>
Configuration
To configure where the FluentD daemon is running, the following two properties need to be
set, either through plugin configuration or on the command-line using -D… Usually we
would expect the daemon to run co-located with the Swarm process (i.e. same docker
image).
FluentD 65
WildFly Swarm User's Guide
JPA
Java Persistence API (JPA) is a standard JavaEE API for developing applications that need
access to relational databases.
Configuration
To use JPA in your application, you need to add the JPA dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jpa</artifactId>
</dependency>
and then specify the dependency for whichever JDBC Driver you need for your particular
database.
Examples include:
H2 JDBC Driver
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
JPA 66
WildFly Swarm User's Guide
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
Usage
The jpa fraction makes the JPA APIs available to your application through a transitive
dependency. There is no need to add them yourself.
Configuration
If the default datasource for JPA is used, it may be configured using system properties.
Property Description
swarm.ds.connection.url JDBC connection URL
swarm.ds.username
Username for authenticating the
connection
swarm.ds.password
Password for authenticating the
connection
JPA 67
WildFly Swarm User's Guide
JPA 68
WildFly Swarm User's Guide
Datasource
Datasources provide managed connections to relational databases. While they may be used
directly, typically they are consumed through other frameworks, such as a JPA.
Configuration
To use Datasources in your application, you need to add the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>datasources</artifactId>
</dependency>
Usage
Using the Java API, you may create one or more datasources, along with registering
relevant JDBC drivers:
swarm.fraction(new DatasourcesFraction()
.jdbcDriver("h2", (d) -> {
d.driverClassName("org.h2.Driver");
d.xaDatasourceClass("org.h2.jdbcx.JdbcDataSource");
d.driverModuleName("com.h2database.h2");
})
.dataSource("MyDS", (ds) -> {
ds.driverName("h2");
ds.connectionUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
ds.userName("sa");
ds.password("sa");
})
);
Datasources 69
WildFly Swarm User's Guide
Datasources 70
WildFly Swarm User's Guide
Flyway
Flyway is an open-source database migration tool. It strongly favors simplicity and
convention over configuration.
Configuration
To enable Flyway, the following dependency is required:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>flyway</artifactId>
</dependency>
Flyway 71
WildFly Swarm User's Guide
Flyway 72
WildFly Swarm User's Guide
Connection pooling
Connections to NoSQL database servers are managed by the underlying native NoSQL
drivers. Connection pooling is provided directly by the native NoSQL drivers.
CDI Injection
Each NoSQL connection profile uniquely names the profile id, which can be used to @Inject
@Named("id") the NoSQL connection into your application code.
NoSQL 73
WildFly Swarm User's Guide
Each NoSQL connection profile uniquely names the JNDI lookup jndi-name, which can be
easily used by application code.
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>${version.mongodb.driver}</version>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>cassandra</artifactId>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>${version.cassandra.driver}</version>
</dependency>
</dependencies>
NoSQL 74
WildFly Swarm User's Guide
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>${version.neo4j.driver}</version>
</dependency>
</dependencies>
NoSQL 75
WildFly Swarm User's Guide
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>orientdb</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-core</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-graphdb</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-object</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-client</artifactId>
</dependency>
<dependency>
<groupId>com.tinkerpop.blueprints</groupId>
<artifactId>blueprints-core</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
</dependency>
NoSQL 76
WildFly Swarm User's Guide
3.0.3 NO YES
3.3.0 NO YES
3.4.2 NO YES
project-defaults.yml
NoSQL 77
WildFly Swarm User's Guide
swarm:
mongodb:
mongos:
mongodbtestprofile:
database: mongotestdb
jndi-name: java:jboss/mongodb/test
id: mongodbtestprofile
module: org.mongodb.driver.custom
security-domain: mongoRealm
hosts:
mongotesthost:
outbound-socket-binding-ref: mongotesthost
security:
security-domains:
mongoRealm:
cache-type:
classic-authentication:
login-modules:
ConfiguredIdentity:
code: ConfiguredIdentity
flag: required
ConfiguredIdentity:
module-options:
principal: DBUSERID
password: DBPASSWORD
username: DBUSERID
network:
socket-binding-groups:
standard-sockets:
outbound-socket-bindings:
mongotesthost:
remote-host: localhost
remote-port: 27017
HelloWorldEndpoint.java
NoSQL 78
WildFly Swarm User's Guide
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import com.mongodb.client.MongoDatabase;
@ApplicationScoped
@Path("/hello")
public class HelloWorldEndpoint {
@Inject @Named("mongodbtestprofile")
MongoDatabase database;
@GET
@Produces("text/plain")
public Response doGet() {
return Response.ok("Hello from WildFly Swarm! database = " + database).build();
}
}
pom.xml
<properties>
<version.wildfly.swarm>2017.6.0-SNAPSHOT</version.wildfly.swarm>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.mongodb.driver>3.2.2</version.mongodb.driver>
<version.org.glassfish.javax.json>1.0.3</version.org.glassfish.javax.json>
</properties>
<dependencyManagement>
<dependencies>
NoSQL 79
WildFly Swarm User's Guide
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>bom-all</artifactId>
<version>${version.wildfly.swarm}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<version>${version.wildfly.swarm}</version>
<configuration>
<mainClass>org.wildflynosql.demo.rest.Main</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Java EE 7 dependency -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- WildFly Swarm Fractions -->
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs-jsonp</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jsonp</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
NoSQL 80
WildFly Swarm User's Guide
<artifactId>javax.json</artifactId>
<version>${version.org.glassfish.javax.json}</version>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>${version.mongodb.driver}</version>
</dependency>
</dependencies>
</project>
project-defaults.yml
NoSQL 81
WildFly Swarm User's Guide
swarm:
cassandradriver:
cassandras:
cassandratestprofile:
database:
jndi-name: java:jboss/cassandradriver/test
id: cassandratestprofile
module: org.cassandra.custom
security-domain: cassandraRealm
hosts:
casstesthost:
outbound-socket-binding-ref: casstesthost
security:
security-domains:
cassandraRealm:
cache-type:
classic-authentication:
login-modules:
ConfiguredIdentity:
code: ConfiguredIdentity
flag: required
ConfiguredIdentity:
module-options:
principal: DBUSERID
password: DBPASSWORD
username: DBUSERID
network:
socket-binding-groups:
standard-sockets:
outbound-socket-bindings:
casstesthost:
remote-host: localhost
remote-port: 9042
HelloWorldEndpoint.java
NoSQL 82
WildFly Swarm User's Guide
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import com.datastax.driver.core.Cluster;
@ApplicationScoped
@Path("/hello")
public class HelloWorldEndpoint {
@Inject @Named("cassandratestprofile")
Cluster cluster;
@GET
@Produces("text/plain")
public Response doGet() {
return Response.ok("Hello from WildFly Swarm! cluster = " + cluster).build();
}
}
pom.xml
<properties>
<version.wildfly.swarm>2017.6.0-SNAPSHOT</version.wildfly.swarm>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.cassandra.driver>3.0.0</version.cassandra.driver>
<version.org.glassfish.javax.json>1.0.3</version.org.glassfish.javax.json>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
NoSQL 83
WildFly Swarm User's Guide
<groupId>org.wildfly.swarm</groupId>
<artifactId>bom-all</artifactId>
<version>${version.wildfly.swarm}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<version>${version.wildfly.swarm}</version>
<configuration>
<mainClass>org.wildflynosql.demo.rest.Main</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Java EE 7 dependency -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- WildFly Swarm Fractions -->
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs-jsonp</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jsonp</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
NoSQL 84
WildFly Swarm User's Guide
<version>${version.org.glassfish.javax.json}</version>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>cassandra</artifactId>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>${version.cassandra.driver}</version>
</dependency>
</dependencies>
</project>
NoSQL 85
WildFly Swarm User's Guide
The OrientDB client API, is heavily dependent on keeping one OrientDB database
open per Java thread. When your application is done with the database, you must
close the OrientDB database to disassociate it from the Java thread, or the open
database will still be open by that Java thread, when the Java thread is returned to
the Java thread pool. A max of one OrientDB database can be open per Java thread,
so if you open a different database, the current one will be automatically closed first.
project-defaults.yml
swarm:
orientdb:
orients:
orienttesttprofile:
database: test
jndi-name: java:jboss/orientdb/test
id: orienttesttprofile
module: org.orientdb.custom
security-domain: orientRealm
hosts:
orienttesthost:
outbound-socket-binding-ref: orienttesthost
security:
security-domains:
orientRealm:
cache-type:
classic-authentication:
login-modules:
ConfiguredIdentity:
code: ConfiguredIdentity
flag: required
ConfiguredIdentity:
module-options:
principal: DBUSERID
password: DBPASSWORD
username: DBUSERID
network:
socket-binding-groups:
standard-sockets:
outbound-socket-bindings:
orienttesthost:
remote-host: localhost
remote-port: 2424
HelloWorldEndpoint.java
NoSQL 86
WildFly Swarm User's Guide
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import com.orientechnologies.orient.core.db.OPartitionedDatabasePool;
@ApplicationScoped
@Path("/hello")
public class HelloWorldEndpoint {
@Inject @Named("orienttesttprofile")
OPartitionedDatabasePool databasePool;
@GET
@Produces("text/plain")
public Response doGet() {
return Response.ok("Hello from WildFly Swarm! databasePool= " + databasePool).build();
}
}
pom.xml
<properties>
<version.wildfly.swarm>2017.6.0-SNAPSHOT</version.wildfly.swarm>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.cassandra.driver>3.0.0</version.cassandra.driver>
<version.org.glassfish.javax.json>1.0.3</version.org.glassfish.javax.json>
</properties>
<dependencyManagement>
<dependencies>
NoSQL 87
WildFly Swarm User's Guide
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>bom-all</artifactId>
<version>${version.wildfly.swarm}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<version>${version.wildfly.swarm}</version>
<configuration>
<mainClass>org.wildflynosql.demo.rest.Main</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Java EE 7 dependency -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- WildFly Swarm Fractions -->
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs-jsonp</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jsonp</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
NoSQL 88
WildFly Swarm User's Guide
<artifactId>javax.json</artifactId>
<version>${version.org.glassfish.javax.json}</version>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>orientdb</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-core</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-graphdb</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-object</artifactId>
</dependency>
<dependency>
<groupId>com.orientechnologies</groupId>
<artifactId>orientdb-client</artifactId>
</dependency>
<dependency>
<groupId>com.tinkerpop.blueprints</groupId>
<artifactId>blueprints-core</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
</dependency>
</dependencies>
</project>
NoSQL 89
WildFly Swarm User's Guide
project-defaults.yml
swarm:
neo4jdriver:
neo4js:
neo4jtestprofile:
jndi-name: java:jboss/neo4jdriver/test
id: neo4jtestprofile
module: org.neo4j.driver.custom
security-domain: neo4jRealm
transaction: 1pc
hosts:
neo4jtesthost:
outbound-socket-binding-ref: neo4jtesthost
security:
security-domains:
neo4jRealm:
cache-type:
classic-authentication:
login-modules:
ConfiguredIdentity:
code: ConfiguredIdentity
flag: required
ConfiguredIdentity:
module-options:
principal: DBUSERID
password: DBPASSWORD
username: DBUSERID
network:
socket-binding-groups:
standard-sockets:
outbound-socket-bindings:
neo4jtesthost:
remote-host: localhost
remote-port: 7687
HelloWorldEndpoint.java
NoSQL 90
WildFly Swarm User's Guide
// HelloWorldEndpoint.java
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import org.neo4j.driver.v1.Driver;
@ApplicationScoped
@Path("/hello")
public class HelloWorldEndpoint {
@Inject @Named("neo4jtestprofile")
Driver database;
@GET
@Produces("text/plain")
public Response doGet() {
return Response.ok("Hello from WildFly Swarm! database = " + database).build();
}
}
pom.xml
<properties>
<version.wildfly.swarm>2017.6.0-SNAPSHOT</version.wildfly.swarm>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.neo4j.driver>1.2.1</version.neo4j.driver>
<version.org.glassfish.javax.json>1.0.3</version.org.glassfish.javax.json>
</properties>
NoSQL 91
WildFly Swarm User's Guide
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>bom-all</artifactId>
<version>${version.wildfly.swarm}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-plugin</artifactId>
<version>${version.wildfly.swarm}</version>
<configuration>
<mainClass>org.wildflynosql.demo.rest.Main</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Java EE 7 dependency -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- WildFly Swarm Fractions -->
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs-jsonp</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jsonp</artifactId>
</dependency>
NoSQL 92
WildFly Swarm User's Guide
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>${version.org.glassfish.javax.json}</version>
</dependency>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>${version.neo4j.driver}</version>
</dependency>
</dependencies>
</project>
Logging categories
org.wildfly.nosql - Enable NoSQL subsystem logging.
Common issues
1. Incorrectly spelled profile name causes CDI injection or JNDI lookup, to fail. Correct to
use correct spelling of NoSQL profile name.
NoSQL 93
WildFly Swarm User's Guide
JAX-RS
JAX-RS is a standard JavaEE API for defining web services. It can be used to replace
Servlet -based applications where resources are well-defined, such as in RESTful
architectures.
WildFly Swarm supports JAX-RS with both .war and .jar deployments.
Configuration
To bring JAX-RS functionality to your application, you need the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs</artifactId>
</dependency>
Usage
The jaxrs fraction brings the JAX-RS APIs to your application through a transitive
dependency. It also provides a JAXRSArchive archive type for easily creating JAX-RS-based
deployments if you provide your own main(…) method.
Use of the jaxrs fraction dependency provides a default Application with the
@ApplicationPath annotation if you do not provide one when creating the deployment. If you
JAX-RS 94
WildFly Swarm User's Guide
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>cdi</artifactId>
</dependency>
With this fraction in place, you can inject dependencies into your JAX-RS endpoints using
@Inject , benefit from CDI interceptors and more.
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jaxrs-multipart</artifact>
</dependency>
JAX-RS 95
WildFly Swarm User's Guide
Swagger
Introduction
Swagger is a formal specification for a language-agnostic interface to REST APIs. This
interface lets both humans and computers understand an API’s capabilities such that a
consumer of the API can interact with the service. In simple terms, swagger is a JSON
representation of a RESTful API, typically made available over HTTP at /swagger.json .
{
"swagger":"2.0",
"info":{},
"basePath":"/",
"tags":[{"name":"time"}],
"paths":{
"/time/now":{
"get":{
"tags":["time"],
"summary":"Get the current time",
"description":"Returns the time as a string",
"operationId":"get",
"produces":["application/json"],
"parameters":[],
"responses":{
"200":{
"description":"successful operation",
"schema":{"type":"string"}
}
}
}
}
}
}
WildFly Swarm provides a swagger fraction that enables JAX-RS API developers to easily
publish a /swagger.json describing the API.
Configuration
Swagger 96
WildFly Swarm User's Guide
To enable Swagger in your application, you need to add a dependency to your pom.xml .
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>swagger</artifactId>
</dependency>
Usage
The swagger fraction pulls in required dependencies, and when your application is
deployed, the underlying Swagger system is automatically configured and initialized.
By default, swagger can be used with zero-configuration. This means you can simply
include the swagger fraction in the POM file for your application, and WildFly Swarm will
figure out reasonable defaults. However, if you would like to customize the configuration, this
is possible using ShrinkWrap and SwaggerArchive . Configure this in the main() method for
your application.
deployment.addAllDependencies();
swarm
.fraction(LoggingFraction.createDefaultLoggingFraction())
.start()
.deploy(deployment);
}
}
The packages are recursively scanned, so if you have a package hierarchy, you just need to
set the top level package name. See the SwaggerArchive interface for additional
configuration options.
Swagger 97
WildFly Swarm User's Guide
If you don’t use JAR packaging, like in the example above (no custom Main()), then you
would need to configure swagger through META-INF/swarm.swagger.conf . It allows you to
specify resource packages to be scanned and other atributes, similar to SwaggerArchive in
the previous example.
packages:com.example.rest (1)
root:rest (2)
title:WildFly Swarm Demo (3)
1. resource packages for the swagger annotation scanner (comma delimited, String[])
Swagger UI
The folks over at http://swagger.io have also created an HTML5/JavaScript application for
querying and interacting with swagger-enabled REST APIs. WildFly Swarm provides a
simple way to deploy this application using the Swagger-UI server. See the Servers
documentation for more information.
Swagger 98
WildFly Swarm User's Guide
CDI
The fraction supports CDI (Content & Dependency Injection) which is a handy method for
weaving components together. The primary part of CDI is the @Inject annotation.
Configuration
To use CDI in your application, you need to add the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>cdi</artifactId>
</dependency>
Dependency Injection 99
WildFly Swarm User's Guide
Messaging
The Messaging fraction brings support for JMS to your application. Currently, the messaging
capability does not span across multiple independent WildFly Swarm-based services, but is
only available within a single service.
Configuration
To enable messaging for your application, you need to include the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>messaging</artifactId>
</dependency>
Additionally, you must configure some destinations for the messaging broker to be useful.
This is done through your main(…) function.
swarm.fraction(new MessagingFraction()
.defaultServer( (server)->{
server.topic("my-topic")
server.queue("my-queue");
} );
);
);
Java API
Messaging 100
WildFly Swarm User's Guide
You can use the same Java API as above to create a remote connection to an outboard
message broker, configuring the host, port, and JNDI name for the pooled connection
factory.
Configuration Properties
Additionally, if you only need a single remote connection, it can be completely configured
using Java system properties, or configuration values from project-defaults.yml .
If any of the following properties are set, a remote connection will be created. Any un-set
properties will use their defaults, as long as at least the swarm.messaging.remote flag is set to
true. If any of the other values are configured explicitly, there is no need to also set
swarm.messaging.remote .
Messaging 101
WildFly Swarm User's Guide
swarm.messaging.remote.host localhost
Hostname of the remote
message broker
Messaging 102
WildFly Swarm User's Guide
JSF
JavaServer Faces (JSF) is a standard JavaEE API for developing component based user
interfaces in web applications. It utilizes Facelets as the default templating system, though
JSP is still supported.
WildFly Swarm supports JSF with both .war and .jar deployments.
Configuration
To use JSF in your application, you need to add the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jsf</artifactId>
</dependency>
Usage
The jsf fraction makes the JSF APIs available to your application through a transitive
dependency. There is no need to add them yourself.
JSF 103
WildFly Swarm User's Guide
deployment.addAsWebInfResource(
new ClassLoaderAsset("WEB-INF/web.xml", Main.class.getClassLoader()), "web.xml");
deployment.addAsWebInfResource(
new ClassLoaderAsset("WEB-INF/template.xhtml", Main.class.getClassLoader()), "template.xhtml"
JSF 104
WildFly Swarm User's Guide
Security Realms
Security realms are provided through the management fraction. Security realms can be used
used to secure the management endpoints, but also the monitoring endpoints are even
application level code.
Configuration
To use the management fraction in your application, you need to add the following
dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>management</artifactId>
</dependency>
You may use the InMemoryAuthentication and InMemoryAuthorization plugins for simple
compile-time definition of security-realms. Each of these can be specified programattically or
through user-defined loading of .properties files similar to the default mgmt-
users.properties and mgmt-groups.properties that WildFly normally uses.
new ManagementFraction()
.securityRealm("ManagementRealm", (realm) -> {
realm.inMemoryAuthentication( (authn)->{
authn.add( "admin", "password", true );
});
realm.inMemoryAuthorization( (authz)->{
authz.add( "bob", "admin" );
});
})
If you wish to perform more advanced configuration, please see the JavaDocs for the
Management API.
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>keycloak</artifactId>
</dependency>
Once this is added, you can use the Secured archive type to secure your application. The
easiest way to integrate is by providing a keycloak.json file in your application classpath
and use .as(Secured.class) .
By default, this only adds support, but not a requirement, on Keycloak. Anonymous users
can still access the entire application. If they are authenticated, the SecurityContext will be
populated with the user’s information.
deployment.as(Secured.class)
.protect( "/some-resource" )
.withMethod( "GET" )
.withRoles( "admin" );
swarm:
keycloak:
security:
constraints:
- url-pattern: /some-resource
methods: [GET]
roles: [admin]
Configuration
Property Description
External keycloak.json path. If this
swarm.keycloak.json.path property specified, keycloak.json on
classpath will be ignored.
Keycloak Server
Generally intended to be used as a standalone service, the Keycloak Server is a fraction like
any other in the WildFly Swarm ecosystem.
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>keycloak-server</artifactId>
</dependency>
There is currently no configuration required beyond this. The Keycloak Server will launch
with your application, and be available at the /auth/admin context path.
NetflixOSS
Introduction
Netflix, the online movie streaming company, has invested heavily in microservices. To
support their architectures, they have created many projects that have been integrated into
WildFly Swarm.
Ribbon
Ribbon provides a method for registering services by name, and allowing clients to invoke
those services. One of the primary facilities of Ribbon is client-side load-balancing. With
Ribbon, each client discovers possibly many instances of a given service, and uses a
strategy (such as round-robin) to balance requests to the service across the many providers.
Hystrix
Part of the Netflix strategy for using microservices involves being able to satisfy (for some
value of "satisfy") requests even if remote services are unavailable. Sometimes called a
circuit-breaker, this pattern allows for providing locally-derived fallback responses when the
bonafide service fails to respond.
The Hystrix components work with Ribbon to provide this circuit-breaker functionality.
For instance, in the case of Netflix’s own consumer product, the "recommendations" for a
given movie or television show may be provided by a specific service. If that service is
unavailable, the UI can still provide some default list of recommendations. Everybody loves
The Big Lebowksi, so it could be returned by the Hystrix component if the intelligent
recommendation service is unavailable.
RxJava
RxJava provides a framework for working with asynchronous & reactive components. If one
service needs to invoke an additional 3 services, RxJava provides the way to fire off the
three additional requests and perform work as each completes (or once all have completed).
Netty
Netty is an asynchronous I/O framework maintained by Trustin Lee of Twitter (formerly of
Red Hat). Ribbon uses Netty underneath the covers to perform its network actions. The
primary way that Netty is exposed to users of Ribbon is through the ByteBuf interface,
which provides interaction with bytes sent or received from an I/O stream.
Configuration
To use the Netflix OSS stack within your WildFly Swarm application, you need to add the
following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>ribbon</artifactId>
</dependency>
The necessary components for RxJava, Hystrix and Netty will be transitively made available
to your code.
Usage
In order for your service to participate in the service discovery (as a service to be
discovered, a client performing discovery, or both), your deployment should be converted to
a TopologyArchive at some point.
In the event your deployment has a service you wish to advertise, you subsequently need to
advertise(name) on the resulting TopologyArchive .
deployment.as(TopologyArchive.class)
.advertise();
swarm.deploy( deployment );
If you haven’t named the archive, or wish to advertise it with a distinct service-name, there is
a version of advertise(…) which can take the service name as an argument.
deployment.as(TopologyArchive.class)
.advertise( "recommendations" );
swarm.deploy( deployment );
Secured Ribbon
If your application is using Keycloak to secure your services, and you are using Ribbon to
invoke those services, you’ll want to use the secured variant of Ribbon. This requires a
slightly different dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>ribbon-secured</artifactId>
</dependency>
By using the SecuredRibbon factory, any Keycloak security token will propagate across
invocations of the services using an HTTP Authorization header and a bearer token.
Ribbon Webapp can be used on the client side to secure calls to ribbon services as well.
Just include the keycloak.js Javascript that is provided with the Keycloak server in your
HTML file and call the ribbon constructor function with a keycloak object.
<script src="/ribbon/ribbon.js"></script>
<script src="http://keycloak-server:9191/auth/js/keycloak.js"></script>
<script>
var keycloak = new Keycloak( '/keycloak.json' );
var Ribbon = ribbon( {keycloak: keycloak} );
</script>
Properties
The following properties control ribbon options:
Vert.x
This fraction adds support for the Vert.x API in Java EE applications by enabling the Vert.x
JCA adapter.
Configuration
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>vertx</artifactId>
</dependency>
Usage
There is no need to configure the VertxFraction if you intend to use the default behavior
(JCA adapter deployed and VertxConnectionFactory registered).
Using the Java API you can inhibit the JCA adapter deployment (if you intend to use just the
Vert.x APIs for example).
swarm.fraction(new VertxFraction()
.inhibitAdapterDeployment()
);
You can also modify the VertxConnectionFactory parameters using the same API
swarm.fraction(new VertxFraction()
.jndiName("java:/eis/MyVertxConnectionFactory")
.clusterHost("myhost")
.clusterPort(1000)
);
Overview
The general purpose of a JCA resource adapter is to provide connectivity to an Enterprise
Information System (EIS) from a Java EE application server. Specifically, the Vert.x JCA
adapter provides both outbound and inbound connectivity with a Vert.x instance.
Outbound Connectivity
An application component (e.g Servlet, EJB), can send messages to a Vert.x instance.
Usage:
@Resource(mappedName="java:/eis/VertxConnectionFactory")
VertxConnectionFactory connFactory;
As with any JCA resource, always call the close() method (or use the try-with-
resources strategy above) when your work is complete to allow the connection to be
returned to the pool. This will not close the underlying Vert.x instance. Please see
the JCA specification for more details.
Inbound Connectivity
Since the JCA 1.5 specification, inbound connectivity is provided via a listener interface
which can be implemented by a Java EE Message Driven Bean (MDB). As opposed to the
default JMS listener type, the Vert.x JCA listener interface allows an MDB to receive
messages from a Vert.x address.
package io.vertx.resourceadapter.examples.mdb;
import io.vertx.resourceadapter.inflow.VertxListener;
import io.vertx.core.eventbus.Message;
import java.util.logging.Logger;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import org.jboss.ejb3.annotation.ResourceAdapter;
@MessageDriven(name = "VertxMonitor",
messageListenerInterface = VertxListener.class,
activationConfig = {
@ActivationConfigProperty(propertyName = "address", propertyValue = "tacos"
})
@ResourceAdapter("vertx-ra")
public class VertxMonitor implements VertxListener {
/**
* Default constructor.
*/
public VertxMonitor() {
logger.info("VertxMonitor started.");
}
@Override
public <T> void onMessage(Message<T> message) {
logger.info("Got a message from Vert.x at address: " + message.address());
T body = message.body();
if (body != null) {
logger.info("Body of the message: " + body.toString());
}
}
}
Topology
When building systems of many microservices, being able to locate, discovery and interact
with them in an ever-changing deployment environment can become a challenge. There are
many solutions to managing a topology of services, each with this own trade-offs.
In a pure WildFly scenario, in an environment where multicast is available, many users rely
upon JGroups to handle discovery and reliable communications between nodes. In other
scenarios, either due to the lack of multicast, heterogenuity of services, or scaling concerns,
different service-discovery mechanisms are used. These may include services such as
Apache Zookeeper or Hashicorp’s Consul.
WildFly Swarm attempts to abstract away the many ways of handling service registration
and discovery through its topology fraction. The topology fraction only provides the
abstractions and APIs. It must work in concert with other specific implementations to actually
provide information about the layout of your concrete services.
JGroups
Consul
General Usage
Advertising Services
default, a no-arg version of advertise() will advertise the deployed service using the base
name of the archive.
Additionally, archives can advertise different names, especially in the case where you do not
provide a name when creating the archive.
Annotations
If you wish to be more declarative in advertising services, the
org.wildfly.swarm.topology.Advertise annotation may be applied to arbitrary classes.
Usually you would apply the annotation to a JAX-RS resource, a servlet, or some other
reasonable component that exposes a discoverable service. The annotation may be
repeated in the event you wish to advertise a single service under multiple names.
@Advertise("cheesemonger")
@Advertise("cheese-seller")
public class MyResource {
...
}
Runtime API
If you only want some services to register when they are actually alive, or dynamically
registered based upon runtime knowledge, the Topology interface provides a method,
advertise(…) which can be used within your deployment to advertise a service during any
General
With alladvertisement forms, the service will be registered with the current server’s IP
address, and the appropriate ports for HTTP and HTTPS, if either or both are enabled.
Additionally, if the HTTP port is registered, the service will also be advertised with the tag of
http , and likewise HTTPS services will be tagged as https .
Additionally, the Topology class provides an asMap() method which returns the full current
topology in a Map where the keys are the service names, and the values are a list of
Topology.Entry items, providing access to the host and port.
Configuration
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>topology-jgroups</artifactId>
</dependency>
Using Consul requires having a Consul server and agent strategy already in place. Further
documentation about Consul can be found at https://www.consul.io/.
Configuration
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>topology-consul</artifactId>
</dependency>
Fault tolerance
In order to build a true fault tolerant system, every application host must have a consul agent
running in client mode. This approach avoids hard coded consul host configuration.
For example, if you don’t use this strategy, your application will need to manage the list of
consul server addresses available and update this list when they become unavailable. This
is consul agent work, you don’t need to do this.
So, instead of every application having its own configuration, you must configure one consul
agent per host application. Thereafter, you configure your app to register itself through the
agent. Start both consul client and you application and everything will work properly.
Furthermore, you won’t have a large number of consul servers because they are resource
intensive. Moreover, the maximum number of servers should be 3-5 per datacenter.
However, you can have any number of clients you need, since they are stateless and they
just need a minimum of resources in order to run properly.
Example
Following what was stated above, suppose you have this structure:
a REST API
With this approach, every instance of your application will register itself to consul
agent(client mode) daemon running in localhost(127.0.0.1), like the following picture:
1. Because every host has its own agent, it will be easier to identify in consul what
applications are online or offline because they will be grouped by host;
2. If the consul client(agent) gets offline, only one instance of your application will be
offline as well.
3. Your application will need to know only one consul agent address, therefore, it is pretty
straightforward: localhost;
4. Your application won’t need to manage the consul servers available list, this is agent
job;
5. If you don’t intend to use any implementation of Java Consul clients keeping your
application clean, you can just register your application by configuring the consul
client(agent) config file inside checks section.
The topology-webapp fraction can be added to a service, and it exposes a URL where
external clients can retrieve a topology.js script which will provide topology access within
the browser. The topology.js script also takes advantage of a Server-Sent-Events (SSE)
endpoint that is also published, in order to push changes of the topology in real-time to the
browser.
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>topology-webapp</artifactId>
</dependency>
By including the above dependency, the topology.js script, along with the SSE endpoint
will automatically be mounted under the context-path of /topology in your application.
JavaScript API
The JavaScript API provided by topology-webapp allows clients to open a persistent
connection to the provided servlet. The known service topology is fed to clients as JSON
data, and updated automatically via Server Sent Events as services come up and go down.
Clients can register listeners to respond to these change events. When you include the
topology.js script in your client application, a topology function is added to the global
scope. This function returns a promise which is resolved when initial topology is obtained
and the API is ready to use. Example usage:
topology().then(function(Topology) {
// listen for changes to the service topology
// and update our component on change
Topology.onTopologyChange(function(topology) {
someReactComponent.setState({data: topology});
});
});
The JSON received from this request will look similar to this.
{
"time": [{"endpoint": "http://192.168.0.5:9000","tags":["http"]}, {"endpoint": "http://192.168.0.
"events": [{"endpoint": "http://192.168.0.6:9000","tags":["http"]}, {"endpoint": "http://192.168.
}
That is, the client will receive a JSON object that has service names as keys, and a list of
available servers as values. To call these services, however, clients do not need to know the
host names and ports. Topology Webapp manages these for you. You simply need to know
the service names. The JavaScript API makes 3 asynchronous functions available.
ajax Makes an AJAX request to a known service. This function allows for
You will note that the services are often available on hosts different from the host that served
the webpage and the topology.js script. Web browsers all apply the same-origin policy, so
by default, calling the services will not be possible. The services should send cross-origin
resource sharing HTTP headers to allow cross-origin access.
Transactions
The Transactions fraction brings support for JTA and JTS to your application. This is based
on the Narayana transaction manager and more information on configuring transactions can
be found at http://narayana.io/documentation/index.html
Configuration
To enable transactions for your application, you need to include the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>transactions</artifactId>
</dependency>
By default Narayana uses two TCP ports for recovery and status information in a distributed
environment. These are 4712 and 4713, respectively. However, you can change these
values in your main(…) function.
Note, if you change either or both of these values then you must ensure that all WildFly
Swarm instances participating in the same transaction have these same values.
JTA/JTS 125
WildFly Swarm User's Guide
In order to illustrate the Narayana STM implementation let’s look at one of the WildFly
Swarm examples (https://github.com/wildfly-swarm/wildfly-swarm-
examples/tree/master/arjuna/stm-shrinkwrap). This example will use all of the default
settings for STM so it’s worth knowing that there are a lot of other things you can change
when building your applications. We’ll start by creating a fairly simple STM integer object
which has three methods, increment, decrement and value which do pretty much what their
names imply.
@Transactional
public interface Sample {
public void increment ();
public void decrement ();
STM 126
WildFly Swarm User's Guide
@Transactional
public class SampleLockable implements Sample {
public SampleLockable (int init) {
_isState = init;
}
@ReadLock
public int value () {
return _isState;
}
@WriteLock
public void increment () {
_isState++;
}
@WriteLock
public void decrement () {
_isState--;
}
@State
private int _isState;
}
In the implementation we use some additional annotations to override the default values. For
instance @ReadLock tells the system that the value method isn’t going to change the state
of the instance so only a read lock will be obtained.
STM 127
WildFly Swarm User's Guide
A.begin();
obj1.increment();
A.commit();
}
return str;
STM 128
WildFly Swarm User's Guide
Spring
The Spring Framework is a popular choice for developers that don’t want to use Java EE.
Configuration
To bring Spring functionality to your application, you need the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>spring</artifactId>
</dependency>
If you also require JSON handling, such as returning JSON response documents from a
REST interface, you will need the following dependency instead:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>spring-rest</artifactId>
</dependency>
Usage
The spring and spring-rest fractions provide some special handling for Spring
applications when used with WildFly Swarm, but they do not provide any Spring Framework
dependencies transitively.
Whatever Spring Framework dependencies your application currently requires are still
necessary within your projects' pom.xml .
Spring 129
WildFly Swarm User's Guide
Management
The management fraction supports enabling the WildFly management interface and
specifying security realms.
Configuration
To use the management fraction in your application, you need to add the following
dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>management</artifactId>
</dependency>
You may use the InMemoryAuthentication and InMemoryAuthorization plugins for simple
compile-time definition of security-realms. Each of these can be specified programattically or
through user-defined loading of .properties files similar to the default mgmt-
users.properties and mgmt-groups.properties that WildFly normally uses.
ManagementFraction.createDefaultFraction()
.httpInterfaceManagementInterface((iface) -> {
iface.securityRealm("ManagementRealm");
})
.securityRealm("ManagementRealm", (realm) -> {
realm.inMemoryAuthentication( (authn)->{
authn.add( "bob", "tacos!", true );
});
realm.inMemoryAuthorization( (authz)->{
authz.add( "bob", "admin" );
});
})
If you wish to perform more advanced configuration, please see the JavaDocs for the
Management API.
Properties
The following properties control options for the management interface:
Jolokia
Jolokia is a small utility which provides a JSON-based JMX connector over HTTP. WildFly
Swarm supports a simple method for adding Jolokia to your application.
Adding Jolokia
To bring Jolokia to your application, you need to add a dependency on the Jolokia fraction:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jolokia</artifactId>
</dependency>
If you would like to configure where Jolokia is mounted, you can override the defaults within
your main(…) method:
Adding the Jolokia fraction to your application will bring in the Undertow fraction implicitly if
you have not already included it.
Securing
If you need to secure your Jolokia endpoint (which is highly recommended), the
JolokiaFraction class supports passing in a pre-existing jolokia-access.xml as a file or
swarm.fraction(
new JolokiaFraction()
.jolokiaAccess( "/path/to/jolokia-access.xml" )
);
Jolokia 132
WildFly Swarm User's Guide
Or
swarm.fraction(
new JolokiaFraction()
.jolokiaAccess( (access)->{
access.host( "localhost" );
access.strictChecking();
} )
);
Jolokia 133
WildFly Swarm User's Guide
Monitor
Configuration
To use the monitor fraction in your application, you need to add the following dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>microprofile-health</artifactId>
</dependency>
Node Status
The monitoring fraction provides access to the runtime status on each node. The runtime
information is exposed through a HTTP interface and gives access following information:
{
"name" : "macbook-pro-thomas",
"server-state" : "running",
"suspend-state" : "RUNNING",
"running-mode" : "NORMAL",
"uuid" : "a8100296-573d-4b40-9648-e82bdb0041d9",
"swarm-version" : "2018.3.0"
}
{
"heap-memory-usage" : {
"init" : 268435456,
"used" : 56067784,
"committed" : 356515840,
"max" : 3817865216
},
"non-heap-memory-usage" : {
"init" : 2555904,
"used" : 52717328,
"committed" : 57622528,
"max" : -1
}
}
{
"thread-count" : 33,
"peak-thread-count" : 47,
"total-started-thread-count" : 49,
"current-thread-cpu-time" : 66855000,
"current-thread-user-time" : 64003000
}
{
"outcome": "UP",
"checks": []
}
automatically converted to an application/json response content type and the HTTP status
derived from the HealthStatus.<UP|DOWN> states:
package org.wildfly.swarm.examples.jaxrs.health;
import java.io.File;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.wildfly.swarm.monitor.Health;
import org.wildfly.swarm.monitor.HealthStatus;
@Path("/app")
public class HealthCheckResource {
@GET
@Path("/diskSpace")
@Health
public HealthStatus checkDiskspace() {
File path = new File(".");
long freeBytes = path.getFreeSpace();
long threshold = 1024 * 1024 * 100; // 100mb
return freeBytes>threshold ? HealthStatus.up() : HealthStatus.down().withAttribute(
}
@GET
@Path("/other")
@Health(inheritSecurity = false)
public HealthStatus checkSomethingElse() {
return HealthStatus.up();
}
Accessing the above endpoint will return a json encoded response like this:
{
"freebytes": "1234567890"
}
For instance if you provide an HTTP endpoint for /app/diskSpace , then it will be listed under
/health and accessible through /health/app/diskSpace
curl http://localhost:8080/health
{
"links": [
"/health/app/diskSpace"
]
}
Usually the security for the endpoints behind '/health' will be inherited. (i.e. the security realm
settings you configured) But you can override this policy with
@Health(inheritSecurity=false) .
If security is inherited, then the JAX-RS endpoint annotated with @Health will not be directly
accessible directly anymore (yields HTTP 403). If you don’t inherit the security, it’s up to your
responsibility to secure the endpoint (or leave it unprotected) .
The combinations of using the @Health annotations with regard to the possible HTTP
requests are outlined in the table below:
Configure
Dependency
To add zipkin instrumentation to your WildFly Swarm application, you need to add a
dependency:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>zipkin-jaxrs</artifactId>
</dependency>
Configuration
To configure where the zipkin backend can be found, you need to specify the reportUrl for
the backend to store the tracing data, i.e. 'http://localhost:9411/api/v1/spans'
swarm.fraction(
new ZipkinFraction(<SERVICE_NAME>)
.reportAsync("http://localhost:9411/api/v1/spans")
.sampleRate(0.1f) // keep 10%
);
JGroups
Traditional WildFly includes a subsystem for clustering, so that many instances can work
together to distribute load. Typically, in a WildFly cluster, each node is homogeneous,
serving the same applications.
WildFly Swarm uses the same subsystem but to a different end. With a cluster of WildFly
Swarm services, each service may be unique and distinct. Clustering, in tandem with the
Topology fraction, serves to assist in discovery of other services.
Configuration
To enable clustering, the following dependency is required:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>jgroups</artifactId>
</dependency>
JGroups 140
WildFly Swarm User's Guide
JGroups
The WildFly clustering functionality is built upon JGroups, a reliable group communications
stack. By default, it uses IP multicast to locate other members of the cluster. In environments
where multicast is not supported, other components may be used.
When using clustering with multicast, JGroups must know which interface to use for
multicast packets. By default, your WildFly Swarm application binds to 0.0.0.0
which means all available interfaces. This is ambiguous to JGroups. Therefore,
when clustering you must explicitly bind to some non-ambiguous interface. You can
do this by setting the swarm.bind.address property through the Maven or Gradle
plugins, or via the command-line using -Dswarm.bind.address=w.x.y.z .
JGroups 141
WildFly Swarm User's Guide
Infinispan
The Infinispan subsystem provides high-performance, clustered, transactional caching. For
example, in a clustered web application, client session identifiers and/or data may need to
be replicated across all nodes in the cluster. The failure of a session-oriented HTTP request
requires that client session data is available on the new failover node.
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>infinispan</artifactId>
</dependency>
local-query , local,
Hibernate default,
hibernate entity , invalidation,
Container SYNC , ASYNC
timestamps replicated
Infinispan 142
WildFly Swarm User's Guide
Infinispan is a fairly complex caching system with plenty of knobs and buttons for
programmers and administrators to twiddle. For more information on Infinispan and how its
runtime configuration may be customized, please also see the WildFly documentation and
the official Infinispan Documentation.
Infinispan 143
WildFly Swarm User's Guide
The Wildfly Swarm team provides an add-on that eases the user experience on Swarm.
Installation
From Forge CLI:
From Netbeans:
Go to the Quick Search field in the upper right corner and type Install an Addon from
GIT .
Features
Wildfly-Swarm Setup command
Using the Forge shell, navigate to a Java EE project, or create one using the project-
new --named demo --stack JAVA_EE_7 command and type the following command if you’re
in shell.
wildfly-swarm-setup
This will make the wildfly-swarm-maven plugin to be installed in your project and the
Wildfly Swarm BOM added to the <dependencyManagement> section.
You may also find some options that will be added to the Wildfly Swarm maven plugin
like the context path, the HTTP port and the HTTP Port offset
Installed fractions are not listed when you press <TAB> to auto-complete
import org.junit.runner.RunWith;
import org.jboss.arquillian.junit.Arquillian;
import org.wildfly.swarm.arquillian.DefaultDeployment;
import org.junit.Test;
@RunWith(Arquillian.class)
@DefaultDeployment
public class HelloWorldEndpointTest {
@Test
public void should_start_service() {
}
}
Swarmtool
Swarmtool is a standalone jar that is used to wrap an existing JAR or WAR file in a -
swarm.jar without requiring any other tooling.
Usage
To use swarmtool, you’ll first need to download the standalone jar for the WildFly Swarm
version you are using. You can get it from Maven Central with the following (or the
equivalent command on your system):
curl https://repo1.maven.org/maven2/org/wildfly/swarm/swarmtool/2017.11.0-SN
This jar file is executable on systems that provide /bin/sh , so you if you are on one of
those systems, you can rename it to something nicer (like swarmtool ), and execute it with:
swarmtool path-to-war
If that isn’t an option for you, you can always execute it with java -jar :
Command-line Options
Name Description
SwarmTool 147
WildFly Swarm User's Guide
Fraction Detection
SwarmTool 148
WildFly Swarm User's Guide
Swarmtool will attempt to auto-detect needed fractions by scanning the WAR file. You can
augment the list of fractions it will include with the --fractions option, and you can disable
fraction detection completely with --no-fraction-detect . Note that in that case, you will
have to specify all needed fractions with --fractions . Any fractions specified via --
fractions will override any corresponding fractions that are discovered.
Properties
Many properties may be used to configure execution and affect the packaging or running of
your application.
You can use the --properties-file or -D options to specify system properties that will be
stored within the -swarm.jar and applied when running your application.
Any properties added to the uberjar can of course be overridden at runtime using the
traditional -Dname=value mechanism of java .
SwarmTool 149
WildFly Swarm User's Guide
Pre-built Servers
The WildFly Swarm project has pre-built some standalone servers. The source for these
reside in the standalone-servers portion of the repository.
MicroProfile
Keycloak
Swagger UI
Management Console
MicroProfile
MicroProfile is a new effort that is underway which attempts to refine the enterprise Java
specifications for use in microservices.
JAX-RS
JSON-P
CDI
Download
You can download the server here.
Usage
MicroProfile 151
WildFly Swarm User's Guide
Keycloak Server
The WildFly Swarm project has built a standalone uberjar for running Keycloak Server.
<dependency>
<groupId>org.wildfly.swarm.servers</groupId>
<artifactId>keycloak</artifactId>
<classifier>swarm</classifier>
</dependency>
Download
Download or otherwise obtain the -swarm.jar and simply execute it as any other service
created with WildFly Swarm.
Usage
java -jar keycloak-2017.11.0-SNAPSHOT-swarm.jar
Swagger UI Server
Swagger UI is a dependency-free collection of HTML, Javascript, and CSS assets that
dynamically generate documentation and sandbox from a Swagger-compliant API. WildFly
Swarm provides an easily deployable and customizable version of this application.
<dependency>
<groupId>org.wildfly.swarm.servers</groupId>
<artifactId>swagger-ui</artifactId>
<classifier>swarm</classifier>
</dependency>
You can customize any of the HTML, CSS, JavaScript or image assets provided by the
server by specifying these on the command line. The command line will accept a path to a
jar or war file on disk, a path to a directory on disk containing your web resources, or
The jar file provided (or the directory on disk) will be overlaid on to the resources provided
by swagger-ui . For example, to customize the main page, provide an index.html file at the
root of the jar or war file, or in the top level of the directory provided.
Swagger UI 153
WildFly Swarm User's Guide
Management Console
The management console is a standalone Web application that allows you to connect to a
management interface of a running WildFly or WildFly Swarm instance.
Configuration
To enable the Management console in your application, you need to add the following
dependency to your Swarm application:
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>management-console</artifactId>
</dependency>
Usage
Using the Java API, you can change the management console context root (default is
/console )
swarm.fraction(new ManagementConsoleFraction()
.contextRoot("/general-console")
);
Additional Reading
The following is a list of resources that we can recommend to get you started.
Online articles
Eberhard Wolff, "Microservices Primer"
Microservice Books
Sam Newman. "Building Microservices"
WildFly Swarm
Homepage
Blog
OpenShift
OpenShift Origin
Getting Involved
WildFly Swarm is an open-source project sponsored by Red Hat, Inc.
Source Code
WildFly Swarm’s source-code is completely open and hosted on GitHub under the WildFly
Swarm organization:
https://github.com/wildfly-swarm
Documentation
This documentation is also maintained on GitHub and published using GitBooks.io.
https://github.com/wildfly-swarm/wildfly-swarm-users-guide
https://issues.jboss.org/browse/SWARM
Chat
You can find us in #wildfly-swarm on Freenode.
Implementation Details
This chapter mostly serves as a road-map for users who are curious about the actual inner
workings of WildFly Swarm.
Uberjar Layout
The layout of the generated myapp-swarm.jar looks roughly like:
wildfly-swarm.properties
File containing all user-specified (or default) properties to be used when executing the
uberjar. For example:
META-INF/wildfly-swarm-bootstrap.conf
Lists all WildFly Swarm module dependencies in Maven GAV format. For example:
org.wildfly.swarm:logging-modules:2017.11.0-SNAPSHOT
org.wildfly.swarm:security-modules:2017.11.0-SNAPSHOT
org.wildfly.swarm:hystrix:2017.11.0-SNAPSHOT
org.wildfly.swarm:rxnetty:2017.11.0-SNAPSHOT
org.wildfly.swarm:rxjava:2017.11.0-SNAPSHOT
org.wildfly.swarm:ee-modules:2017.11.0-SNAPSHOT
org.wildfly.swarm:logstash-modules:2017.11.0-SNAPSHOT
org.wildfly.swarm:ribbon-secured-modules:2017.11.0-SNAPSHOT
META-INF/wildfly-swarm-application.conf
module:org.wildfly.swarm.keycloak
module:org.wildfly.swarm.netflix.ribbon.secured
module:org.wildfly.swarm.security
module:org.wildfly.swarm.logstash
module:org.wildfly.swarm.netflix.ribbon
gav:org.wildfly.swarm:undertow:2017.11.0-SNAPSHOT
gav:org.wildfly.swarm:io:2017.11.0-SNAPSHOT
gav:io.netty:netty-transport:4.0.27.Final
gav:io.netty:netty-buffer:4.0.26.Final
gav:org.wildfly.swarm:clustering:2017.11.0-SNAPSHOT
gav:javax.json:javax.json-api:1.0
gav:io.reactivex:rxnetty:0.4.9
META-INF/MANIFEST.MF
Standard Java archive manifest which specifies the WildFly Swarm bootstrap Main-
Class along with tracking the user-provided main class. For example:
Main-Class: org.wildfly.swarm.bootstrap.Main
Wildfly-Swarm-Main-Class: org.mycorp.myapp.Main
_bootstrap/
Bootstrap
When the myapp-swarm.jar is executed through java -jar , the
org.wildfly.swarm.bootstrap.Main class is always executed initially. It initializes the JBoss-
It then loads the user-provided main-class from the artifact in the _bootstrap/ directory and
executes it.
ClassLoaders
Conceptually there are 3 classloader spaces in a WildFly Swarm uberjar.
The first is the system classloader, which is used initially when bootstrapping the core
Main .
Thirdly, the Container configuration is passed to the back-end classloader which then
converts the simple POJO configuration objects into the appropriate control structures used
to initialize the WildFly container.
When a user-provided main-class is executed directly from an IDE, the first two conceptual
classloaders are actually both satisfied by the system ClassLoader .
Fraction Authoring
Introduction
The composable pieces of WildFly Swarm are called fractions. Each fraction starts with a
single Maven-addressable artifact which may transitively bring in others.
The pom.xml
It is useful to set at least a pair of properties, specifying the version of the WildFly Swarm
SPI and fraction-plugin being used:
<properties>
<version.swarm>2017.7.0</version.swarm>
<version.swarm.fraction-plugin>57</version.swarm.fraction-plugin>
</properties>
You can include all of the primary bits of WildFly Swarm using the bom-all artifact in a
<dependencyManagement> import. Additionally, you’ll need two more dependencies added in
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>bom-all</artifactId>
<version>${version.swarm}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.wildfly.swarm</groupId>
<artifactId>wildfly-swarm-fraction-plugin</artifactId>
<version>${version.swarm.fraction-plugin}</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
What’s in a Fraction
A "fraction" can include all or none of the following components. Ultimately a fraction
contributes configuration or capabilities to a runtime system.
Package Layout
For a given fraction, a unique package root is required. In the usual case of the core code, it
matches the pattern of org.wildfly.swarm.CAPABILITY , such as org.wildfly.swarm.undertow
or org.wildfly.swarm.naming .
deployment
detect
internal
runtime
The module.conf
Alongside your pom.xm you need at least an empty module.conf file to signal the plugin
that your build is actually a fraction.
This file is used to enumerate the JBoss-Modules dependencies your fraction may have, and
helps produce the resulting module.xml files for your fraction.
In this file, one per line, you may list the module dependencies you may have. If your fraction
relies on runtime linking to other fractions, they should typically be listed in this file.
org.jboss.logging
org.wildfly.swarm.undertow
org.fluentd:fluent-logger:${fluentd.version}
org.msgpack:msgpack:0.6.8
com.googlecode.json-simple:json-simple:1.1.1
org.javassist:javassist:3.18.1-GA
org.slf4j:slf4j-api:1.7.7.jbossorg-1
org.jboss.logmanager:jboss-logmanager-ext:${version.jboss-logmanager-ext}
<resources>
<artifact name="org.fluentd:fluent-logger:${fluentd.version}"/>
<artifact name="org.msgpack:msgpack:0.6.8"/>
<artifact name="com.googlecode.json-simple:json-simple:1.1.1"/>
<artifact name="org.javassist:javassist:3.18.1-GA"/>
<artifact name="org.slf4j:slf4j-api:1.7.7.jbossorg-1"/>
<artifact name="org.jboss.logmanager:jboss-logmanager-ext:${version.jboss-logmanager-ext}"
</resources>
<dependencies>
<module name="org.jboss.logmanager"/>
<module name="javax.json.api"/>
<module name="javax.xml.stream.api"/>
</dependencies>
</module>
For more information on the syntax of the JBoss-Modules module.xml descriptor, see
https://jboss-modules.github.io/jboss-modules/manual/.
Generated modules
The wildfly-swarm-fraction-plugin generates a number of module.xml descriptors depending
on what features it has found in the faction. You may override any one of these descriptors
by providing the corresponding module.xml in your src/main/resources/modules directory.
api: this is a module definition that depends on all modules specified in module.conf +
swarm container and cdi modules, the fraction artifact, excluding the <fraction-root-
package>/{runtime,deployment} packages if they exist. It is used to configure fractions,
container, etc, when running in Uber jar mode when JBoss-Modules is fully active
main: This is a module definition similar to API, but active when running from IDE or
wildfly-swarm:run
runtime: this is a module definition that depends on the fraction artifact with the root
excluded, the main module, swarm and cdi modules, and all modules in module.conf.
This module is used to load the fraction and any of its runtime code. These modules are
what JBoss Modules loads for use by the WF self contained server to make extensions,
subsystems, etc available for the deployment.
The *Fraction.java
If the fraction includes configuration capabilities, or otherwise alters the runtime system
through deployments or adjustments to the server, it may include an implementation of
org.wildfly.swarm.spi.api.Fraction .
Any opaque POJO configuration details that are required may be added in the
implementation, and will be made available to the back-end runtime portion during server
boot-up to control configuration.
package com.mycorp.cheese;
import java.util.Set;
import java.util.HashSet;
import org.wildfly.swarm.spi.api.Fraction;
Typically these components would, at the minimum, inject their own fraction. They should
each be marked as @Singleton .
@Singleton
public class MyComponents implements Whatever {
@Inject
private MyFraction myFraction;
DeploymentProcessor
If your fraction needs an opportunity to alter or otherwise prepare all deployed archives, you
may implement the org.wildfly.swarm.spi.api.DeploymentProcessor interface.
@DeploymentScoped
public class MyArchivePreparer implements DeploymentProcessor {
@Inject
private MyFraction myFraction;
@Inject
public MyArchivePreparer(Archive archive) {
this.archive = archive;
}
@Override
public void process() throws Exception {
WARArchive war = archive.as(WARArchive.class);
...
}
}
Useful Annotations
There are a few additional annotations that you may include on your fraction class:
Injecting IndexView
If your fraction needs an opportunity to process the Jandex metadata of all deployed
archives, you can inject org.jboss.jandex.IndexView into your DeploymentProcessor
instance, e.g.
@DeploymentScoped
public class ServiceClientProcessor implements DeploymentProcessor {
private final Archive<?> archive;
private final IndexView index;
@Inject
public ServiceClientProcessor(Archive archive, IndexView index) {
this.archive = archive;
this.index = index;
}
}
Customizer
If your fraction is always present with other fractions, cross-fraction manipulation may be
achieved.
Two different executions of Customizers occur. All customizers annotated with @Pre are
fired, followed by all annotated with @Post .
@Post
@Singleton
public class MyCustomizer implements Customizer {
@Inject
private MyFraction myFraction;
@Inject
private UndertowFraction undertowFraction;
Archive producers
In some cases, a fraction implicitly produces a deployment archive by its simple presence in
the dependency graph. For example, including org.wildfly.swarm:jolokia ensures that the
Jolokia web-app is deployed. This is accomplished by having a CDI component that
@Produces a ShrinkWrap Archive . No particular interface is required to be implemented.
@Singleton
public MyArchiveProducers {
@Inject
private MyFraction myFraction;
@Produces
Archive myManagementConsole() {
WARArchive archive = ... // produces the Archive any way you like
archive.setContextRoot( myFraction.getContextRoot() );
return archive;
}
}
@Inject @ConfigurationValue('my.db.url')
private String dbUrl;
@Inject @ConfigurationValue('my.age')
private int age;
Transitive dependencies
If your fraction depends upon the presence of a Servlet container being configured, you
should add a dependency on the necessary fractions into your pom.xml
<dependencies>
<dependency>
<groupId>org.wildfly.swarm</groupId>
<artifactId>undertow</artifactId>
</dependency>
</dependencies>
By doing this, a user must only include your fraction, and the Undertow fraction will be
dragged along implicitly into their application.