How to prevent conflicts between JBoss modules and application libraries

Confirmation environment

JBoss EAP 6.4.0, 7.0.0, 7.1.0beta1

Causes of module and library conflicts

One thing to keep in mind when using JBoss EAP (JBoss) as a Java EE application server is the conflict between libraries and modules. More details can be found in Chapter 3 Class Loading and Modules in the Development Guide. To explain, JBoss loads the modules that come with JBoss in preference to the application libraries. (There seems to be no setting to change the order of the feelings that you see briefly.)

This means that your application may run on a version ** different from the version of the library you used at build time, which may result in errors at startup and run time. (It's okay now, but problems may occur when upgrading: anguished :)

Know which modules will be loaded

JBoss modules are automatically loaded depending on what you deploy, so try deploying the application you want to run once and figure out what's loaded.

If it is the default of standalone.xml in {JBOSS_HOME} / standalone / configuration, there is a setting related to log output on the 115th line, so change the level to DEBUG.

standalone.xml


  <root-logger>
   <level name="DEBUG"/>
   <handlers>
    <handler name="CONSOLE"/>
    <handler name="FILE"/>
   </handlers>
  </root-logger>

In this state, start JBoss and try deploying any application. Then, a list of application libraries and modules loaded by JBoss is output to {JBOSS_HOME} /standalone/server.log. The part that says Adding resource is the library loaded from war, Adding dependency Module The part labeled Dependency is the loaded module. The following is an example output.

server.log


2017-09-04 18:29:42,597 DEBUG [org.jboss.as.server.deployment](MSC service thread 1-7) Adding resource "/C:/jboss/standalone/deployments/todo.war/WEB-INF/lib/aopalliance-1.0.jar" to module deployment.todo.war
2017-09-04 18:29:42,648 DEBUG [org.jboss.as.server.deployment](MSC service thread 1-7) Adding dependency ModuleDependency [identifier=javax.ejb.api, moduleLoader=local module loader @282ba1e (finder: local module finder @13b6d03 (roots: C:\jboss\modules,C:\jboss\modules\system\layers\base)), export=false, optional=false, importServices=true] to module deployment.todo.war

This time, let's exclude javax.ejb.api as an example.

Creating a configuration file for the module

Place jboss-deployment-structure.xml directly under WEB-INF of the web application. After placing it, set as follows.

jboss-deployment-structure.xml


<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
	<deployment>
		<exclusions>
			<module name="javax.ejb.api" />
		</exclusions>
	</deployment>
</jboss-deployment-structure>

Simply enclose the modules you want to exclude in <exclusions>. You need to specify it from the path, which is written in the module.xml of each module. Now, let's restart JBoss in this state.

I will omit it because the log is long, but there should be no javax.ejb.api in the Adding dependency Module Dependency column.

Other settings

You can add modules that are not originally included in JBoss to jboss-deployment-structure.xml, or exclude individual subsystems that consist of multiple modules. Although not covered here, the setting method is described in Chapter 3 of the Development Guide, so please refer to it.

Background to this post

I had a hard time not knowing the cause of the error if the application that works fine on Tomcat is JBoss: dizzy_face:

bonus

Specific case

I was worried about whether to write this as the main, but it was not just a matter of excluding modules, so as a bonus ... Create Blank Project of TERASOLUNA (5.3.0) and put the following in HelloController.java Add code.

HelloController.java



/** (Abbreviation**/
import com.fasterxml.jackson.databind.util.StdDateFormat;

	/** (Abbreviation**/

	@RequestMapping(value = "/", method = { RequestMethod.GET, RequestMethod.POST })
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);

		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		String formattedDate = dateFormat.format(date);

		//from here
		Set<DateFormat> set = new HashSet<>();
		set.add(StdDateFormat.instance);
		//So far

		model.addAttribute("serverTime", formattedDate);

		return "welcome/home";
	}
}

Deploy this to Pivotal tc Server (v3.2) included with STS and access [http: // localhost: 8080 / todo](http: // localhost: 8080 / todo).

pivotal_result.PNG

There is no particular problem. Now let's deploy and access JBoss EAP 7.0.0.

jboss7_result.PNG

I got an error. There is also an error on the console.

console.log


15:28:42,923 ERROR [org.terasoluna.gfw.common.exception.ExceptionLogger](default task-2) [e.xx.fw.9001] UNDEFINED-MESSAGE: java.lang.NullPointerException
	at java.text.DateFormat.hashCode(Unknown Source)
	at java.util.HashMap.hash(Unknown Source)
	at java.util.HashMap.put(Unknown Source)
	at java.util.HashSet.add(Unknown Source)
	at todo.app.welcome.HelloController.home(HelloController.java:38)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	(Abbreviation)

The 38th line of HelloController.java is the part ofset.add (StdDateFormat.instance);.

This error has already been fixed in 2.7.2 of jackson-databind reported. The version of jackson-databind used by TERASOLUNA 5.3.0 is 2.8 as shown in Stack List. It's .5, why did this happen?

That's because the version of jackson-databind included in JBoss EAP 7.0.0 is 2.5.4 ... but since multiple modules are dependent on each other and simply excluding jackson-databind doesn't work, it's a sub. Exclude system JAX-RS.

Reference: Wildfly 9 --How do I exclude Jackson

Set jboss-deployment-structure.xml as follows:

jboss-deployment-structure.xml


<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
	<deployment>
		<exclude-subsystems>
			<subsystem name="jaxrs" />
		</exclude-subsystems>
	</deployment>
</jboss-deployment-structure>

Now, let's restart JBoss in this state.

jboss7_result.PNG

I did it ☆

Recommended Posts

How to prevent conflicts between JBoss modules and application libraries
Ruby How to convert between uppercase and lowercase
How to create an application
How to resolve Git conflicts
Difference between Java and JavaScript (how to find the average)
[Rails] Differences between redirect_to and render methods and how to output render methods
Differences in how to handle strings between Java and Perl
How to dynamically switch between FIN and RST in Netty
How to Synchronize Customer Data Between Salesforce and Kintone (Java-Simple JDBC)
How to use EventBus3 and ThreadMode
[Rails] How to prevent screen transition
How to call classes and methods
How to use equality and equality (how to use equals)
How to connect Heroku and Sequel
How to convert LocalDate and Timestamp
How to call libraries such as JQuery and JQuery UI in Liferay 7 / DXP
How to prevent duplicate processing by addEventListener
How to use OrientJS and OrientDB together
How to detect microphone conflicts on Android
How to publish an application on Heroku
[Java] How to output and write files!
How to set up and use kapt
How to build SquashTM and how to support Japanese
How to find the tens and ones
[Easy] How to upgrade Ruby and bundler
How to use substring and substr methods
[Struts] How to pass values between jsps
Note: [Docker] How to start and stop
How to add application version information to Sentry information
How to switch between multiple Java versions
How to write and explain Dockerfile, docker-compose
How to use @Builder and @NoArgsConstructor together
Differences between Java, C # and JavaScript (how to determine the degree of obesity)
How to find the distance and angle between two points on a plane