Exclude all modules from Wildfly 10 - spring-boot

I'm trying to deploy my Spring-boot app to a wildlfy server.
However, i'm finding some conflicts between the libs.
So, i want my app to use only what i define on my pom, and completely ignore all wildfly modules.
Is it possible?
Using Wildfly 10 and spring-boot 2.x

Modules
Yes, it is possible. According to the RedHat docs, ยง3.4, and according to my practice which I have tested several times: You can PREVENT A Module being implicitly loaded. For this:
Create (if not already existing) jboss-deployment-structure.xml file and add this into that file:
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.javassist" />
<module name="org.dom4j" />
<module name="org.apache.commons.configuration" />
<!--and so on.. -->
</exclusions>
</deployment>
</jboss-deployment-structure>
add this (jboss-deployment-structure.xml) file to the project (For a web application (WAR) add this file to the WEB-INF directory. For an EJB archive (JAR) add it to the META-INF directory).
Sub-systems
On the other hand, EAR files (modules) will most likely include sub-systems, like WAR and JAR files. You can exclude only sub-system, from the module, as well. For this, include this snippet in the same (jboss-deployment-structure.xml) file:
<exclude-subsystems>
<subsystem name="SUBSYSTEM_NAME" />
</exclude-subsystems>

Related

Deployed Web application getting nosuchmethod error for javax.json.JsonValue.asJsonArray - Jboss eap 7.0 linux server

I have a web application deployed to jboss eap 7.0 on linux.
Within my java code I am using javax.json.JsonValue.asJsonArray method.
When I run locally on tomcat all runs fine.
Once I deploy to Jboss I get a nosuchmethod error on asJsonArray method. within my WEB-INF\lib folder I have the necessary json jar with that method javax.json-1.1.4.jar. I have discovered that under modules within Jboss it has its own version of javax.json \jboss-eap-7.0\modules\system\layers\base\org\glassfish\javax\json\main\javax.json-1.0.3.redhat-1.jar.
It is my speculation that when I run my application it is first looking at jar within the Jboss modules directory rather than the jar within the WEB-INF\lib folder in the war file. How do I direct the application to reference the jar within the WEB-INF\lib and not the jar withing the jboss modules?
You can exclude the JBoss provided dependency using jboss-deployment-structure.xml file which you need to place under the WEB-INF directory of your war. You have to specify the exclusion dependencies something like below.
`<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="$LIBRARY_OR_MODULE_YOU_WANT_TO_EXCLUDE"/>
</exclusions>
</deployment>
</jboss-deployment-structure>`
e.g. <module name="javax.json.api"/>

How to exclude a bundle from Karaf Feature programatically

In my project, there is Karaf feature XML file contains all OSGi bundles. Now, this is used as dependency in other maven project's pom.xml file.
<dependency>
<groupId>a.b.c</groupId>
<artifactId>dummyfeature</artifactId>
<type>xml</type>
<classifier>features</classifier>
<version>1.0.0</version>
</dependency>
Now, following code is being used to install above feature.
KarafDistributionOption.features(
maven()
.groupId("a.b.c")
.artifactId("dummyfeature")
.version("1.0.0")
.type("xml")
.classifier("features"), "dummyfeature")
Is there a way to exclude a particular OSGi bundle from above feature programtically?
https://issues.apache.org/jira/browse/KARAF-5376 provides a way to alter the features read from XML file. You can:
blacklist some bundles
blacklist some features
override some bundles (like changing version or even group/artifact IDs)
override entire features
See this comment for overview of the mechanism. There's no documentation fragment yet (I didn't have time to do it). But for your particular case, you should add etc/org.apache.karaf.features.xml file with this content:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Configuration generated by Karaf Assembly Builder
-->
<featuresProcessing xmlns="http://karaf.apache.org/xmlns/features-processing/v1.0.0">
<blacklistedBundles>
<!-- there are several patterns you can use here -->
<bundle>mvn:groupId/artifactId</bundle>
<bundle>mvn:groupId/artifactId/1.0</bundle>
<bundle>mvn:groupId/artifactId/[1,2)</bundle>
</blacklistedBundles>
</featuresProcessing>

Jboss modules dependencies

I have a question about dependencies in jboss modules.
I have a spring application with structure like:
myApp.war/
--/WEB-INF
--/classes/com/myapp/monitoring/IMonitoring.class
--/classes/com/myapp/monitoring/MonitoringFirst.class
--/lib
my-core.jar
IMonitoring.class defines contract for monitoring class
MonitoringFirst.class provides implementation for mornitoring, also it uses some class defined in my-core.jar for logging purpose so it depends on my-core.jarin spring I define bean like:
<bean id="myMonitoring" class="com.myapp.monitoring.MonitoringFirst">
then I decided to prepare another implementation of IMonitoring.class and provide it in sepatare jar as module in jboss modules so in jboss-deployment-structure.xml I have like:
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="com.myapp.my-customization" />
</dependencies>
</deployment>
</jboss-deployment-structure>
and my module defines jar with second implementation of IMonitoring.class inside
<module xmlns="urn:jboss:module:1.0" name="com.myapp.my-customization">
<resources>
<resource-root path="customization.jar"/>
</resources>
<dependencies>
<module name="my-core.jar"/>
</dependencies>
</module>
then in my spring I can use
<bean id="myMonitoring" class="com.myapp.monitoring.MonitoringSecond">
but since MonitoringSecond also uses some class defined in my-core.jar for logging purpose I had to move my-core.jar to jboss modules - otherwise class needed in MonitoringSecond.class is not available and I have java.lang.ClassNotFoundException: com.myapp.LogManager from [Module "com.myapp.my-customization:main" from local module loader....
Unfortunatelly class used for logging purpose (com.myapp.LogManager in my-core.jar) need information about name of the war in which it is called from, what can be achieved by asking for URL like
URL url = LogManager.class.getResource(LogManager.class.getSimpleName() + ".class");
but this gives different results:
when class is located in myApp.war/WEB-INF/lib it gives:
vfs:/C:/server/bin/content/myApp.war/WEB-INF/lib/my-core.jar/com/myapp/LogManager.class
and I can determine war name
when class is located in jboss module it gives:
jar:file:/C:/server/modules/system/layers/base/com/myapp/my-customization/main/my-core.jar!/com/myapp/LogManager.class
and here I don't have info about war name
Finally, actual question:
Is there possibility that MonitoringSecond class can use LogManager.class defined in /WEB-INF/lib so that I'm not forced to move my-core.jar to jboss modules ?
If not, some other idea to determine war name from which LogManager.class has been called ?
Hope I didn't confuse it too much.
Thanks for any answer. Regards.
A module in $JBOSS_HOME/modules is not possible to depend on a deployment WAR (Dynamic module). So It is not possible to maintain my-core.jar inside war lib folder, my-core.jar have to be located in $JBOSS_HOME/modules

How is a war file created for spring boot with maven?

I'm trying to follow the guide for converting a spring project to a war.
http://spring.io/guides/gs/convert-jar-to-war/
It starts out using maven and gradle and then right after the jar portion it completely forgets about maven and only has gradle updates.
There are two main changes that you need to make in the pom. The first is to change the project's packaging type to war:
<groupId>org.springframework</groupId>
<artifactId>gs-convert-jar-to-war</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
The second is to add a dependency on spring-boot-starter-tomcat and mark it as provided:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
mvn package will now produce a war file that can be run using java -jar or deployed to a separate servlet container.
There is an official guide at spring:
http://spring.io/guides/gs/convert-jar-to-war-maven/
Pay attention to "Initialize the servlet" section.
It explains an important point of adding a class that substitutes web.xml. Without it (or without proper web.xml) you will get a war file but when deployed nothing will be accessible in browser as nothing will be registered as your request dispatcher.
Also note that it is best to run this example on Tomcat 8 as it supports latest servlet specs. I have spent number of hours trying to figure out why it does not work on my Tomcat 7.

Jboss EAP 6.1 spring modules class loading not working

I have a spring integration project deployed in jboss as a WAR file.
The project uses maven and structured to support any type of archival War or Jar.
However, the dependencies of the project (all spring jars and custom jars) should be externalized
The reason would be that, later there would be 100s of Spring Integration flows would be deployed and if we have the jars in WEB-INF/libs the size of WAR grows to ~ 50MB. As we have abstracted much of our functionality in a seperate jar (would be added as dependency to my spring integration project), Externalization will result in reducing the WAR file to ~ 5 KB.
I do not have a web.xml and use the WebInitializer for loading the context (Which is part of my common functionality and added as dependency)
Below is what I have tried with JBOSS.
Created a module com.xxx.yyy and added all my spring/third party and custom jars as resources.
Added the dependency to manifest file. (This did not work)
Added the jboss-deployment-structure.xml to my war WEB-INF (did not work)
If I give the wrong module name its throws errors as module
not found.
The war gets deployed, but not initialized. If I have the dependencies in my WEB-INF/lib, everything works as expected.
Below is the jboss deployment structure xml that I used.
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0">
<deployment>
<dependencies>
<module name="com.xxx.yyy" services="import" >
<imports>
<include path="META-INF**"/>
<include path="org**"/>
</imports>
</module>
</dependencies>
</deployment>
</jboss-deployment-structure>
Here is the expectation,
Externalize the Jar dependencies.
Import the dependencies to my war(manifest or jboss-deployment-structure.xml)
Should be used Spring Service should be initialize.
The deployed war should be working as it does if the libraries are
in WEB-INF
Please help...
With JBOSS EAP 6, Its not possible to deploy the war without a web.xml, But such is possible only with tomcat or by using spring boot.
Also, to address this problem, we had to create a dummy web.xml and use jboss modules to load dependencies.

Resources