I have a war that uses the errai-bus, which depends on guava 14.0.1. I'm deploying the app with Jboss, but when I do, Jboss is using its weld version of guava, which is guava r6 (very old). This causes horrible class loading issues and the errai-bus completely fails to work.
Even when I declare guava 14.0.1 as a top-level dependency in my pom, it still uses guava r6. How can I stop Jboss from loading the wrong guava version for my war?
I've tried to look up info about how to do this with the class loader files in Jboss AS 6, but I can't seem to find any documentation.
You can try add the following jboss-classloading.xml to your WEB-INF folder:
<classloading xmlns="urn:jboss:classloading:1.0"
name="mywar.war"
domain="mywar_domain"
parent-domain="Ignored"
export-all="NON_EMPTY"
import-all="true">
</classloading>
In this case, put the war's classloader in the mywar_domain which is shared with all other applications that don't define their own domain. Also choose to look at all other classes exported by other applications import-all and to expose all our classes to other classes export-all.
What you get when you deploy this file, is that the Web application classloader will act as top-level Classloader so there will be no conflict with the same classes in the server's library.
See also:
JBoss 5 - ClassLoading
Demystifying the JBoss5 jboss-classloading.xml file
Anyway JBoss AS 6 is out of date, and have a lot of de bugs unresolved. You would have to see the possibility of using a newer version (Wildfly or JBoss EAP 6).
Related
Application structure description: Ear application with ejb module (.jar), jboss-seam (.jar) and war module (.war).
I have a StartupAction.class (seam component) annotated with org.jboss.seam.annotations.Startup. During application deployment I need to get the resource from application.war module root (application.war/pages/page.xhtml) and WEB-INF/classes (application.war/WEB-INF/classes/file.properties)
Jboss 4.2
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.properties") would fetch the file from application.war/WEB-INF/classes/file.properties.
Jboss 7.1.1
Code from above doesn't work with Jboss 7.
I know that the class loading changed but I can't figure it out how to get into application.war in jboss 7.
Is it possible to do this? Are there any example of this?
Thanks in advance.
As mentioned by #BalusC, you will not be able to read a properties file that is embedded in a web module from any other modules (EJB or otherwise) that are packaged in your EAR.
The fact that this works in JBoss 4.x is a consequence of it providing backwards compatibility for even earlier versions of JBoss. Additional configuration is required in JBoss 4.x in order for it to use specification compliant class loading. JBoss 7.x and newer use specification compliant class loading by default.
If your properties file contains external configuration that is intended to be accessible after deployment then you might consider the approach described in How to put an external file in the classpath.
However, if it is effectively static data then you should package the properties file in a jar module and place it in the the lib directory of your EAR.
In jboss7, you have a classloader for each subdeploy.
In your case, Thread.currentThread().getContextClassLoader() will return the classloader of the current deployment.
To fix your problem, you could try this:
SomeRandomClassContainedInsideTheWAR.class.getClassLoader()
Check this guide to learn more about JBoss7 ClassLoader
https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7
I have a .war application module, that can be successfully deployed without any exotic changes and server tuning. However, i was unable to deploy this app to GF 3.1.2: server throws following exception:
java.lang.Exception: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.NoSuchFieldError: theInstance
What i am doing wrong? Has anyone suggest me something? Is there any additional settings that i should perform to deploy .war module successfully?
Thanks a lot in advance.
UPD
More precise log entry:
javax.xml.bind.JAXBException: Provider com.sun.xml.bind.ContextFactory_1_0_1 could not be instantiated: javax.xml.bind.JAXBException
- with linked exception:
[java.lang.NoSuchFieldError: theInstance]
- with linked exception:
[javax.xml.bind.JAXBException
- with linked exception:
[java.lang.NoSuchFieldError: theInstance]]
Sounds like a class loader issue.
You need your WEB-INF/lib JAXB jars used ahead of the GlassFish JAXB jars.
Or change your app to use the versions GlassFish 3.1.2 is bundled with.
Servlet spec says that web applications should use the local class loader before delegating to the parent. I think GlassFish delegates to the the parent class loader for web applications by default. Use <class-loader delegate="false"/> in web.xml or glassfish-web.xml.
Note there may be other ways to modify the class loader in GlassFish if this does not work.
This type of issue is common during deployment to many application servers.
I've used GlassFish daily for the last 5+ years and see this every so often.
Recently saw a similar issue when deploying to JBoss on CloudBees, and modified a deployment descriptor accordingly.
Googling "glassfish prefer web-inf/lib jars".
Response To psed comment below
EJB interfaces must reside in the class path hierarchy shared by the Web module and EJB module. If you have an EJB interface jar in WEB-INF/lib and another copy of the EJB interface jar on the EJB module classpath, you would get a ClassCastException when injecting/locating the EJB in your web application. I assume WebServices have the same issue. Sharing the EJB interface jar though an EAR should resolve this issue though. Note there may be other issues I am unaware of
You should not bundle JAXB jars with your application - Glassfish already has them, and it seems this is causing a conflict (incidentally, I've been digging through JAXB code recently, and theInstance is part of a static class defined by MarshallerImpl)
You should place your all jar files to your runtime server lib...
This instruction is for GlassFish 3.1.2
The issue is runtime classes from JAXB 2.2.5 are not backward compilable with JAXB 1 code.
This issue was fixed with JAXB 2.2.6, however, it's not in latest GlassFish release. So, either you wait until the next GlassFish upgrade or you do it manually.
Here is how i did,
I removed the 2 bundle files from GlassFish module
C:\glassfish3\glassfish\modules\jaxb-osgi.jar
C:\glassfish3\glassfish\modules\endorsed\jaxb-api-osgi.jar
Clear the osgi-cache by deleting all the subfolder in
C:\glassfish3\glassfish\domains\domain1\osgi-cache
Download JAXB 2.2.6 from ORACLE JAXB
Extract the zip file to a temp location [C:\Java\jaxb-ri-2.2.6\jaxb-ri-2.2.6\osgi]
copy C:\Java\jaxb-ri-2.2.6\jaxb-ri-2.2.6\osgi\jaxb-osgi.jar to C:\glassfish3\glassfish\modules\
copy C:\Java\jaxb-ri-2.2.6\jaxb-ri-2.2.6\osgi\jaxb-api-osgi.jar to C:\glassfish3\glassfish\modules\endorsed\
restart your server ... i hope this will help. Good Luck
So I am working on a project whereby we needed to create a custom Tomcat Realm implementation to read authentication credentials from a mongo backed datastore.
This has been pretty painless, but the implementation we have come up with has several dependencies on external libs i.e. scala libs, the java mongo-db driver, spring, salat (a mongodb ORM) etc....
Now in order for Tomcat to use this Realm we must deploy our Jar (and all the dependent jars) to tomcats lib folder.
Being pretty new to Java, I have no idea how much of an issue this is, but it doesn't seem nice to me. So really, my question is what issues would I have with dumping a load of JARs into Tomcats lib directory?
Cheers, Chris.
Most likely dependencies will become a problem. All JARs you place in tomcat/lib are visible to the WARs you deploy at a later time. I suppose your Realm implementation is the base for one or more web applications.
Let's say your Realm depends on Spring 2.0 and you're required to place those libs in tomcat/lib and afterwords you deploy a WAR using Spring 3.0. The WAR will see all classes available in tomcat/lib - the Spring 2.0 classes. So your WAR ships the 3.0 classes in WEB-INF/lib, at runtime it can see the Spring 2.0 libs in tomcat/lib as well as its own Spring 3.0 libs in WEB-INF lib. This is going to cause trouble...
I'm not aware of a simple solution for this, maybe you should have a look at OSGI and Tomcat integration. No question, it won't make life easier...
I'm using JBoss AS 4.2.3.GA and I want to make it to hot reload changed classes.
Now, I have a running JBoss AS with deployed exploded war, after changing (recompiling) some classes, it starts to redeploy all war:
14:14:03,732 INFO [StandardContext] Reloading this Context has started
and redeployment takes a very long time. I want to avoid such time wasting, and maybe there is a way to tell JBoss, just to replace changed class files w/o redeploying all the war?
I've also tried reloadable="true" in
jboss-4.2.3.GA\server\default\deploy\jboss-web.deployer\server.xml
But, perhaps, that's not what i seek. I don't know if it matters, but the exploded war's directory is external to server's /default/deploy/ dir. All my classes are in WEB-INF/classes dir.
You probably need to research framework-specific solutions. Look for OSGi, Spring Dynamic Modules, JEE6 dependency injection.
Also, there may be an Eclipse plugin that will facilitate this for you. I know there is one for Glassfish and JEE6.
What technology are you developing this with?
We need to use jasper reports in web application under JBoss on AIX.
Today we get a problem when we tried to add xml-apis to WEB-INF/lib - JBoss did not start at all.
What should we do in order to use xml-apis under JBoss?
PS.
As far as I know we need org.w3c.dom.xpath.XPathEvaluator and org.w3c.dom.svg.*
Are you sure you need to? JBoss already has those APIs in its standard library set, your WAR should automatically have access to them. Try removing the JAR from your WEB-INF/lib.
The only way to replace JBoss's copy of that JAR is to place it in the top-level JBoss lib/endorsed directory, and make sure it doesn't clash. This will affect the entire JBoss server, though, so you need to very sure you know what you're doing. JBoss itself uses these libraries.