JBOSS AS 7 custom class loader not working - jboss

We recently moved to JBOSS AS 7.Since it is based on OSGi and all modules are isolated, we are having a problem.
One of our jars is loaded by a URLclassloader from a specified directory outside of the JBOSS modules.
Class[] parameters = new Class[]{URL.class};
URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
Method method = sysclass.getDeclaredMethod("addURL",parameters);
method.setAccessible(true);
method.invoke(sysloader,new Object[]{ flist[i].toURI().toURL()});
flist[i] contains the jar with complete path to be loaded.
Where as this used to work previously, after AS 7, this class is not getting loaded.
I know you can add these jars to the modules folder and specify dependency. But we want this to work.
Is there a solution for this?

As others have said, JBoss AS 7 is not based on OSGi, it uses its own module system (JBoss Modules). What you're doing (reflection on classloaders) is against any rules, totally unsupported and worked only by accident. You you should is the following:
create a JBoss module for your JAR (the link is for a database module but should work with any JAR)
use jboss-deployment-structure.xml to reference that module

Related

How to solve ClassCastException for same class in Jboss EAP 6.5

I have created and deployed one war for my application.
I wanted to use derby for integration testing so I created one module in Jboss.
At run time I am getting ClassCastException for same class, since the class is getting loaded twice: first from war, then from my module's jar.
To elaborate, my war, say application.war contains myderby.jar and under my module i have added myderby.jar .My class, say Custom.java, is present in myderby.jar.
If you want a jar to be accessible to multiple WARs, JARs, or an EAR and a WAR/JAR - or in fact any such combination, you can include it as a global module. Here's how it can be done.
This might also help.
As Suggested I followed the following link
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Administration_and_Configuration_Guide/Add_a_module_to_all_deployments.html and it worked for me.

How to deploy two cross-dependent EARs in JBoss 7 in order to prevent ClassCastExceptions?

I have a problem when deploying two ear files in Jboss 7 and would be thankful for your help.
Following scenario:
EAR 1 contains EJBs which are looked up by EAR 2 (also) at server startup. Thus, EAR 1 has to be deployed before EAR 2 (via jboss-deployment-structure.xml dependency settings).
Right after being deployed, EAR 1 also needs access to classes contained in EAR 2 because of Hibernate and JNDI related class loading (among others).
But as EAR 2 isn't deployed at that time, there's a need for EAR 1 to contain a client-jar file of EAR 2.
Now, the problem is that in the course of EAR 1 and EAR 2 configuration (at server startup) ClassCastExceptions occur because...
(non-EJB) Java object obj1, whose class C was loaded by the classloader of EAR 1, is bound in JNDI
and after being looked up, supposed to be cast to object obj2 whose class C was loaded by the classloader of EAR 2
Now I wonder, if there's a possibility that these common classes of EAR 1 and EAR 2 are being loaded with the same classloader in JBoss 7. I already tried to put them in a server module, which didn't work out.
Thanks a lot for your help in advance!
PS: I'm aware of the poor design declared above. But due to restrictions, I have to follow up on it.
To avoid class cast exceptions, the common libraries need to be put in a classloader that is common to all applications in the two EARs, and no other copies of those libraries should exist in each application.
If it's an option to use only one EAR instead of two, put all the WARs inside a single EAR, remove the common classes from the WARs and put them on the EAR library folder.
This will associate the common classes to the EAR classloader, which is common to all the applications running inside a EAR, so that would solve the problem.
If you must use two EARS, then the common classes need to be put in a classloader at the level of the server shared by all applications.
JBoss 7 is an OSGI based container that allows to create an isolated module with a few jars and link it to an application. So if you try this:
create a module with the common library AND it's dependencies, see instructions here
link the module to all applications
remove the copies of those libraries from all applications and leave them only at the module
It will work fine, but don't forget to put the dependencies of the common library in the module as well otherwise it will not work, the dependencies need to be visible at the level of the module, and there can be no duplicate jars between module and applications (otherwise class cast exceptions might happen).
Another way far less recommendable but it would also work, is to put the common classes at the level of the common classloader, see this diagram. The common classloader folder is located at $CATALINA_HOME/lib (Jboss is based internally on Tomcat).
Specially if there are other applications running in that server don't try the second option. It could help to have a look at a tool I built for these type of issues, JHades.

JBoss eap 6 (as 7) - 2 different classes with same package and name

I am having an issue with a 3rd party developer.
They have provided a number of jars, and unfortunately in 2 different jars they have different implementations of a class (same name, same package).
We deploy using a single war file where both jars (among many others) are packaged together in web-inf/lib directory and unfortunately both jars are needed.
Is there a way where I can guarantee in JBoss eap 6 that the class from a.jar gets loaded before the class from b.jar?
Thanks.
All of your answers about classloading on JBoss can be found here at this link. But since now I advise you to read the "JBoss Deployment Structure File" section
With the "jboss-deployment-structure.xml" JBoss specific deployment descriptor you can control class loading in a fine grained manner. It should be placed in the top level deployment, in META-INF (or WEB-INF for web deployments). It can do the following:
Prevent automatic dependencies from being added
Add additional dependencies
Define additional modules
Change an EAR deployments isolated class loading behaviour
Add additional resource roots to a module

Esper deployment on jboss as 7.X, event type or class name not found

I have developed a java ee project to be deployed on jboss as 7 server.
scenario is
A java ee project in which ejb module contains execution classes.
some of the pojo events are defined in another plain java project lets say p1
and p1 is referenced in java ejb module and it appears in ./lib directory
of ear where other jar files exists.
auto-import tag in esper-config.xml has been added for p1 classes.
"cepConfig.cnfigure(esper-config.xml)" executes fine and
I can see all event types as reuired in debug mode.
"EpServiceProvider.getProvider("MyEngine",cepConfig)" results in error
which says "could not find event type or class named p1.mypack.class1"
I have checked reference and deployment settings of projects. p1.jar exists in ./lib directory.
All classes are public and accessible. what other things i need to check?
That class "p1.mypack.class1" would need to be part of the classpath, either the Jboss system classpath or the module classpath.

How to use 3rd party libraries in glassfish?

I need to connect to a MongoDB instance from my EJB3 application, running on glassfish 3.0.1. The Mongo project provides a set of drivers, and I'm able to use them in a standalone Java application.
How would I use them in a Java EE application? Or maybe better phrasing: how would I make a 3rd party library available to my application when it runs in an EJB container?
At the moment, I'm getting a java.lang.NoClassDefFoundError when deploying a bean that
tries to import from the library:
[#|2010-03-24T11:42:15.164+0100|SEVERE|glassfishv3.0|global|_ThreadID=28;_ThreadName=Thread-1;|Class [ com/mongodb/DBObject ] not found. Error while loading [ class mvs.core.LocationCacheService ]|#]
[#|2010-03-24T11:42:15.164+0100|WARNING|glassfishv3.0|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=28;_ThreadName=Thread-1;|Error in annotation processing: java.lang.NoClassDefFoundError: com/mongodb/DBObject|#]
[#|2010-03-24T11:42:15.259+0100|SEVERE|glassfishv3.0|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=28;_ThreadName=Thread-1;|Exception while loading the app
org.glassfish.deployment.common.DeploymentException: java.lang.NoClassDefFoundError: com/mongodb/DBObject
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:171)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:125)
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:224)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:338)
I tried adding it to the NetBeans project (Properties -> Libraries -> Compile -> Add Jar, enable 'Package'), and I also tried manually copying the jar file to $GF_HOME/glassfish/domains/domain1/lib (where the mysql-connector already resides).
Do I need to 'register' the library with the container? Reference it via Annotation? Extend the classpath of the container to include the library?
Hmm... Shouldn't you put this "driver" in glassfishv3/glassfish/domains/domain1/lib/ext?
You could put shared libs to lib/ext of your domain. commons-logging and jdbc drivers are often added in this domain path.
Common Class Loader
GlassFish v2 has a well defined Class
Loader hierarchy which identifies the
common class loader as the proper way
to deal with shared libraries. So to
make a long story short, putting you
libraries and other framework JARs in
domains/domain1/lib is all you need to
do.
lib/, not lib/ext
The person asking me the question had
tried putting the libraries in
domains/domain1/lib/ext which
triggered an interesting
ClassNotFoundError for core Java EE
classes such as
javax.servlet.http.HttpServlet. Shing
Wai Chan was quick to explain that
domains/domain1/lib/ext is part of
-Djava.ext.dirs which makes any of its JARs be considered as a JDK extension
which means web app frameworks placed
there will be loaded before
webcontainer implementation classes as
they are higher up in the classloader
delegation chain.
Glassfish has own Class loader hierarchy, http://docs.oracle.com/cd/E19798-01/821-1752/beade/index.html
I face the same problem in my project and then I put all my Third party libraries in domain/domain1/lib and my problem solved. On other way round, my problem was solved too by putting libraries in glassfish/lib.
In my case I was using Oracle Express Edition 11gR2 and Glassfish 3.1.2 and the ONLY way that works in my case was putting the ojdbc6 in:
C:\Program Files\glassfish-3.1.2.2\glassfish\lib
Go to your Glassfish doamin directory.
Then go to lib folder.
Place the libraries there.
Restart the glassfish and run.
(Ex) C:\glassfish3\glassfish\domains\domain1\lib
Try to put Your libs into $GF_HOME/glassfish/modules/.
It's dirty, but will work.