Enhanced Classloading

Since Payara 4.1.1.162

This page covers the enhanced class loading functionality provided by Payara Server.

Default Class and Library Loading

Payara Server has included many standard Java libraries and packages, for example Google Guava, Jackson, Logback and others to use. These libraries are located on the ${PAYARA_INSTALL_DIR}/modules directory.

The default class loading mechanism of Payara Server Works like this: When loading classes that belong to a library or framework that is included in the server, the server will always load those classes even if the application itself includes different versions.

In some cases, application developers will want to include a different version of the libraries that are already included on the server. Common use cases for this are:

  1. Use a newer version of a library that is included in the server. For example, Payara Server includes the Jackson library, and you might need to use a newer version that includes a specific feature you want to use.

  2. Use an older version of a library included within the server in order to support legacy applications. For example, you are using an older version of Icefaces that depends on an older version of JSF.

Unfortunately, due to the way the default class loading works, this will not be possible, and all libraries included with the server libraries will take precedence.

Disable Classloading delegation

In order for the server’s classloader to load classes from libraries of different versions to the ones shipped with it, it’s possible to disable the default classloader delegation. It can be altered to allow the server to load classes from libraries located at different sources in the following order:

  • First, libraries on WAR applications (included on WEB-INF/lib)

  • Then, libraries on EAR applications (included on /lib)

  • Then, libraries from the domain (located at ${DOMAIN_DIR}/lib)

  • Finally, libraries from the server (located at ${PAYARA_INSTALL_DIR}/modules_)

Disable Classloading delegation globally

To disable class loading delegation globally, you can set the system property fish.payara.classloading.delegate to false. This way, any library that is included on deployed applications will override the ones that are included in the server.

Libraries included at the domain level (${DOMAIN_DIR}/lib) will take precedence over the libraries included at the server.

Disable Classloading delegation locally

It’s possible to disable class loading delegation directly at the application level. This can be done for both WAR and EAR applications.

On WAR Applications

For WAR applications, you can include <class-loader delegate="false"/> element in the glassfish-web.xml deployment descriptor. Here’s an example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  ...
  <class-loader delegate="false"/>
  ...
</glassfish-web-app>

With this, all libraries included on the WEB-INF/lib/ directory will take precedence.

This feature is also available on GlassFish Server 4.x Open Source Edition

On EAR Applications

For EAR applications, you can include the <classloading-delegate>false</classloading-delegate> element in the glassfish-application.xml deployment descriptor. Here is an example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-application PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Java EE Application 6.0//EN" "http://glassfish.org/dtds/glassfish-application_6_0-1.dtd">
<glassfish-application>
    ...
    <classloading-delegate>false</classloading-delegate>
    ...
</glassfish-application>

With this, all libraries included on the EAR’s lib/ directory will take precedence.

Use other JSF implementation

In order to make the server use the bundled JSF implementation within the application, you need to set an additional configuration parameter; class loading delegation alone is not enough. You need to indicate within the payara-web.xml (or glassfish-web.xml) file that the server should use the bundled JSF implementation as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE payara-web-app PUBLIC "-//Payara.fish//DTD Payara Server 4 Servlet 3.0//EN" "https://docs.payara.fish/schemas/payara-web-app_4.dtd">
<payara-web-app error-url="">
    <class-loader delegate="false"/>
    <property name="useBundledJsf" value="true" />
</payara-web-app>

By specifying these options, the bundled JSF implementation within your deployment (WAR or EAR) will be used correctly.

Extreme Classloading Isolation

Since Payara Server 4.1.1.171

It’s possible to configure an extreme isolation level on the class loading delegation for deployed applications. With this extreme isolation behavior, a deployed application can force the server to load only classes and resources from libraries included on Payara Server that belong to whitelisted packages defined on its deployment descriptors.

To configure whitelist packaging you can use the <whitelist-package> element on the glassfish-web.xml (WAR artifacts) or the glassfish-application.xml (EAR artifacts). This element can be included multiple times to whitelist multiple packages. Here is an example of whitelisting both the Google Guava, Jackson and Faces Config packages for a WAR application:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  ...
  <whitelist-package>com.google.guava</whitelist-package>
  <whitelist-package>com.fasterxml.jackson</whitelist-package>
  <whitelist-package>com.sun.faces.spi.FacesConfigResourceProvider</whitelist-package>
</glassfish-web-app>

The whitelist syntax is simple: Define the name of the package which contains the classes or resources in question. For example writing com.google would whitelist all Google libraries included on the server, while writing com.google.guava would only whitelist the Google Guava library instead.

To enable this extreme isolation behavior, at least one whitelist-package element must be defined in the appropriate descriptor.

Default Whitelisted Classes

Certain classes are whitelisted automatically, meaning they will always be loaded from Payara Server’s libraries, even if this feature is turned on.

This is because these packages are required by Payara Server and therefore cannot be loaded from a deployed application:

  • java

  • javax

  • com.sun

  • org.glassfish

  • org.apache.jasper

  • fish.payara

  • com.ibm.jbatch

  • org.hibernate.validator

  • org.jboss.weld

  • com.ctc.wstx

Default whitelisted resources are:

  • META-INF/services/javax.

  • META-INF/services/org.glassfish.

  • META-INF/services/java.