Choose a library version between Jboss modules and project dependencies - java

I'm trying to make a sign operation with a XML file. In this process, I use the xmlSec 1.5 library. If I run the code in a local test the process finishes successfully.
However, if I deploy the code in a war in a Jboss 7.1, my dependency with xmlSec 1.5 is override by Jboss by its module dependency "xmlsec-2.0.8.redhat-1", and the sign process fails.
For client's petition, I can exclude the xmlsec Jboss module, but I cannot use it to sign.
So, the problem is: how could I specify a given library version to be used only in a part of the code?.
In this case, the path of both dependencies are the same: org.apache.santuario, so, I cannot use it in order to specify the library.
I'm trying to use a provider for signing, but, again, Jboss override my xmlsec-1.5 security provider for its xmlsec-2.0.8 security provider. There exists some way to instanciate a provider and adds it to the set of java providers in order to replace the Jboss one?

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>
e.g. <module name="org.apache.santuario.xmlsec"/>

Related

Class loading issue with JBOSS 6.3.0

I'm running the following class loading issue with JBOSS.
My JBOSS's module.xml:
<module xmlns="urn:jboss:module:1.0" name="com.example">
<resources>
...
<resource-root path="spring-amqp-1.4.6.RELEASE.jar"/>
...
</resources>
</module>
When org.springframework.amqp.support.converter.DefaultJackson2JavaTypeMapper:getClassIdType(String classId) is called
MessageConversionException: failed to resolve class name... is thrown by
ClassUtils.forName(classId, getClass()
.getClassLoader())
Debugging getClass().getClassLoader() returns ModuleClassLoader for Module "com.example:main".
So it seems the issue is the class I'm deserializing is not in module com.example (defined in module.xml) so it throws that exception
Myjboss-deployment-structure.xml has com.example as a dependency:
<dependencies>
<module name="com.example">
<imports>
<include path="META-INF**"/>
</imports>
</module>
</dependencies>
I can fix this problem if I remove spring-amqp-1.4.6.RELEASE.jar from module.xml and add spring-amqp to my build.gradle. Problem is module.xml is shared across my org and I can't change that.
So how can I fix this? Appreciate any help.
A stacktrace (and some more code) to reproduce would be nice. I am not familiar with amqp.
In https://github.com/spring-projects/spring-amqp/blob/master/spring-amqp/src/main/java/org/springframework/amqp/support/converter/DefaultJackson2JavaTypeMapper.java at line 56, ClassUtils.forName(classId, getClass().getClassLoader()) gets called, but can't find the class.
In JBoss, module classloaders are seperated from application classloaders. In your application, you can access all classes from the module, but the module can't access your WAR or JAR classes.
So, this is exception is thrown, because your module, tries to load a class from your application, which is not visible in the module classloader. But if you add the amqp-jar to your application, it works, because they share the same classloader.
If you want/need amqp in a module, you need to create a module with your application common-classes and add it to your module as a dependency. But also note, you can't add the common.jar to the application.jar anymore to avoid classCastExceptions.
I don't know, how amqp is used, but probably, you need to create multiple modules to use it with different common.jars.
For more information about jboss classloading, i can refer you to:
http://www.mastertheboss.com/jboss-server/jboss-as-7/discover-jboss-as-7-modularity
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/chap-Class_Loading_and_Modules.html

Rhino explicitly required for Jawr's LESS Processor

jawr-core has the following dependency (see artifact details):
<dependency>
<groupId>org.mozilla</groupId>
<artifactId>rhino</artifactId>
<scope>provided</scope>
</dependency>
When processing LESS files I'm facing an exception saying java.lang.NoClassDefFoundError: org/mozilla/javascript/ScriptableObject
If adding rhino dependency explicitly with scope compile to my project the exception is gone.
But why Jawr has a dependency on it with scope provided when it is required to process LESS files?
The servlet container my webapp is running on is Tomcat 7.
jawr have made all their dependencies provided, not just the rhino dependency.
It looks to me like they are really worried about getting in the way of your server's classpath.
At this link: http://jawr.java.net/docs/postprocessors.html#YUI_compressor, they state the following:
...which might be problematic if you already have rhino on your server's classpath...
Can only presume that is why they are all provided. You then explicitly need to include the dependencies that you require for the functionality of jawr that you want to use.

Provider com.bea.xml.stream.MXParserFactory not found with JCL

I'm trying to develop an application which uses a library with a stax-api as a dependency. Build as stand-alone application it works fine, but when I'm trying to load JAR with dependencies assembled in my application using JCL, I get the following error:
javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found
at javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:72)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:178)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:92)
at javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:136)
at org.codehaus.xfire.util.STAXUtils.<clinit>(STAXUtils.java:48)
at org.codehaus.xfire.transport.http.HttpChannel.writeWithoutAttachments(HttpChannel.java:54)
at org.codehaus.xfire.transport.http.CommonsHttpMessageSender.getByteArrayRequestEntity(CommonsHttpMessageSender.java:422)
at org.codehaus.xfire.transport.http.CommonsHttpMessageSender.send(CommonsHttpMessageSender.java:360)
at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:123)
at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)
at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
at org.codehaus.xfire.client.Client.invoke(Client.java:336)
at eu.unicore.security.xfireutil.client.ReliableProxy.handleRequest(ReliableProxy.java:122)
at eu.unicore.security.xfireutil.client.ReliableProxy.doInvoke(ReliableProxy.java:102)
at eu.unicore.security.xfireutil.client.ReliableProxy.invoke(ReliableProxy.java:69)
at com.sun.proxy.$Proxy71.QueryResourceProperties(Unknown Source)
at de.fzj.unicore.wsrflite.xmlbeans.client.BaseWSRFClient.queryResourceProperties(BaseWSRFClient.java:372)
at de.fzj.unicore.wsrflite.xmlbeans.client.RegistryClient.listServices(RegistryClient.java:199)
at de.fzj.unicore.wsrflite.xmlbeans.client.RegistryClient.listAccessibleServices(RegistryClient.java:214)
at org.caebeans.wsrf.UNICOREModule.initialize(UNICOREModule.java:53)
... 9 more
It's rather strange, this class is assembled into the JAR, I can find it in archive.
I've seen this kind of message when application server libraries are loaded before application ones. Usually there's a setting that lets you specify the inverse order. If, as it seems, you're using Weblogic this may be achieved by inserting the following definition in your weblogic.xml file:
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
Try adding this Maven dependency:
<dependency>
<groupId>stax</groupId>
<artifactId>stax</artifactId>
<version>1.2.0</version>
</dependency>

JBoss 7.x SAR archive class loading issue

I am trying to build a sar archive that contains an MXBean and deploy it in JBoss 7.
Until recently I had a problem referencing classes from other libraries in my MXBean class because JBoss wouldn't load those libraries no matter where in the SAR archive I'd put them.
I found out that one can configure the classpath of a SAR through the jboss-deployment-structure.xml file placed in META-INF. My version of this file looks like this:
<jboss-deployment-structure>
<deployment>
<resources>
<resource-root path="management.api.jar" />
</resources>
</deployment>
Now the classes from the "management.api.jar" are loaded.
The problem I am now facing is the following: If the interface of the MXBean is stored in the management.api.jar and the class implementing it is directly in the SAR archive, then, when JBoss reads the jboss-service.xml and tries to create the mxbean it yields a ClassNotFoundException pointing to the interface (that is in the management.api.jar). Hence, although classes from the external jar are loaded ok (i tested this by actually invoking a method that referenced a class from the jar and it worked), it seems that when JBoss registers the bean, it doesn't go through the whole classpath as defined in the jboss-deployment-structure.xml.
I am currently stuck and I suspect this to be a bug in the way JBoss handles the class loading. If anyone knows a way around this (other than taking the interface out of the jar and putting it in the SAR archive directly, cause this will break the whole "api" idea) please let me know.
Thanks!
When I understand it right, the management api should be used in different projects and should be global in the server. A simple workaround can be to put your jar in the module-folder of your jboss. Therefor create a module.xml like this below and put it with your jar in a extra-folder main in the jboss7/modules/yourfolder.
(In the module folder the jboss 7.1 stores all libs.)
<!-- defines the name of your lib -->
<module xmlns="urn:jboss:module:1.1" name="yourfolder">
<resources>
<!-- the jar in your main folder-->
<resource-root path="management.api.jar"/>
<!-- Insert resources here -->
</resources>
<dependencies>
...dependencies of your api
</dependencies>
</module>
Then you can load the dependency from your sar-jboss-deployment-structure by
<dependencies>
<module name="yourfolder" slot="main" export="true"/>
</dependencies>
The slot=main means that you use the the folder main, you can add different versions, like 1.1 and so on. Main is also the default slot, you can leave it out.
If your folder-structure goes into deep, simple define and include the modules like packages.
In that way you can define api.jars in the jboss and reference it from several projects.

Web Service dependencies on another Web Service

I have a web service WebService1 that is deployed on JBoss (4.2.3.GA).
WebService1's endpoint is Endpoint1.
I wrote a WebService2 which dependends on WebService1. When Maven creates the .EAR file, it places the .JAR with WebService1 in WebService2's .EAR.
So, when I deploy WebService2 in JBoss I get the exception:
Endpoint1 has already registered.
If I remove class with Endpoint1 from the .JAR in the .EAR, then it's all normally deployed. But I can't remove this class after every project building.
Any ideas?
If you have a dependency that you don't want packaged with your maven build, use the "provided" dependency scope like this:
<dependency>
..
<scope>provided</scope>
..
</dependency>
This will allow Maven to compile the project, but won't include said dependency with the final package. More information here.
Is this what you were looking for?

Categories

Resources