[JAVA] WildFly class loading

Introduction

There was no particular request, but I will write a continuation of Try moving WildFly Wild. This time is about class loading. This time we will use the latest WildFly-15.0.0.Final as of December 2018.

WildFly class loading

The jars included in WildFly are managed with the idea of modules. There are two types of modules: static modules and dynamic modules.

Module type

** 1. Static module ** Refers to the jar installed under the modules directory. You can also put a custom module jar created by the user. ** 2. Dynamic module ** Refers to a jar or class in a war or ear file.

If you want to use a static module from your application, you need to put a deployment descriptor file jboss-deployment-structure.xml in your application and write a ** dependency ** that declares that you will use this module. There is.

However, some static modules have ** implicit ** dependencies ** [^ 2], which you don't need to write in jboss-deployment-structure.xml. Will be loaded into.

Class loading priority

Classes (modules) are loaded in priority, and if there are classes with the same name in the same package, the one with the highest priority loaded first will be used.

Each module is loaded in the following order [^ 1].

  1. Implicit Dependencies Static Module [^ 2](System Dependencies)
  2. User Dependencies set by the user in jboss-deployment-structure.xml
  3. Dynamic module (Local Resource)

Check if it is true

I'm skeptical so I'll try to see if it's true.

Creating a JSP for confirmation

Check using ʻorg.apache.log4j` in the Implicit Dependency module. First, prepare the following jsp.

logger.jsp


<%@page contentType="text/html; charset=UTF-8" %>
<html>
<body>
<%
Object logger = org.apache.log4j.Logger.getLogger("test");
out.print(logger.getClass().getName());
out.print("<br>");
out.print(logger.toString());
%>
</body>
</html>

Creating a fake class for confirmation

Create a fake Logger class like the one below, compile it, and jar it into classloadTestInModules.jar. Install this as a ** static module ** under the modules directory.

Logger.java


package org.apache.log4j;
public class Logger {

	public static String getLogger(String name) {
	//org.apache.log4j.Returns the string module instead of the Logger class.
		return "module";
	}
}

Then make a few changes and compile it in the same way into classloadTestInWar.jar. This is included in the application (war) as a ** dynamic module **.

Logger.java


package org.apache.log4j;
public class Logger {

	public static String getLogger(String name) {
	//org.apache.log4j.Returns the string war instead of the Logger class.
		return "war";
	}
}

Installation of static modules

Install the created classloadTestInModules.jar under the modules directory.

Create the following directories.  wildfly-15.0.0.Final/modules/system/layers/base/test  wildfly-15.0.0.Final/modules/system/layers/base/test/test  wildfly-15.0.0.Final/modules/system/layers/base/test/test/main

Place classloadTestInModules.jar below.  wildfly-15.0.0.Final/modules/system/layers/base/test/test/main

Create module.xml with the following contents. test.test is the name of this module.

module.xml


<?xml version="1.0" encoding="UTF-8"?>
<module name="test.test" xmlns="urn:jboss:module:1.7">
    <resources>
        <resource-root path="classloadTestInModules.jar"/>
    </resources>
</module>

Then place logger.jsp directly under classloadTestInWar.jar war in WEB-INF / lib of the appropriate application helloworld.war in wildfly-15.0.0.Final / standalone / deployments .. You're ready to create and deploy the deployment marker file helloworld.war.dodeploy.

Is the implicit dependency module used?

Go to http: //localhost:8080/helloworld/logger.jsp in your browser.

It was displayed as follows. Now that the Logger class object is back, you can see that the implicit dependency module class is back.

org.apache.log4j.Logger org.apache.log4j.Logger@62af7a58

It worked as expected: clap:

Will the user-placed static module be used?

Let's put in a setting that wants to use a user-specified module instead of an implicit dependency module. Create a deployment descriptor file jboss-deployment-structure.xml in helloworld.war / META-INF with the following content:

jboss-deployment-structure.xml


<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
		<exclusions>
			<module name="org.apache.log4j" />
		</exclusions>
		<dependencies>
			<module name="test.test"/>
		</dependencies>
    </deployment>
</jboss-deployment-structure>

<dependencies> is the name of the static module you want to use. <exclusions> is the name of the implicit dependency module you don't want to use. Now go to http: // localhost: 8080 / helloworld / logger.jsp again to create and redeploy the helloworld.war.dodeploy file.

It was displayed as follows. The String type with the content module is returned, so you can see that the class of the installed test.test module was used.

java.lang.String module

It worked as expected: clap:

Is a dynamic module used?

Then set it to use only dynamic modules. Modify jboss-deployment-structure.xml to the following: Leave only the settings that exclude the implicit dependency module.

jboss-deployment-structure.xml


<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
		<exclusions>
			<module name="org.apache.log4j" />
		</exclusions>
    </deployment>
</jboss-deployment-structure>

Create and redeploy the helloworld.war.dodeploy file again and access http: // localhost: 8080 / helloworld / logger.jsp.

It was displayed as follows. Since the String type with the content of war is returned, we can see that the class of the dynamic module classloadTestInWar.jar in WEB-INF / lib was used.

java.lang.String war

It worked as expected: clap:

Summary

If WildFly is not aware of the priority of loading classes, if the application you create contains the same module as the implicit dependency module, you may suffer from unexpected errors due to different versions etc. Please note that there is.

Reference material

[^ 1]: Class Loading Priority ⇒ 1.3. Class Loading Precedence [^ 2]: List of modules with implicit dependencies ⇒ 2.3. Which are the implicit module dependencies? Chapter 6 JBoss EAP Class Loading

Recommended Posts

WildFly class loading
11th class: Class
Anonymous class (anonymous class)
Wildfly installation
Class method
ObjectMapper class
ArrayList class