Jboss EAP 7 - How to exclude implicit modules from deployment (javax.jms)? - java

I didn't think I would end up here but after a lot of Google and StackOverflow searches here I'm.
This is my exact problem except that I can't afford to make code changes.
The WAR I'm trying to deploy includes a JMS library (i.e. javax.jms, which I cannot exclude form the WAR.) which is already loaded by Jboss EAP 7 by default. The path to jar is something like this jboss/modules/system/layers/base/javax/jms/api/ain/jboss-jms-api_2.0_spec-1.0.0.Final-redhat-1.jar. Because of this two different versions of the same classes loading I'm getting ClassCastException.
org.apache.activemq-ra.ActiveMQConnectionFactory cannot to be cast to javax.jms.ConnectionFactory
So, I want Jboss to NOT load javax.jms so that my application can use the JAR included with the WAR.
So, I was wondering if there was any way to exclude the module globally (for all WAR deployments).
Excluding it per deployment would work too. And I do realize it can be acheivd using jboss-deployment-structure.xml but I can't get it to work.
Here is what I tried:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure
xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="javax" />
<subsystem name="javax.jms" />
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
and
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure
xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="javax" />
<module name="javax.jms" />
<module name="javax.jms.api" />
</exclusions>
</deployment>
</jboss-deployment-structure>
I placed the file in WEB-INF directory. It didn't work. It still loaded the JMS class from modules folder of Jboss EAP. So, how do I correctly do this?

The correct jboss-deployment-structure.xml is here:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="messaging-activemq"></subsystem>
</exclude-subsystems>
<exclusions>
<module name="javax.jms.api"></module>
</exclusions>
</deployment>
</jboss-deployment-structure>
This way you exclude both messaging subsystem and the JMS api.

You should remove the JMS API JAR from your deployment. You can still keep the JMS implementation JAR in your deployment but that should probably end up in a RAR, preferably outside your deployment.

This link has some things you could try.
Notably:
I think the problem is that activemq-all-5.4.2.jar contains javax.jms.*. Your deployment already gets this implicitly from the javaee.api module (see more information about implicity module dependencies here). I don't think it is appropriate for an application module/jar to package Java EE interfaces. You can try simply deleting the javax directory from activemq-all-5.4.2.jar or using a different set of ActiveMQ jars in your module to limit it to only what you need.
and/or altering your module.xml for ActiveMQ
<module xmlns="urn:jboss:module:1.0" name="activemq">
<resources>
<resource-root path="activemq-all-5.4.2.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>
There appears to be a method to embed ActiveMQ in Jboss as well, if you're interested. I won't pull out information from that article, as it doesn't answer the original question.

Related

What is wrong with my jboss-deployment-structure.xml? I'm trying to exclude a dependancy. The exclusion works in WAR but not in EAR

So we have found that JBoss 7.1 EAP provides its own version of Jackson-Databind. This version interferes with our deployment as we have a newer version in the WAR. We've proven out this theory by including this jboss-deployment-structure.xml at the WAR level's WEB-INF:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="jaxrs"/>
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
This lets the WAR deploy on its own without errors when it previously received the errors.
However, when trying to implement the same solution at the EAR level of deployment I've been unsuccessful. I've tried putting the jboss-deployment-structure.xml in the META-INF, WEB-INF, and root level of the EAR. I've done that with all number of different configurations but I can't get it to correctly exclude jaxrs. It's worth mentioning that this is my first run on JBoss configurations and I could be missing something incredibly simple.
EAR level file:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclude-subsystems>
<subsystem name="jaxrs" />
</exclude-subsystems>
</deployment>
<sub-deployment name="myWar.war">
<exclude-subsystems>
<subsystem name="jaxrs" />
</exclude-subsystems>
</sub-deployment>
</jboss-deployment-structure>
So, turns out that this was the answer. Just as it stands here. Another developer put the same file into his build and it worked. I don't know what the difference was between his environment and mine but I'm marking this question resolved.

Jackson - java.lang.EnumConstantNotPresentException when deserialization with JsonTypeInfo.DEDUCTION

I have SpringBoot app (1.4.3.RELEASE). Recently I have upgraded Jackson (com.fasterxml.jackson.datatype, com.fasterxml.jackson.core) from 2.8.5 to 2.12.2 because of polymorphic subtype deduction feature. Everything works just fine on my local development environment during unit tests and also when I'm running app from IDE.
The problem occurs when I push my changes to build and deploy it on development environment, where app is deployed on Wildfly 21.0.2. (as a WAR archive). Calling ObjectMapper#readValue throws java.lang.EnumConstantNotPresentException (detailed stack below).
There are no enums used in objects which I'm deserializing and I have already checked through Wildfly management console, that there is correct version of Jackson on deployed app. Now I am a bit clueless. Any ideas?
com.fasterxml.jackson.annotation.JsonTypeInfo$Id.DEDUCTION
at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector._findTypeResolver(JacksonAnnotationIntrospector.java:1424)
at com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector.findTypeResolver(JacksonAnnotationIntrospector.java:522)
at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findTypeResolver(AnnotationIntrospectorPair.java:225)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findTypeDeserializer(BasicDeserializerFactory.java:1584)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findPropertyTypeDeserializer(BasicDeserializerFactory.java:1748)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.resolveMemberAndTypeAnnotations(BasicDeserializerFactory.java:2116)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.constructCreatorProperty(BasicDeserializerFactory.java:1000)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addExplicitPropertyCreator(BasicDeserializerFactory.java:634)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addDeserializerConstructors(BasicDeserializerFactory.java:407)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:283)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:224)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:220)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:414)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:479)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4405)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4214)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3214)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3197)
Well, the problem was solved by explicit exclusion of Jackson related libraries in jboss-deployment-structure.xml file (as shown on code below). Without these exlusions Wildfly was forcing its own Jackson lib located in /wildfly/modules/system/layers/base/ path (e.g. wildfly/modules/system/layers/base/com/fasterxml/jackson/core/jackson-core) which is 2.10.5 for Wildfly 21.0.2. Wildfy is doing this regardless of specifing custom version in maven pom.xml. Also I wasn't able to find any mention about this "embedded" Jackson version in Wildfly through management console, so it was a bit pain to realize where is the problem. Maybe this will save someone else some time.
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.3">
<deployment>
<exclusions>
<module name="com.fasterxml.jackson.core.jackson-core" />
<module name="com.fasterxml.jackson.core.jackson-databind" />
<module name="com.fasterxml.jackson.datatype.jackson-datatype-jdk8" />
<module name="com.fasterxml.jackson.datatype.jackson-datatype-jsr310" />
<module name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider" />
<module name="org.jboss.resteasy.resteasy-jackson2-provider" />
</exclusions>
<dependencies>
<module name="jdk.unsupported"/>
</dependencies>
</deployment>
</jboss-deployment-structure>

JBoss - How can to exclude javax.validation in jboss-deployment-structure?

I have .war using Jersey REST, and it works in tomCat. But I need to run my .war in JBoss 6.4.0 which causes an exception
java.lang.RuntimeException: java.lang.NoSuchMethodError:
javax.validation.spi.ConfigurationState.getParameterNameProvider()
because JBoss uses old version javax.validation, and I need to exclude javax.validation from deployment of JBoss.
I create jboss-deployment-structure.xml in WEB-INF of .war:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="resteasy" />
<subsystem name="jpa"/>
<subsystem name="org.hibernate" />
<subsystem name="org.hibernate.validator" />
</exclude-subsystems>
<exclusions>
<module name="javaee.api" />
<module name="javax.ws.rs.api"/>
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
<module name="javax.validation.api"/>
<module name="org.hibernate"/>
<module name="org.hibernate.validator"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
This helped me to exclude javax.ws.rs, but How can to exclude javax.validation? Help me, please
Ok, so You need to exclude not only
<module name="javax.validation.api"/>
itself, but also modules that are dependent on javax.validation.api module. The easiest way to see which modules are dependent on javax.validation.api and force it to be included, even though it was excluded, is to search your .xml files in
JBOSS_DIRECTORY/modules for javax.validation.api, the modules that are dependent have something like that in module.xml:
<dependencies>>
<module name="javax.validation.api"/>
...
And those modules need to be excluded as well. For me - I also needed to exclude:
<module name="javax.faces.api"/>
<module name="org.jboss.resteasy.resteasy-hibernatevalidator-provider"/>
And then, javax validation eclusion was working :)
So, it is something! May be help to someone:
Library javax.validation.api in JBoss - belongs to Implicit module, documentation about implicit module: implicit module dependencies
So implicit modules are Automatic Dependencies, and their can exclusion, about this: class lading and automatic dependencies - part about Automatic Dependencies:
Automatic dependencies can be excluded through the use of jboss-deployment-structure.xml. But this is not work! :(, and JBoss has bug with similar library javax.persistence, and it bug open in tasks.
So - what can to do?
Update JBoss to 7.0.0 version, but now just Alpha and Beta versions :(
Replace old javax.validation.api .jar on new version .jar
(in EAP-6.4.0/modules/system/layers/base/javax/faces/api/main)
Add custom version, and it tangled:
change default config in EAP-6.4.0/modules/system/layers/base/javax/faces/api/main module.xml file, in line <module name="javax.validation.api" export="true"/> remove option export="true", result: <module name="javax.validation.api"/> This changed to allow you add a new custom library javax.validation.
And create custom folder with name 1.1 in EAP-6.4.0/modules/system/layers/base/javax/validation/api, put in 1.1 folder new javax.validation .jar and model.xml.
model.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="javax.validation.api" slot="1.1">
<resources>
<resource-root path="validation-api-1.1.0.Final.jar"/>
</resources>
<dependencies>
<module name="org.jboss.logging"/>
</dependencies>
</module>
params:
slot - name custom folder (1.1),
path - path to .jar library
Last: add module to jboss-deployment-structure.xml in project:
<dependencies>
<module name="javax.validation.api" slot="1.1" export="true"/>
</dependencies>

are ejb and jars subdeployments in an EAR

I've been having problems with jboss/logback and I made a jboss-deployment-structure.xml and it looks like this
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<ear-subdeployments-isolated>false</ear-subdeployments-isolated>
<deployment>
<!-- Exclusions allow you to prevent the server from automatically adding
some dependencies -->
<exclusions>
<module name="org.apache.commons.logging" />
<module name="org.slf4j" />
<module name="org.slf4j.ext" />
<module name="org.slf4j.impl" />
<module name="org.apache.log4j" />
</exclusions>
</deployment>
</jboss-deployment-structure>
this is in the META-INF folder of the EAR, but now I've been thinking... the EAR also has a lib folder that has:
slf4j-api.jar,
logback-classic.jar,
logback-core.jar, and
log4j-over-slf4j.jar
as well as the other two other ejb projects wrapped up in it during deployment time.
my question is, do I have to specify the jars and other other ejb projects as sub-deployments in the jboss-deployment-structure.xml??
also, the jboss-deployment-structure.xml has been basically ignored everytime I deploy the ear and start the server, i know this because the server still is accessing the exclusions i have declared, is the xml in the right spot in the meta-inf of the ear?
thank you for the help
Yes I added the jars as subdeployments and fixed errors

Differences between Jboss EAP6 and Weblogic 11 XML responses

I have a problem with a Webservice deployed in JBoss EAP 6.
I have a war file, that war contains a WS, but, that war originally was developed and tested in a Weblogic 11 AS; and everything works fine BUT
my boss said that my war can deploys in other server (JBoss) that he has mounted in other computer.
Everything is normal, but in the response, the date is different, i mean, in Weblogic, it appears like this:
<birthday class="com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl">
<year>1952</year>
<month>4</month>
<day>17</day>
<timezone>-360</timezone>
<hour>0</hour>
<minute>0</minute>
<second>0</second>
<fractionalSecond>0.000</fractionalSecond>
</birthday>
So, in JBoss EAP 6, the date appears whit more fields, like this:
<birthday class="org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl">
<orig__year>1944</orig__year>
<orig__month>3</orig__month>
<orig__day>1</orig__day>
<orig__hour>0</orig__hour>
<orig__minute>0</orig__minute>
<orig__second>0</orig__second>
<orig__fracSeconds>0.000</orig__fracSeconds>
<orig__timezone>-300</orig__timezone>
<year>1944</year>
<month>3</month>
<day>1</day>
<timezone>-300</timezone>
<hour>0</hour>
<minute>0</minute>
<second>0</second>
<fractionalSecond>0.000</fractionalSecond>
</birthday>
My question is, how can i switch the implementation of the de/serializer for this data type?
It seems, Weblogic uses the JDK interal classes to make the job, but JBoss uses it's own implementation.
I read about to add a xml file (jboss-deployment-structure.xml) to the war archive, i integrate one xml, like this:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="org.apache.xerces" />
</exclusions>
<dependencies>
<module name="sun.jdk" >
</module>
<system>
<paths>
<path name="com/sun/org/apache/xerces/internal/jaxp/datatype"/>
</paths>
</system>
</dependencies>
</deployment>
</jboss-deployment-structure>
If i understood well, that xml avoids the use of the JBoss XML implementation (xerces) then i can use the internal classes of the JDK; but the result is the same, any ideas?
I resolve my issue in this form:
I change the default xerces implementation, in this path
{JBOSS_HOME}\modules\system\layers\base\org\apache\xerces\main
I add two files: jaxp-api-1.4.5.jar and jaxp-ri-1.4.5.
And in the module.xml i made a change for the jar declared as a resource root, like this:
<module xmlns="urn:jboss:module:1.1" name="org.apache.xerces">
<resources>
<!--<resource-root path="xercesImpl-2.9.1-redhat-4.jar"/> -->
<resource-root path="jaxp-ri-1.4.5.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>
Now, my xml comes with the desired XMLGregorianCalendar implementation.
Cheers.

Categories