1. What is Open Liberty?
OpenLiberty is a lightweight open framework for building fast and efficient cloud-native Java microservices. It supports some of the most popular Java standards today, including:
-
Java EE 7 and 8
-
Microprofile 1.X, 2.X, and 3.X
-
Spring Boot 1.5 and 2.0
2. TL;DR info
-
Get OpenLiberty using Maven/Gradle/Docker here: https://openliberty.io/downloads/
-
Create server:
<liberty-root>/bin/server create myServer
-
Start server:
<liberty-root>/bin/server start myServer
-
Main config file:
<liberty-root>/usr/servers/myServer/server.xml
-
Default app folder:
<liberty-root>/usr/servers/myServer/dropins/
-
Default ports: http=9080, https=9443
-
Enable only the features you need for smaller disk/memory footprint and faster start time
-
Develop apps using "dev mode" using the Liberty Maven Plugin
mvn liberty:dev
goal -
Lots of useful guides here: https://openliberty.io/guides/
3. Getting Started
Generate a basic Liberty project using the MicroProfile Starter website:
-
Select "MicroProfile 3.0" for MicroProfile version
-
Select "OpenLiberty" for MicroProfile Runtime
-
Select any example specifications you want to be included
-
Download and extract the project, then import into your preferred IDE
This creates a Maven project with a simple JAX-RS resource class in it:
@Path("/hello")
@Singleton
public class HelloController {
@GET
public String sayHello() {
return "Hello World";
}
}
You can start the application in "dev mode" using the command:
mvn liberty:dev
Then open a web browser to http://localhost:8181/data/hello to access the JAX-RS endpoint. You will see the text Hello World
.
If you make code changes the application will automatically be updated.
If you add tests to the project, you can run them from dev mode by pressing the Enter
key. To exit dev mode press Ctrl+C
.
A more detailed Getting Started walkthrough can be found in the OpenLiberty Maven guide.
4. Configuration
The primary source of configuration for a Liberty server is the server.xml
file. In most projects it is located at src/main/liberty/config/server.xml
and might look like this:
<server>
<featureManager>
<feature>servlet-4.0</feature>
</featureManager>
<httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443"/>
<webApplication location="test.war" name="test"/>
</server>
For more info see: OpenLiberty server configuration overview
4.1. Dynamic Configuration
All configuration in server.xml
is dynamic by default, meaning that if you modify it while the server is running, the server will automatically update to account for the change — typically in a few milliseconds.
4.2. Variable Substitution
Server configuration can be parameterized using variables. When resolving variable names the following sources are consulted in decreasing order of precedence:
-
The value in the
<variable value="…"/>
attribute -
Java system properties (i.e. jvm.options)
-
bootstrap.properties
-
environment variables
-
The value in the
<variable defaultValue="…"/>
attribute
Variables are referenced using ${variableName}
syntax. In server config, specify variables using the variable element:
<variable name="variableName" value="some.value" />
Default values, specified in server config, are only used if no other value can be found. They are specified using the variable element and the defaultValue
attribute:
<variable name="DB_SERVER" defaultValue="localhost"/>
4.3. Predefined Variables
-
${wlp.install.dir}
- the location where the Liberty runtime is installed. -
${wlp.server.name}
- the name of the server. -
${wlp.user.dir}
- the location of the usr folder. Defaults to ${wlp.install.dir}/usr. -
${shared.app.dir}
- the location of shared applications. Defaults to ${wlp.user.dir}/shared/apps. -
${shared.config.dir}
- the directory that contains the server config. Defaults to ${wlp.user.dir}/shared/config. -
${shared.resource.dir}
- the location of shared resource files. Defaults to ${wlp.user.dir}/shared/resources. -
${server.config.dir}
- the directory that server config is stored in. Defaults to ${wlp.user.dir}/servers/${wlp.server.name}. -
${server.output.dir}
- the directory that the server writes the workarea, logs and other runtime generated files to. Defaults to ${server.config.dir}.
4.4. MicroProfile Config
MicroProfile Configuration is a simple yet powerful way to externalize configuration in any application.
In OpenLiberty, there are 5 builtin configuration sources:
-
A
<variable name="…" value="…"/>
element in server.xml (ordinal = 500) -
System Properties, jvm.options, or bootstrap.properties (ordinal = 400)
-
Environment variables or server.env (ordinal = 300)
-
Inside application at
/META-INF/microprofile-config.properties
(ordinal = 100) -
Annotation
@ConfigProperty
withdefaultValue
(no ordinal)
To inject a config property into your application (regardless of the configuration source) you can use the following code:
@ApplicationScoped
public class MyService {
@Inject
@ConfigProperty(name = "foo", defaultValue = "bar")
String fooProperty;
For more info, see this OpenLiberty guide: Separating configuration from code in microservices
4.5. Configuration Secrets
If you are running your application in Kubernetes, you don’t want to have credentials exposed as simple environment variables, and you certainly don’t want them checked in with the rest of your application source code!
First, configure a Kubernetes secret, for example database-credentials
with the contents:
my-app.db.username=dbUser
my-app.db.password=dbPass
Then, you can inject the Kubernetes secret contents into a a boostrap.properties
file that contains sensitive information as follows:
kind: Deployment
apiVersion: apps/v1beta1
metadata:
name: my-app
spec:
# ...
containers:
- name: my-app
image: ...
volumeMounts:
- name: database-credentials-volume
mountPath: /opt/wlp/usr/servers/defaultServer/bootstrap.properties
subPath: bootstrap.properties
readOnly: true
volumes:
- name: database-credentials-volume
secret:
secretName: database-credentials
Finally, the secrets can then be referenced in server configuration using variables:
<dataSource ...>
<properties ...
user="${my-app.db.username}"
password="${my-app.db.password}"/>
</dataSource>
5. Features
The features enabled for a Liberty server are listed in the <featureManager>
element. A Liberty feature may include other Liberty features. For example, the jsp-2.3
feature pulls in the servlet-4.0
feature, and the webProfile-8.0
feature pulls in all of the features for Java EE 8 Web Profile.
Tip
|
Only enable the features that you need! While it may be convenient to enable "convenience" features like javaee-8.0 initially, over time you should only enable features that your application actually needs. Less features = faster startup and lower disk/memory footprint
|
Some of the most common Liberty features are:
5.1. Java EE 8
-
webProfile-8.0
: Enables all features in Java EE 8 Web profile: Bean Validation 2.0, CDI 2.0, EJB Lite 3.2, EL 3.0, JAX-RS 2.1, JNDI 1.0, JPA 2.2, JSF 2.3, JSON-B 1.0, JSON-P 1.1, JSP 2.3, Servlet 4.0, WebSocket 1.1 -
javaee-8.0
: Enables all features in Java EE 8 Full Profile:webProfile-8.0
plus Java Batch 1.0, EE Concurrency 1.0, EJB 3.2, JavaMail 1.6, JAX-WS 2.2, JCA 1.7, JMS 2.0 -
jaxrs-2.1
: Java XML RESTful Web Services (JAX-RS) 2.1 -
cdi-2.0
: Context Dependency Injection (CDI) 2.0 -
jpa-2.2
: Java Persistence Architecture (JPA) 2.2 -
jsf-2.3
: Java Server Faces (JSF) 2.3 -
jsonb-1.0
: JSON Binding (JSON-B) 1.0 -
servlet-4.0
: Servlet 4.0
5.2. Java EE 7
-
webProfile-7.0
: Enables all features in Java EE 7 Web Profile -
javaee-7.0
: Enables all features in Java EE 7 Full Profile
Warning
|
You cannot mix Java EE 7 and 8 features in the same server.xml! |
5.3. MicroProfile 3.2
-
microProfile-3.2
: Enables all features in MicroProfile 3.2 platform -
cdi-2.0
-
jaxrs-2.1
-
jsonb-1.0
-
mpConfig-1.4
: MicroProfile Config 1.4 -
mpHealth-2.1
: MicroProfile Health 2.1 -
mpMetrics-2.2
: MicroProfile Metrics 2.2 -
mpRestClient-1.3
: MicroProfile REST Client 1.3
A complete list of all Liberty features can be found here: OpenLiberty Server Features
6. Maven
Add the maven plugin to your pom.xml file:
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.1</version>
</plugin>
Some of the essential maven commands are:
-
mvn liberty:dev
: Starts your Liberty server in "dev mode" which runs the application and automatically updates it whenever you save changes to the source code or configuration -
mvn liberty:run
: Starts your Liberty server in the foreground. Stop it withCtrl+C
-
mvn liberty:start
: Starts your Liberty server in the background -
mvn liberty:stop
: Stops your Liberty server that was started usingliberty:start
Create an application using an OpenLiberty Maven archetype:
-
Servlet/JSP web application:
mvn archetype:generate -DarchetypeGroupId=io.openliberty.tools -DarchetypeArtifactId=liberty-archetype-webapp -DarchetypeVersion=3.2.2 -DgroupId=com.example -DartifactId=myapp -Dversion=1.0-SNAPSHOT -B
Also see:
7. Gradle
Add the following snippet to your build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'net.wasdev.wlp.gradle.plugins:liberty-gradle-plugin:2.7'
}
}
apply plugin: 'war'
apply plugin: 'liberty'
dependencies {
libertyRuntime group:'io.openliberty', name:'openliberty-runtime', version:'19.0.0.12'
}
Some of the essential gradle tasks are:
-
./gradlew libertyRun
: Starts your Liberty server in the foreground. Stop it withCtrl+C
-
./gradlew libertyStart
: Starts your Liberty server in the background -
./gradlew libertyStop
: Stops your Liberty server that was started usingliberty:start
Also see:
8. Docker
The basic Liberty Dockerfile looks like this:
FROM openliberty/open-liberty:full-java8-openj9-ubi
COPY src/main/liberty/config /config/
ADD target/myApp.war /config/dropins
# Running configure.sh takes ~20s at docker build time but will greatly reduce
# container start time. You may not want to run this for local development if
# you are constantly changing the app layer, but should used for production
RUN configure.sh
There are also base layers using Java 11 and 13 which can be found here: OpenLiberty Docker Hub
For complete documentation on OpenLiberty Docker containers, see: OpenLiberty/ci.docker Github
9. Supported Java versions
OpenLiberty is currently supported on Java SE 8, 11, and 13. Official documentation can be found here: JavaSE support
10. Databases
This is the most common base configuration for using a JDBC DataSource (or JPA) with Liberty:
<featureManager>
<feature>jdbc-4.2</feature>
</featureManager>
<library id="jdbcLib">
<fileset dir="/path/to/driver/dir" includes="*.jar"/>
</library>
10.1. Validating Connections
OpenLiberty has a REST API to test database connections. To use it, add this config:
<featureManager>
<feature>appSecurity-3.0</feature>
<feature>restConnector-2.0</feature>
<feature>jdbc-4.2</feature>
</featureManager>
<!-- Any security mechanism can be used, <quickStartSecurity> is the simplest -->
<quickStartSecurity userName="admin" userPassword="admin"/>
<dataSource id="DefaultDataSource">
<!-- the rest of your datasource config... -->
</dataSource>
To validate a connection, go to the URL: https://{hostname}:{httpsPort}/ibm/api/validation/dataSource/{dataSource-id}
In the above example, that would be: https://localhost:9443/ibm/api/validation/dataSource/DefaultDataSource
For a complete walkthrough, see this blog post: Testing database connections with REST
10.2. PostgreSQL
<dataSource id="DefaultDataSource" jndiName="jdbc/myDB">
<jdbcDriver libraryRef="jdbcLib"/>
<properties.postgresql serverName="localhost" portNumber="5432"
databaseName="myDB"
user="exampleUser"
password="examplePassword"/>
</dataSource>
To run a Postgres Docker container locally:
docker run -it --rm=true --memory-swappiness=0 --ulimit memlock=-1:-1 \
--name postgres-liberty \
-e POSTGRES_USER=exampleUser \
-e POSTGRES_PASSWORD=examplePassword \
-e POSTGRES_DB=myDB \
-p 5432:5432 postgres:10.5
10.3. IBM DB2
<dataSource id="DefaultDataSource" jndiName="jdbc/test">
<jdbcDriver libraryRef="jdbcLib"/>
<properties.db2.jcc serverName="localhost" portNumber="50000"
databaseName="test"
user="db2inst1"
password="foobar1234"/>
</dataSource>
To run a DB2 Docker container locally:
docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 \
--name db2-liberty \
-e AUTOCONFIG=false -e ARCHIVE_LOGS=false -e LICENSE=accept \
-e DBNAME=test \
-e DB2INSTANCE=db2inst1 \
-e DB2INST1_PASSWORD=foobar1234 \
-p 50000:50000 \
--privileged \
ibmcom/db2:11.5.0.0a
10.4. Microsoft SQL Server
<dataSource id="DefaultDataSource" jndiName="jdbc/myDB">
<jdbcDriver libraryRef="jdbcLib"/>
<properties.microsoft.sqlserver serverName="localhost" portNumber="1433"
databaseName="tempdb"
user="sa"
password="examplePassw0rd"/>
</dataSource>
To run a SQL Server Docker container locally:
docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 \
--name mssql-liberty \
-e ACCEPT_EULA=Y \
-e SA_PASSWORD=examplePassw0rd \
-p 1433:1433 \
mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
10.5. MySQL
<dataSource id="DefaultDataSource" jndiName="jdbc/myDB">
<jdbcDriver libraryRef="jdbcLib"/>
<properties serverName="localhost" portNumber="3306"
databaseName="myDb"
user="exampleUser"
password="examplePassword"/>
</dataSource>
To run a MySQL Docker container locally:
docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 \
--name mysql-liberty \
-e MYSQL_DATABASE=myDB \
-e MYSQL_USER=exampleUser \
-e MYSQL_PASSWORD=examplePassword \
-p 3306:3306 \
mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
10.6. Oracle
<dataSource id="DefaultDataSource" jndiName="jdbc/myDB">
<jdbcDriver libraryRef="jdbcLib"/>
<properties.oracle URL="jdbc:oracle:thin:@//localhost:1521/myDB"/>
</dataSource>
10.7. Derby (in-memory DB)
JDBC driver available at: Maven Central
<dataSource id="DefaultDataSource" jndiName="jdbc/myDB">
<jdbcDriver libraryRef="jdbcLib"/>
<properties.derby.embedded databaseName="memory:myDB" createDatabase="create"/>
</dataSource>
11. Messaging
Applications can pass messages among themselves with the Java Message Service (JMS) APIs. These APIs allow applications to produce messages that are placed on a destination and/or consuming messages from a destination. Liberty can act as a server of JMS destinations or it can connect to another server to access those destinations. JMS defines two core types of destinations: queues, and topics.
Some terms commonly used in JMS:
-
Message: Information that is being sent via JMS. Payload can be any kind of data, from plain text and numbers to serialized Java objects.
-
Destination: A specific place for messages to be stored and retrieved by name. Common types are queues and topics.
-
Queue: A destination where each message is delivered to the first consumer to receive a message.
-
Topic: A destination where each message is delivered to all consumers subscribed to it.
-
Producer: Any code that produces a message onto a JMS destination.
-
Consumer: Any code that subscribes to a destination and receives messages from it.
11.1. JMS Server
Liberty can act as a JMS server whether or not it is serving any applications using the wasJmsServer-1.0
feature.
<featureManager>
<feature>wasJmsServer-1.0</feature>
</featureManager>
<messagingEngine>
<queue id="myQueue" />
<topicSpace id="myTopicSpace" />
</messagingEngine>
The messagingEngine
element defines all JMS destinations served by Liberty. Note that topics are organized into topic spaces here—the individual topics are created and subscribed to by the applications or by defining administered objects representing them in the JMS client.
If you want applications on other servers to connect to your JMS server, create a <wasJmsEndpoint>
. Without this, only applications served by the same Liberty server can acccess the JMS destinations.
<wasJmsEndpoint host="*" wasJmsPort="7276" wasJmsSSLPort="7286" />
11.2. JMS Client
Liberty allows applications to connect to both local and remote JMS destinations. Local connections will also need the JMS server config from the previous section. To connect to either Liberty JMS servers or traditional WebSphere Service Integration Bus, use the wasJmsClient
feature. The feature has two versions, 1.1 and 2.0, that correspond to the matching versions of the jms
feature.
<featureManager>
<feature>wasJmsClient-2.0</feature>
<feature>jms-2.0</feature>
</featureManager>
<jmsConnectionFactory jndiName="jms/localCF">
<properties.wasJms />
</jmsConnectionFactory>
<jmsConnectionFactory jndiName="jms/remoteCF">
<properties.wasJms remoteServerAddress="example.com:7276:BootstrapBasicMessaging" />
</jmsConnectionFactory>
The format for remoteServerAddress
is hostname:port:transportChain
, where transportChain
is either BootstrapBasicMessaging
for non-secure JMS endpoints or BootstrapSecureMessaging
for secure JMS endpoints. You can optionally omit the :transportChain
portion of the address if you are using BootstrapBasicMessaging
.
Liberty can provide administered objects for queues and topics that applications can use. This is where a topic can be subscribed to within a specific topic space on the JMS server. Applications can use these objects both to produce messages on the destination and consume messages from the destination.
<jmsTopic jndiName="jms/jmsLocalTopic">
<properties.wasJms topicName="myTopic" topicSpace="myTopicSpace" />
</jmsQueue>
<jmsQueue jndiName="jms/jmsRemoteQueue">
<properties.wasJms queueName="myQueue" />
</jmsQueue>
11.3. IBM MQ Client
Liberty can connect to IBM MQ servers and other messaging servers (e.g. ActiveMQ or RabbitMQ) with the appropriate resource adapter. You don’t need the wasJmsClient
feature to connect to these servers. Be sure to read the documentation for your resource adapter and ensure it is configured properly to connect to the server. The following example will use IBM MQ.
<featureManager>
<feature>jms-2.0</feature>
</featureManager>
<!-- The IBM MQ resource adapter is available here: -->
<resourceAdapter id="mqJmsRa" location="/path/to/wmq.jmsra.rar">
<classloader apiTypeVisibility="+third-party"/>
</resourceAdapter>
<jmsQueueConnectionFactory id="myRemoteQueueConnectionFactory" jndiName="jms/mqRemoteQCF">
<properties.mqJmsRa channel="DEV.APP.SVRCONN" hostName="localhost" port="1414" queueManager="mqtest"/>
</jmsQueueConnectionFactory>
<jmsQueue id="myMQQueue" jndiName="jms/mqRemoteQueue">
<properties.mqJmsRa baseQueueManagerName="mqtest" baseQueueName="DEV.QUEUE.1"/>
</jmsQueue>
<jmsTopicConnectionFactory id="myRemoteTopicConnectionFactory" jndiName="jms/mqRemoteTCF">
<properties.mqJmsRa channel="DEV.APP.SVRCONN" hostName="localhost" port="1414" queueManager="mqtest" clientId="myClientId"/>
</jmsTopicConnectionFactory>
<jmsTopic id="myMQTopic" jndiName="jms/mqRemoteTopic">
<properties.mqJmsRa baseQueueManagerName="mqtest" baseTopicName="dev1/"/>
</jmsTopic>
To run an MQ Docker container locally:
docker run -it --rm=true --name mq-liberty \
-e LICENSE=accept \
-e MQ_QMGR_NAME=mqtest \
-e MQ_ADMIN_PASSWORD=testpassword \
-p 1414:1414 \
-p 9443:9443 \
ibmcom/mq:9.1.4.0
11.4. Exchanging JMS Messages
Regardless of how you configure your administered objects and what server they connect to, you will access them within your application in the same way. Obtain the destination and connection factory using JNDI, then use the connection factory to create a connection, use the connection to create a session, and use the session to create a producer and/or consumer that can interact with the destination.
import javax.jms.*;
// Note: In managed components (CDI beans, servlets, EJBs, etc) lookups can be replaced with @Resource annotations
QueueConnectionFactory factory = InitialContext.doLookup("jms/mqRemoteQCF");
Queue queue = InitialContext.doLookup("jms/mqRemoteQueue");
QueueConnection connection = factory.createQueueConnection();
QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
// Send a message to the queue
TextMessage message = session.createTextMessage("Your Message Here");
MessageProducer producer = session.createProducer(queue);
producer.send(message);
producer.close();
// Receive a message from the queue
MessageConsumer consumer = session.createConsumer(queue);
TextMessage result = (TextMessage) consumer.receieve(5000L);
System.out.println("Got " + result);
consumer.close();
session.close();
conn.close();
11.5. Reactive Messaging
MicroProfile Reactive Messaging (mpReactiveMessaging-1.0
) provides a very easy-to-use way to send, receive, and process messages and is well-suited to writing applications that process streams of events.
MP Reactive Messaging is a different messaging API than the traditional JMS API. However, many of the same messaging engines (such as Kafka) can be used.
This blog post provides an excellent overview of the feature: Sending and receiving messages between microservices with MicroProfile Reactive Messaging
12. Security
To enable security for your application, enable the appSecurity-3.0
feature. This will cause all application endpoints requiring a role to go through HTTPS and some form of authentication.
12.1. Basic authentication
A simple form of authentication is the <basicRegistry>
element, which allows you to directly configure user/password pairs.
<featureManager>
<feature>appSecurity-3.0</feature>
</featureManager>
<basicRegistry id="basic">
<user name="bob" password="bobpwd"/>
</basicRegistry>
<webApplication location="myApp.war">
<application-bnd>
<!-- this can also be defined in web.xml instead -->
<security-role name="admin">
<user name="bob"/>
</security-role>
</application-bnd>
</webApplication>
Then, managed resources (JAX-RS endpoints, servlets, etc) can be secured with @RolesAllowed
:
@Path("/")
@ApplicationScoped
@RolesAllowed("admin")
public class HelloEndpoint {
@GET
public String sayHello() {
return "Hello World";
}
}
Accessing any endpoints in the HelloEndpoint
(on http
or https
) will then then restrict access to a user in the admin
role (in this case bob
).
For more details see this guide: Security a web application
12.2. Secure Communication
Enabling SSL/TLS communication requires the transportSecurity-1.0
or ssl-1.0
feature. The transportSecurity-1.0
feature is newer and therefore preferred over the ssl-1.0
feature.
By default, the server will generate a default keystore at ${server.config.dir}/resources/security/key.p12
.
The password for this keystore will be either:
-
The password defined in
<keyStore id="defaultKeyStore" password="…" />
-
Otherwise, it will use a randomly generated password which can be found in the
${server.config.dir}/server.env
file.
The default SSL configuration will use the defaultKeyStore
as both keystore and truststore. All TLS protocols are enabled by default: TLSv1
, TLSv1.1
, and TLSv1.2
. If you are using Java 11 or newer, TLSv1.3
is also enabled.
By default, a Liberty server uses a self-signed certificate so that the default SSL configuration only trusts itself. To establish trust with other servers, trusted certificates should be added to the defaultKeyStore
using a keystore tool like $JAVA_HOME/bin/keytool
.
If manually adding trusted certificates is not desireded, then the default SSL configuration can be set to use the JDK’s default truststore like so:
<ssl id="defaultSSLConfig" trustDefaultCerts="true" />
12.3. MicroProfile JWT
JSON Web Token (JWT) is a token-based authentication mechanism that offers a lightweight way for security controls and tokens to propagate user identities across different services. Because of these characteristics, it has become a popular security mechanism for microservice applications.
To use it, enable the mpJwt
feature:
<featureManager>
<feature>appSecurity-3.0</feature>
<feature>mpJwt-1.1</feature>
</featureManager>
Then, configure the JWT issuer and public key with MicroProfile Config:
# If you set/override these values using environment variables,
# convert all '.' chars to '_' chars in property key names
mp.jwt.verify.publickey=<the JWT issuer's public key>
mp.jwt.verify.issuer=http://someJwtIssuer.com
Lastly, resources can be secured using the @RolesAllowed
annotation:
@Path("/")
@RequestScoped
@RolesAllowed("users") // Requires jwts to have "group=users" claim
public class SecuredServiceEndpoint {
For more details see this guide: Securing microservices with JWTs
13. Integration Testing
There are two primary frameworks available to help make testing your Liberty applications easier:
13.1. MicroShed Testing
-
Ideal for testing apps that run in Docker containers
-
Ideal for testing REST endpoints
-
Ideal for testing apps that depend on other services (e.g. database or another HTTP-based service)
-
Ideal for black-box testing
-
OpenLiberty guide available here: Testing a MicroProfile or Jakarta EE application
See the MicroShed Testing website for full documentation
13.2. Arquillian
-
Ideal for grey-box testing
-
Ideal for testing apps that are not in containers
-
Works with JUnit 4, JUnit 5, and TestNG (MicroShed only works with JUnit 5)
-
OpenLiberty guide available here: Testing microservices with the Arquillian managed container
See arquillian.org for full documentation
14. Included OSS Components
Liberty Feature | OSS Component |
---|---|
|
Apache BVal 1.1 |
|
Weld 2.4.X |
|
Weld 3.X |
|
Sun ref impl |
|
Sun ref impl |
|
Sun ref impl |
|
Sun ref impl |
|
Apache CXF 2.6 |
|
Apache CXF 3.2 |
|
Apache CXF 2.6 |
|
Apache CXF 3.2 |
|
EclipseLink 2.6 |
|
EclipseLink 2.7 |
|
Apache MyFaces 2.2 |
|
Apache MyFaces 2.3 |
|
Eclipse Yasson 1.0 |
|
Glassfish ref impl |
|
Glassfish ref impl |
|
SmallRye Reactive Messaging |
15. Replaceable Components
-
JPA implementation can be changed (typically to Hibernate) using the
jpaContainer-2.1
or2.2
features -
JSF implementation can be changed (typically to Mojarra) using the
jsfContainer-2.2
or2.3
features -
JSON-B implementation can be changed using the
jsonbContainer-1.0
feature -
JSON-P implementation can be changed using the
jsonpContainer-1.0
or1.1
feature
16. Contribute
Find some incorrect information or want to contribute an additional section?
Fork this document on github and raise a PR: GitHub - openliberty-cheat-sheet