Installing on WildFly
Liferay DXP 2025.Q3+/Portal 2026.Q1+
For pre-Jakarta Liferay versions, see Installing Earlier Versions on WildFly.
Installing on WildFly requires installing the DXP WAR, installing dependencies, configuring WildFly, and deploying DXP on WildFly. You must also configure your database and mail server connections.
Prerequisites
Liferay DXP/Portal requires a supported Java version to run. See JVM Configuration for more information.
Download these files from the Help Center (subscription) or from Liferay Community Downloads. Administrators must download the following:
- DXP WAR file
- OSGi Dependencies ZIP file
- WildFly 30+
The installation steps use these terms:
[Liferay Home]: The folder containing the WildFly server folder (referred to as $WILDFLY_HOME). After installing and deploying DXP, it generates data, deploy, and logs folders.
$WILDFLY_HOME: The WildFly server folder. It is usually named wildfly-[version].
Installing Dependencies and the DXP WAR
-
If you’re starting with a clean Wildfly installation and a
$WILDFLY_HOME/standalone/deployments/ROOT.warfolder exists, delete all of its subfolders and files. -
Unzip the DXP WAR file into the
$WILDFLY_HOME/standalone/deployments/ROOT.warfolder (create this folder if it doesn’t exist). -
Unzip the OSGi Dependencies ZIP file into the
[Liferay Home]/osgifolder (create this folder if it doesn’t exist). Liferay’s OSGi runtime depends on these modules.
Running DXP on WildFly in Standalone Mode vs. Domain Mode
WildFly can be launched in either standalone mode or domain mode. Domain mode allows multiple application server instances to be managed from a single control point. A collection of such application servers is known as a domain. For more information on standalone mode vs. domain mode, please refer to the section on this topic in the WildFly Admin Guide. DXP fully supports WildFly in standalone mode but not in domain mode.
DXP supports WildFly when it runs in standalone mode but not when it runs in domain mode. DXP’s auto-deploy does not work with a managed deployment, since WildFly manages the content of a managed deployment by copying files (exploded or non-exploded). This prevents JSP hooks and Ext plugins from working as intended. For example, JSP hooks don’t work on WildFly running in managed domain mode, since DXP’s JSP override mechanism relies on the application server. Since JSP hooks and Ext plugins are deprecated, however, you may not be using them.
If you use domain mode deployment, use the command line interface.
This does not prevent DXP from running in a clustered environment on multiple WildFly servers. You can set up a cluster of DXP instances running on WildFly servers running in standalone mode. Please refer to the clustering articles for more information.
Configuring WildFly
Configuring WildFly to run DXP includes these things:
- Setting environment variables
- Setting properties and descriptors
- Removing unnecessary configurations
Make the following modifications to $WILDFLY_HOME/standalone/configuration/standalone.xml:
-
Locate the closing
</extensions>tag in the<server>s. Directly beneath that closing tag, insert the following system properties, if they don’t already exist:<system-properties> <property name="org.apache.catalina.connector.URI_ENCODING" value="UTF-8" /> <property name="org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING" value="true" /> </system-properties> -
Filter out
WFLYSRV0059andWFLYEE0007messages from the log. In the<subsystem xmlns="urn:jboss:domain:logging:8.0">element’s<console-handler>tag, add the following<filter-spec>tag directly below the<level name="INFO"/>tag.<filter-spec value="not(any(match("WFLYSRV0059"),match("WFLYEE0007")))" /> -
Add a deployment scanner timeout by adding a
deployment-timeout="600"setting to the<deployment-scanner>tag in the<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">element. For example,<deployment-scanner deployment-timeout="600" path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/> -
Comment out the welcome content elements from the
<subsystem xmlns="urn:jboss:domain:undertow:12.0" ...>element. For example,<!--<location name="/" handler="welcome-content"/>-->and
<handlers> <!--<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>--> </handlers> -
If you’re using the IBM JDK with the WildFly server, navigate to the
$WILDFLY_HOME/modules/system/layers/base/sun/jdk/main/module.xmlfile. Then, insert these paths inside the<paths>...</paths>element to resolve issues with deployment exceptions and image uploads:<path name="com/sun/crypto" /> <path name="com/sun/crypto/provider" /> <path name="com/sun/image/codec/jpeg" /> <path name="com/sun/org/apache/xml/internal/resolver" /> <path name="com/sun/org/apache/xml/internal/resolver/tools" />
Checkpoint:
Before continuing, verify the following properties have been set in the standalone.xml file:
- The new
<system-property>is added. - The new
<filter-spec>is added. - The
<deployment-timeout>is set to600. - The new
<security-domain>is created. - Welcome content is disabled.
Next, configure the JVM and startup scripts:
In the $WILDFLY_HOME/bin/ folder, open the standalone domain’s configuration script file standalone.conf:
- Set the file encoding to
UTF-8 - Set the user time zone to
GMT - Set the preferred protocol stack
- Increase the default amount of memory available.
DXP requires the application server JVM to use the GMT time zone and UTF-8 file encoding.
Make the following edits to your standalone.conf script.
-
Below the
if [ "x$JAVA_OPTS" = "x" ];statement, remove the JVM sizing options from theJAVA_OPTSassignment. For example, replace thisJAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true"with this:
JAVA_OPTS="-Djava.net.preferIPv4Stack=true" -
Add these Java options setting at the end of the file:
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Duser.timezone=GMT -Xms2560m -Xmx2560m -XX:MaxNewSize=1536m -XX:MaxMetaspaceSize=768m -XX:MetaspaceSize=768m -XX:NewSize=1536m -XX:SurvivorRatio=7 -Djboss.as.management.blocking.timeout=1800" JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/sun.net.www.protocol.http=ALL-UNNAMED --add-opens=java.base/sun.util.calendar=ALL-UNNAMED --add-opens=jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED" export JDK_JAVA_OPTIONS
The Java options and memory arguments are explained below.
JVM Options Explained
| Option | Explanation |
|---|---|
-Dfile.encoding=UTF-8 | DXP requires UTF-8 file encoding. |
-Djava.net.preferIPv4Stack=true | Prefers an IPv4 stack over IPv6. |
-Djboss.as.management.blocking.timeout=1800 | Set timeout to retry in case WildFly fails to start. |
-Duser.timezone=GMT | DXP requires the application server JVM to use the GMT time zone. |
The deep reflection options are necessary for some components in Liferay to function.
Memory Arguments Explained
| Memory Arguments | Explanation |
|---|---|
-Xms | Initial space for the heap. |
-Xmx | Maximum space for the heap. |
-XX:NewSize | Initial new space. Setting the new size to half of the total heap typically provides better performance than using a smaller new size. |
-XX:MaxNewSize | Maximum new space. |
-XX:MetaspaceSize | Initial space for static content. |
-XX:MaxMetaspaceSize | Maximum space for static content. |
-XX:SurvivorRatio | Ratio of the new space to the survivor space. The survivor space holds young generation objects before being promoted to old generation space. |
After installing DXP, these configurations (including these JVM options) can be further tuned for improved performance. Please see Tuning Liferay and Tuning Your JVM for more information.
Checkpoint:
-
The file encoding, user time-zone, and preferred protocol stack have been set in the
JAVA_OPTSin thestandalone.conf.shscript. -
The default amount of memory available has been increased.
The prescribed script modifications are now complete for the DXP installation on WildFly.
Data Source Configuration in Liferay
DXP contains a built-in Hypersonic database which is great for demonstration purposes but should not be used in production. For production, use a full-featured, supported RDBMS. See Configure a Database to set up your database.
Liferay DXP can connect with your database using DXP’s built-in data source (recommended) or using a data source you create on your app server.
You can configure DXP’s built-in data source with your database the first time you run DXP by using the Setup Wizard. Or you can configure the data source in a portal-ext.properties file based on the Database Template for your database.
Data Source Configuration in Wildfly
If using WildFly to manage the data source, follow these steps:
-
The DXP WAR file includes drivers for MariaDB and PostgreSQL. Earlier WARs don’t have them. If the WAR doesn’t have the driver for the supported database you’re using, download your database vendor’s JDBC JAR file and place it in the
$WILDFLY_HOME/standalone/deployments/ROOT.war/WEB-INF/shielded-container-libfolder. This is the recommended method for adding dependencies that are only needed by Liferay on WildFly. Alternatively, you can install dependencies using JBoss’ global classpath location.See the compatibility matrix for a list of supported databases.
A Hypersonic database is bundled with DXP and is useful for testing purposes. Do not use HSQL for production DXP instances.
-
If you haven’t already, create a file called
module.xmlin the$JBOSS_HOME/modules/com/liferay/portal/mainfolder. In the file, declare the portal module and all of its required dependencies:<?xml version="1.0"?> <module name="com.liferay.portal" xmlns="urn:jboss:module:1.5"> <dependencies> <module name="jakarta.servlet.api" optional="true" /> <module name="jakarta.transaction.api" /> </dependencies> </module> -
Get the JDBC JAR from your DXP WAR or from the database vendor and copy it to the
$WILDFLY_HOME/modules/com/liferay/portal/mainfolder. -
Update
module.xmlin the$WILDFLY_HOME/modules/com/liferay/portal/mainfolder to declare the portal module and the JDBC JAR.<resources> <resource-root path="[place your database vendor's JAR file name here]" /> </resources> -
Add the data source inside the
$WILDFLY_HOME/standalone/configuration/standalone.xmlfile’s<datasources>element:<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" jta="true" use-java-context="true" use-ccm="true"> <connection-url>[place the URL to your database here]</connection-url> <driver>[place your driver name here]</driver> <security user-name=[place your user name here] password=[place your password here]/> </datasource>Make sure to replace the database URL, user name, and password with the appropriate values.
NoteIf the data source
jndi-namemust be changed, edit thedatasourceelement in the<default-bindings>tag. -
Add the driver class name to the
standalone.xmlfile’s<drivers>element also found within the<datasources>element.<drivers> <driver name="[name of database driver]" module="com.liferay.portal"> <driver-class>[JDBC driver class]</driver-class> </driver> </drivers>A final data sources subsystem that uses MySQL should look like this:
<subsystem xmlns="urn:jboss:domain:datasources:1.0"> <datasources> <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" jta="true" use-java-context="true" use-ccm="true"> <connection-url>jdbc:mysql://localhost/lportal</connection-url> <driver>mysql</driver> <security> <user-name>root</user-name> <password>root</password> </security> </datasource> <drivers> <driver name="mysql" module="com.liferay.portal"> <driver-class>com.mysql.cj.jdbc.Driver</driver-class> </driver> </drivers> </datasources> </subsystem> -
In a
portal-ext.propertiesfile in the Liferay Home folder, specify the JNDI data source. For example,jdbc.default.jndi.name=java:jboss/datasources/ExampleDS
The data source is now configured and ready to go.
Connect to a Mail Server
As with database configuration, the easiest way to configure mail is to let DXP handle the mail session. If you want to use DXP’s built-in mail session, skip this section and configure the mail session in the Control Panel.
If you want to manage your mail session with WildFly, follow these steps:
-
Specify your mail subsystem in the
$WILDFLY_HOME/standalone/configuration/standalone.xmlfile like this:<subsystem xmlns="urn:jboss:domain:mail:4.0"> <mail-session jndi-name="java:jboss/mail/MailSession" name="mail-smtp"> <smtp-server ssl="true" outbound-socket-binding-ref="mail-smtp" username="USERNAME" password="PASSWORD"/> </mail-session> </subsystem> ... <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> ... <outbound-socket-binding name="mail-smtp"> <remote-destination host="[place SMTP host here]" port="[place SMTP port here]"/> </outbound-socket-binding> </socket-binding-group> -
In the
portal-ext.propertiesfile in Liferay Home, reference the mail session. For example,mail.session.jndi.name=java:jboss/mail/MailSession
Deploying DXP
-
To trigger deploying
ROOT.war, create an empty file calledROOT.war.dodeployin the$WILDFLY_HOME/standalone/deployments/folder. -
Start the WildFly application server by navigating to
$WILDFLY_HOME/binand runningstandalone.sh. WildFly detects theROOT.war.dodeployfile and deploys the web application matching the file prefix (i.e.,ROOT.war).
After deploying DXP, you may see excessive warnings and log messages such as the ones below, involving PhaseOptimizer. These are benign and can be ignored. You can turn off these messages by adjusting the app server’s logging level or log filters.
May 02, 2018 9:12:27 PM com.google.javascript.jscomp.PhaseOptimizer$NamedPass process
WARNING: Skipping pass gatherExternProperties
May 02, 2018 9:12:27 PM com.google.javascript.jscomp.PhaseOptimizer$NamedPass process
WARNING: Skipping pass checkControlFlow
May 02, 2018 9:12:27 PM com.google.javascript.jscomp.PhaseOptimizer$NamedPass process
INFO: pass supports: [ES3 keywords as identifiers, getters, reserved words as properties, setters, string continuation, trailing comma, array pattern rest, arrow function, binary literal, block-scoped function declaration, class, computed property, const declaration, default parameter, destructuring, extended object literal, for-of loop, generator, let declaration, member declaration, new.target, octal literal, RegExp flag 'u', RegExp flag 'y', rest parameter, spread expression, super, template literal, modules, exponent operator (**), async function, trailing comma in param list]
current AST contains: [ES3 keywords as identifiers, getters, reserved words as properties, setters, string continuation, trailing comma, array pattern rest, arrow function, binary literal, block-scoped function declaration, class, computed property, const declaration, default parameter, destructuring, extended object literal, for-of loop, generator, let declaration, member declaration, new.target, octal literal, RegExp flag 'u', RegExp flag 'y', rest parameter, spread expression, super, template literal, exponent operator (**), async function, trailing comma in param list, object literals with spread, object pattern rest
If you have a Liferay DXP Enterprise subscription, DXP requests your activation key. See Activating Liferay DXP for more information.
Congratulations! You’re running DXP on WildFly.
Next Steps
You can sign in as your administrator user and start building a solution on DXP. Or you can explore additional Liferay DXP setup topics: