What is a deployment overlay and how do I use it?

Solution Verified - Updated

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 6.1.x and further 6.x releases
    • 7.x

Issue

  • Need to change any file of a deployment at runtime so that the application need not be edited.
  • Patch deployment in JBOSS - How to change *.class file of a deployment at runtime so that the application need not be edited.
  • How to do deployment overlays in JBoss EAP 6.1
  • Is it possible to overlay a deployment descriptor of a sub-deployment inside an ear?
  • How to change the content of web.xml file at runtime in JBoss EAP 6.1 ?
  • Is it possible to define separate context-roots for multiple applications when jboss-web.xml are not defined for the applications?
  • Tried to use the overlay functionality over a directory instead over a single file. The CLI command is as follows:
  deployment-overlay add --name=jspOverlay --content=/test_jsp/=/a/testing_jsp/ --deployments=*.war --redeploy-affected

Here /a/testing_jsp/ and /test_jsp/ are directories not a file hence getting the following ERROR stacktrace:

java.lang.RuntimeException: java.io.FileNotFoundException: /a/testing_jsp/ (It's a directory)
        at org.jboss.as.controller.client.OperationBuilder.addFileAsAttachment(OperationBuilder.java:81)
        at org.jboss.as.cli.handlers.DeploymentOverlayHandler.add(DeploymentOverlayHandler.java:708)
        at org.jboss.as.cli.handlers.DeploymentOverlayHandler.doHandle(DeploymentOverlayHandler.java:381)
        at org.jboss.as.cli.handlers.CommandHandlerWithHelp.handle(CommandHandlerWithHelp.java:86)
        at org.jboss.as.cli.impl.CommandContextImpl.handle(CommandContextImpl.java:600)
        at org.jboss.as.cli.impl.CommandContextImpl.handleSafe(CommandContextImpl.java:616)
        at org.jboss.as.cli.impl.CommandContextImpl.interact(CommandContextImpl.java:1204)
        at org.jboss.as.cli.impl.CliLauncher.main(CliLauncher.java:263)
        at org.jboss.as.cli.CommandLineMain.main(CommandLineMain.java:34)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.jboss.modules.Module.run(Module.java:292)
        at org.jboss.modules.Main.main(Main.java:455)
Caused by: java.io.FileNotFoundException: /a/testing_jsp/ (It's a directory)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at org.jboss.as.controller.client.OperationBuilder$FileStreamEntry.<init>(OperationBuilder.java:158)
        at org.jboss.as.controller.client.OperationBuilder$FileStreamEntry.<init>(OperationBuilder.java:154)
        at org.jboss.as.controller.client.OperationBuilder.addFileAsAttachment(OperationBuilder.java:75)
        ... 14 more
  • Is it possible to use this deployment overlays feature for overlaying directories as well?

  • How can I creating custom class loader that loades classes from a jar in specific directory and later use this class in my application?
    Where can I find an example to this? The idea is to load jars at runtime in jboss.
    Is this functionality exist out of the box? for example, can I add new jars to modules at runtime or load them somehow other then creating my own custom
    classloader?

Resolution

Deployment overlays are a way of overlaying content into an existing deployment without physically modifying the contents of the deployment archive. Possible use cases include swapping out deployment descriptors, modifying static web resources to change the branding of an application, or even replacing jar libraries with different versions.

Deployment overlays have a different life-cycle to a deployment. In order to use a deployment overlay, you first create the overlay using the CLI or the management API. You then add files to the overlay, specifying the deployment paths you want them to overlay. Once you have created the overlay you then have to link it to a deployment name (which is done slightly differently depending on if you are in standalone or domain mode). Once you have created the link, any deployment that matches the specified deployment name will have the overlay applied.

Note:

  • If you use this to overlay a deployment descriptor already in the deployment, the existing one will be completely replaced by the overlay.
  • Adding or replacing jar libraries does not work until EAP 6.3. See <This content is not included.https://bugzilla.redhat.com/show_bug.cgi?id=1016995>.
  • When you modify or create an overlay it will not affect existing deployments; they must be redeployed in order to take effect.
  • Adding or replacing directories through this deployment overlays feature is not possible, it is only used for files.

Creating the Overlay


The following options are used in the sample commands:
  • --name: The name of the deployment overlay. This is only used to reference the overlay in future CLI commands.
  • --content: A comma-delimited list of files to overlay. Each item in the list is a key-value pair, where the key is the path in the deployment in which to place the overlaid file and the value is the filesystem path to be used as the content that will be overlaid in the deployment.
  • --deployments: A glob-like string to describe all the deployments to which this overlay should apply.
  • --redeploy-affected: Add this to cause all deployments identified by --deployments to be redeployed upon the addition of this overlay.

Creating an Overlay and linking it to deployments in one command

Standalone mode

deployment-overlay add --name=myOverlay \
                       --content=/WEB-INF/web.xml=/myFiles/myWeb.xml,/WEB-INF/ejb-jar.xml=/myFiles/myEjbJar.xml \
                       --deployments=test.war,*-admin.war \
                       --redeploy-affected

Domain mode

deployment-overlay add --name=myOverlay \
                       --content=/WEB-INF/web.xml=/myFiles/myWeb.xml,/WEB-INF/ejb-jar.xml=/myFiles/myEjbJar.xml \
                       --deployments=test.war,*-admin.war \
                       --server-groups=main-server-group \
                       --redeploy-affected

Creating an Overlay

Standalone mode

deployment-overlay add --name=myOverlay \
                       --content=/WEB-INF/web.xml=/myFiles/myWeb.xml,/WEB-INF/ejb-jar.xml=/myFiles/myEjbJar.xml 

Domain mode

deployment-overlay add --name=myOverlay \
                       --content=/WEB-INF/web.xml=/myFiles/myWeb.xml,/WEB-INF/ejb-jar.xml=/myFiles/myEjbJar.xml 

Linking an existing Overlay to deployments

Please note that the --deployments should refer to the runtime-name of the application and not the name field (if there is a separate one).

Standalone mode

deployment-overlay link --name=myOverlay \                       
                       --deployments=test.war,*-admin.war \
                       --redeploy-affected

If you are using domain mode and applying overlays in order to customize different environments, for instance with a different config file/module, and the application name field is different in each environment such as myapp-stage1.war but they all have the same runtime-name, the recommended way to handle this is to have each different environment correspond to a server-group so that application names and server-groups match up.

Domain mode

deployment-overlay link --name=myOverlay \
                       --deployments=test.war,*-admin.war \
                       --server-groups=main-server-group \
                       --redeploy-affected

Other Overlay Commands


**Display help**
deployment-overlay --help

List the overlay names

deployment-overlay -l

Show deployments using the overlay named myOverlay

deployment-overlay list-links --name=myOverlay

Nested deployments

If you have an zipped deployment with multiple zipped JAR's, WARs, etc. containing artifacts you want overlaying, then you need to include the name of the nested archive in the --content option.

For example, if the EAR archive contains a war module in the root folder with the name myWARInsideAnEAR.war, then the following command overlays the WEB-INF/jboss-web.xml inside the sub-deployment myWARInsideAnEAR.war.

deployment-overlay add --name=myOverlay --content=/myWARInsideAnEAR.war/WEB-INF/jboss-web.xml=/myFiles/jboss-web.xml --deployments=test.ear --redeploy-affected

Example


This example will show how to change which JSP is used as the web application's welcome file using a deployment overlay.

First, deploy a very simple web archive with the following contents:

/index.jsp
/index2.jsp
/WEB-INF/web.xml

web.xml has the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

So by default, the index.jsp gets shown as the welcome page. Now deploy the app through the CLI:

deploy ~/path/to/webapp.war

Next create the web.xml to overlay the one in the deployment: /tmp/web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index2.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Note the index2.jsp. Now create the overlay and have it apply to the deployment:

deployment-overlay add --name=ovTest --deployments=webapp.war --content=/WEB-INF/web.xml=/tmp/web.xml --redeploy-affected

And indeed, now index2.jsp is displayed when the application is accessed.

Another quick example showing how to replace an existing *.class file with a new version:

[standalone@localhost:9999 /] deployment-overlay add --name=classOverlay --content=/WEB-INF/classes/com/redhat/CallMe.class=/TestOverlay/bin/com/redhat/CallMe.class --deployments=TestClassOverlays.war --redeploy-affected

Related Documentation
EAP Configuration Guide - Deployment overlays

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.