I'm running an application on WildFly 10. It contains a number of EJBs in an EAR. I have one EJB "gt" being triggered via JMS. That EJB calls another EJB "ps", resulting in an error, ultimately
Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.filefilter.IOFileFilter from [Module "deployment.MyApplication.ear:main" from Service Module Loader]
My jboss-deployment-structure.xml contains this
<sub-deployment name="ps.jar">
<dependencies>
<module name="org.apache.commons.io"/>
</dependencies>
</sub-deployment>
And there is a module of name "org.apache.commons.io" under jboss\modules\system\layers\base\org\apache\commons\io\main
What am I doing wrong?
What is the significance of stuff being under jboss\modules\system\layers rather than just under jboss\modules?
Is there a way to look into the configured dependencies of a sub-deployment at runtime, e.g, via the jboss-cli?
Update:
According to https://docs.jboss.org/author/display/WFLY10/Class+Loading+in+WildFly, I would have expected the error message to say [Module "deplyoment.MyApplication.ear.ps.jar:main" ...], but it doesn't. But why would the context be the global deployment, rather than the specific sub-deployment?
The logical call stack looks like this:
general.GeneralSomeClass.getIOFileFilter()
<-- static method. return type is IOFileFilter from Commons IO.
general is just a POJO lib (MyApplication.ear/lib/general.jar)
the exception occurs on loading the GeneralSomeClass, before calling the method
ps.PsSomeClass.run()
ps.PsEJB.run()
gt.GtEJB.run()
You need to load the classes manually in that case, I have done this in the standalone.xml for our application.
<subsystem xmlns="urn:jboss:domain:ee:4.0">
<global-modules>
<module name="com.tibco.tibjms"/>
<module name="org.apache.logging.log4j.api"/>
<module name="org.apache.logging.log4j.core"/>
<module name="org.apache.logging.log4j.web"/>
</global-modules>
We ended up using the Dependencies: option in MANIFEST.MF, getting rid of the jboss-deployment-structure.xml altogether.
Related
I have Ejb webservice project ,and other web projects ,which I am deploying through EAR on Wildfly 10.x server,
the war project and the Ejb project require oracle.sql.OPAQUE for creating xml data through xdb jars,
For oracle.sql.OPAQUE I have added ojdbc6 in the project build path and added it in the deployment descriptor as well,
I have added ojdbc6 drivers in the wildfly module as well, for jdbc connections.
On deploying the project, there are no errors, where as when running the page, I am getting oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE: java.lang.ClassCastException: oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE
it seems like the classloader has loaded the oracle.sql.OPAQUE twice and thus its a problem
I have tried removing the ojdbc6 from the deployment descriptor, but
then that throws noclassdeffounderror on the EAR deployment itself.
if somebody could please tell me how do I resolve this classloader issue,
on wildfly server side, it would be helpful.
or to force it to use the class from particular side.
thanks alot, please provide any possible links, I would be grateful to you.
10:24:39,460 INFO [icrCommon] (default task-8) ++++ QueryRequest queryXMLAccess() - ContextKey:256574422:190508:210142844 TypeId: 0 Channel: CAP
10:24:40,521 SEVERE [com.sun.xml.ws.server.sei.EndpointMethodHandler] (default task-8) oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE: java.lang.ClassCastException: oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE
at com.att.icr.dataAccess.ICRDatabaseAccess.IcrActiveHistoryXMLQuery(ICRDatabaseAccess.java:2093)
at com.att.icr.icrservices.datamapping.ICRDataAccess.queryXMLAccess(ICRDataAccess.java:1161)
at com.att.icr.icrservices.ICRSoapHttpBindingImpl.queryICR(ICRSoapHttpBindingImpl.java:307)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
This issue relevant class loading issue in Wildfly. As you know Wildfly has a modular class loading structure. Each module has a own Classloader. It is not enough that the class types are the same. Must be the same in Classloaders. In JBoss doc:
WildFly's class loading is based on modules that have to define explicit dependencies on other modules. Deployments in WildFly are also modules, and do not have access to classes that are defined in jars in the application server unless an explicit dependency on those classes is defined.
You can create custom module and provide .ears load jar within this module. Create module.xml file in $JBOSS_HOME/modules/com/example/main/, Write the jar's name you want to load into module.xml.
<module xmlns="urn:jboss:module:1.5" name="com.example">
<resources>
<resource-root path="sample.jar"/>
</resources>
Copy the jar to the path where module.xml is located.
+-----com
+-----example
+-----main
module.xml
sample.jar
Create deployment descriptior(jboss-deployment-structure.xml) in .ears and add your module to this files.
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<deployment>
<dependencies>
<module name="com.example" export="true" />
</dependencies>
</deployment>
</jboss-deployment-structure>
So, Jar's classloaders are the same. You can look into this example and redhat doc.
Migrating an existing project to maven and wildfly and had to move some files around creating the following situation.
core.jar
ejb1.jar
ejb2.jar
With the ejb-jar.xml for ejb1.jar having the following:
<ejb-jar>
<enterprise-beans>
<session id="Value">
..
<home>path.to.ejb1Home</home>
<remote>path.to.ejb1</remote>
...
The classes referenced in the home and remote tags have moved to be inside core.jar
Meanwhile ejb2.jar has dependencies on other parts of core.jar.
What looked like the easiest resolution was to create a global module and place core.jar in it, creating the appropriate module.xml and entry in standalone.sh to make it accessible to all deployments.
module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="path.to">
<resources>
<resource-root path="core-1.0.jar"/>
</resources>
<dependencies>
</dependencies>
</module>
With this setup, ejb2.jar deploys as expected but ejb1.jar throws the following error:
Caused by: java.lang.NoClassDefFoundError: Failed to link path.to.ejb1
(Module "path.to" from local module loader #4c40b76e (finder: local
module finder #2ea6137 (roots: /opt/wildfly/modules,
/opt/wildfly/modules/system/layers/base))): javax/ejb/EJBObject
You should carefully think about your requirement. Usually, you don't need to provide common resources, especially application interfaces, as module, especially as global module. Choose the right solution for your requirements, not a solutions that looks easy at first sight without knowing the implications.
I would recommend these possibilities in the order given (see the Class Loading in Wildfly Documentation for more information):
Reconsider your requirement for different EARs. Provide the core jar as library with your EAR.
Even with more than one EAR: provide the core.jar as library. This is no redundancy, this is just separation.
Consider not using a global module. Just install your custom module. Provide a jboss-deployment-structure.xml file, adding this module as additional dependency. If the module contains annotated classes or interfaces, which should be considered upon deployment, set the attribute annotations=true with the module dependency configuration.
Add a global module to your configuration file. Probably you can even use the `annotations' property, but this is something I don't know and I didn't check.
An example for the jboss-deployment-structure.xml file:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.3">
<ear-subdeployments-isolated>false</ear-subdeployments-isolated>
<deployment>
<dependencies>
<module name="my.custom.module" export="true" annotations="true"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
EDIT:
When installing modules, don't forget to provide transitive module dependencies to other modules your own module depends on. User your module.xml file to do so. In your case, you probably need at least a dependency to the javax.ejb.api module.
I'm pretty new to JBoss and I'm trying to deploy a .war file on JBoss version 7.0.6 GA.
The .war file is created with the "export as .war file" option in Eclipse.
If I deploy the same .war file on Tomcat, it works without any error.
When I deploy on Jboss, I came across this strange error:
2017-10-20 17:29:26,803 ERROR [stderr] (ServerService Thread Pool -- 106)
Caused by: java.lang.IllegalAccessError: Failed to link
org/apache/log4j/xml/ExtXMLWatchdog (Module "deployment.
[MY_WAR_NAME].war:main" from Service Module Loader): class
org.apache.log4j.xml.ExtXMLWatchdog cannot access its superclass
org.apache.log4j.xml.XMLWatchdog
I'm using the log4j-1.2.17.jar library inside my web app; also, I'm using another custom library named util-log4j.jar.
Inside the log4j-1.2.17.jar is defined the class org.apache.log4j.xml.XMLWatchdog; inside the util-log4j.jar is defined the class
org.apache.log4j.xml.ExtXMLWatchdog.
It seems that the ExtXMLWatchdog cannot see the XMLWatchdog defined in another .jar, but why?
Thank you,
cheers!
Ok, I solved it. Sharing the solution:
inside the .war file, in the WEB-INF folder, I put a file named
jboss-deployment-structure.xml
with this content:
<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<deployment>
<exclusions>
<module name="org.apache.log4j" />
</exclusions>
<exclude-subsystems>
<subsystem name="org.apache.log4j" />
</exclude-subsystems>
</deployment>
It seems that JBoss is equipped with some standard library, but those libraries maybe are loaded by a different ClassLoader (not sure of this, however)
With that file, essentially I'm telling to JBoss to ignore it's own org.apache.log4j library.
The result is that my log4j library is used, and problem is gone!
We want to exclude the modules\system\layers\base\javax\servlet\jstl\api\main\jboss-jstl-api_1.2_spec-1.1.2.Final.jar from our web application deployment (WAR file).
Hence we have the following configuration in src\main\webapp\WEB-INF\jboss-deployment-structure.xml:
<?xml version='1.0' encoding='UTF-8'?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="javax.servlet.jstl.api"/>
</exclusions>
<dependencies>
<module name="deployment.my-dependencies.jar"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
In the Wildfly log I see that my-dependencies.jar is added as a ModuleDependency. But when searching for javax.servlet.jstl.api I only see this:
2015-04-03 15:22:11,971 DEBUG [org.jboss.modules] (ServerService
Thread Pool -- 12) Module javax.servlet.jstl.api:main defined by local
module loader #1f7c9157 (finder: local module finder #2b29f6e7 (roots:
C:\Users\me\Documents\wildfly-8.2.0.Final\modules,C:\Users\me\Documents\wildfly-8.2.0.Final\modules\system\layers\base))
Why isn't the module excluded?
Update: It seems that modules that are part of a user dependency can not be excluded.
It seems like the mechanism doesn't work as described in the Wildfly documentation. I was not able to exclude that module.
Yep. I was trying to upgrade to Spring Framework to v4.3. It has upped some minimum dependency requirements. One such example is Jackson min version required is 2.6+
Wildfly loads jackson that comes packaged (v2.4.1 in Wildfly 8.2.1), and it won't be excluded using jboss-deployment-structure.xml.
I was trying to see if the upgrade did not involve making changes to the installed server which takes this upgrade out of source control.
im trying to migrate my JBOSS 5.1 application to JBOSS 7.0.2. In admin console i select deployments -> add content and my .war and try to enable it.
I already resolved some problems, but cant figure out this one: (in short, in long at the end)
Caused by: java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener from [Module "deployment.ZaprogsProject.war:main" from Servic
e Module Loader]
I copied to JBOSS7\standalone\lib\ the following files:
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-context-support-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-jdbc-3.0.5.RELEASE.jar
spring-orm-3.0.5.RELEASE.jar
spring-test-3.0.5.RELEASE.jar
spring-tx-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar
I have read this: https://docs.jboss.org/author/display/AS7/How+do+I+migrate+my+application+from+AS5+or+AS6+to+AS7 (Debug and resolve ClassNotFoundExceptions and NoClassDefFoundErrors) but cant find a solution for me and still getting the same error. Can anyone help?
22:19:12,091 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC00001: Failed to start service jboss.deployment.unit."ZaprogsProject.war".INSTALL: o
rg.jboss.msc.service.StartException in service jboss.deployment.unit."ZaprogsProject.war".INSTALL: Failed to process phase INSTALL of deployment "ZaprogsProject
.war"
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:121) [jboss-as-server-7.0.2.Final.jar:7.0.2.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1824) [jboss-msc-1.0.1.GA.jar:1.0.1.GA]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1759) [jboss-msc-1.0.1.GA.jar:1.0.1.GA]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [:1.7.0]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [:1.7.0]
at java.lang.Thread.run(Thread.java:722) [:1.7.0]
Caused by: java.lang.RuntimeException: Failed to load class org.springframework.web.context.ContextLoaderListener
at org.jboss.as.ee.component.deployers.EEClassConfigurationProcessor$1.compute(EEClassConfigurationProcessor.java:141)
at org.jboss.as.ee.component.deployers.EEClassConfigurationProcessor$1.compute(EEClassConfigurationProcessor.java:122)
at org.jboss.as.ee.component.LazyValue.get(LazyValue.java:40)
at org.jboss.as.ee.component.EEApplicationDescription.getClassConfiguration(EEApplicationDescription.java:183)
at org.jboss.as.ee.component.ComponentDescription.createConfiguration(ComponentDescription.java:153)
at org.jboss.as.ee.component.deployers.EEModuleConfigurationProcessor.deploy(EEModuleConfigurationProcessor.java:70)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115) [jboss-as-server-7.0.2.Final.jar:7.0.2.Final]
... 5 more
Caused by: java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener from [Module "deployment.ZaprogsProject.war:main" from Servic
e Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:361)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:333)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:310)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:103)
at java.lang.Class.forName0(Native Method) [:1.7.0]
at java.lang.Class.forName(Class.java:264) [:1.7.0]
at org.jboss.as.ee.component.deployers.EEClassConfigurationProcessor$1.compute(EEClassConfigurationProcessor.java:139)
... 11 more
JBoss AS 7 does class-loading in a diff way.
All classes in the WAR are loaded with the same class loader. This means classes packaged in the WEB-INF/lib are treated the same as classes in WEB-INF/classes.
Hence it works for you.
But as you have said correctly your WEB-INF/lib is bloated.This would not be the correct way.
You would need to make a module :
Goto modules folder, make folder structure with main folder and put your jar and modules.xml with entries in it.
Something like :
<main-class name="org.jboss.msc.Version"/>
<resources>
<resource-root path="jboss-msc-1.0.1.GA.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.modules"/>
<!-- Optional deps -->
<module name="javax.inject.api" optional="true"/>
<module name="org.jboss.threads" optional="true"/>
<module name="org.jboss.vfs" optional="true"/>
</dependencies>
You would also need to update MANIFEST as well.
Details are here :
https://docs.jboss.org/author/display/MODULES/Module+descriptors
I would not put those JARs in that directory. Try them in your WAR file's WEB-INF/lib. The class loader will find them there.
You need to understand that all Java EE app servers use a hierarchy of class loaders: bootstrap, server, application. JBoss wasn't finding that class when it needed to.
There is a major change Jboss 7 when compared to previous versions.If you want to access any libraries outside your war file, it should be installed as module.
Check https://docs.jboss.org/author/display/MODULES/Introduction
In this case you should install Spring as module and specify the name of the module as dependency in your application's manifest file(check Manifest module information)
In case the issue started occurring all of a sudden(just like in my case), deleting the application (MyApp) physically from #JBOSS_HOME#\standalone\deployments\ MyApp.war worked for me.