-
1. More on BaseClassLoader conflict with Instrumentation....
alesj Feb 18, 2011 6:42 PM (in response to ted.hulick)* The classes in the BaseClassLoader pick up the classes from the sun Class Loader just fine - evidently, the BaseClassLoader IS delegating to the
sun base Class Loader EVEN THOUGH it shows that it's parent is NOT the base loader (which I normally see), but instead the parent being
null indicating a native or boot loader.
System Classloader
* The problem comes when code in the sun loader is called by the code in the BaseClassLoader and the javax.jms.Session interface seems to be loaded into the BaseClassLoader from jms.jar in the WAR (self first? as it DID NOT delegate down to the sun Class Loader) and all comes
apart when a class impl for javax.jms.Session created in the BaseClassLoader is then cast to javax.jms.Session in the sun Class Loader and
because they were loaded in 2 different class loaders they are not considered the same class and we get a Class Cast Exception.
Why exactly do you need that jms.jar in .war?
Self first is per the spec for web/.war deployments.
***** I want to either at runtime set the Classpath for the BaseClassLoader to my instrumentation classes which would resolve this issue OR
force ALL class loaders to delegate downstream to the jms.jar that I loaded in the sun AppClassLoader....
Add jboss-classloading.xml with parent-first=true attribute.
If you want that the rest of classes (non jms.jar) are still looked parent-first=false, you need a bit more work.
The new jboss-classloading-domain.xml in AS6 helps here, but unfortunately it has a few bugs, which are already fixed,
and as such will be part of next AS6.1 release.
-
2. More on BaseClassLoader conflict with Instrumentation....
ted.hulick Feb 23, 2011 7:37 AM (in response to alesj)First, I really appreciate your help...
Ok - I don't control the WAR file...essentially, our product montiors JBoss app server...the WAR in this case was written by QA...and they included jms.jar in their deployment. So, you are saying that if they DID NOT include it - it would have found the one I attached to the base system classloader?
And you are saying that by default the WAR will indeed load it's jms.jar and NOT look downstream to my jms.jar? Is there a way to override this behavior just for that 1 jar? Maybe via a property that was set? Can it be done programmatically? We can't ask the customer to change
their deployments.
On the jboss-classloading.xml to parent first...would this override the WAR file self-first? Again, can something be done via property or programmatically so customers don't have to alter their deployment.
Essentially, I'm just added some jars to the classpath using the addURL (and change protection) on the system classloader and then referring
to those classes in instrumentation....because they make reference to jms classes - I have to make sure jms.jar is in the system classloader
path as well. When anything else in the app loader loads jms.jar (which is only interfaces anyhow) classes from their own loader and now
delegate downstream to mine - then Class Cast issues occur as of course, a class instance in 2 different loaders is not considered to be
the same class.
Again - any help/suggestions is appreciated....
-
3. More on BaseClassLoader conflict with Instrumentation....
alesj Feb 23, 2011 9:28 AM (in response to ted.hulick)All deployments are metadata / attachment driven via deployers.
What this means in more human form? :-)
btw: did you read any of the DZone article's on Microcontainer topic?
Each configuration file is transfomed into some metadata class / instance.
And this metadata instance is added / attached to DeploymentUnit instance.
DeploymentUnit is what is passed between deployer instances -- see Deployer::deploy(DeploymentUnit unit).
DeploymentUnit's attachments are nothing more then a smarter semi type-safe Map.
As you can see deployers actually don't care where this metadata instances come from.
It could be either from parsed configuration or added programatically.
So, to answer your question, yes it can be done programmatically.
Simply add a new custom deployer to the existing chain of deployers.
Where you would add or replace or modify an existing ClassLoaderMetaData, which is jboss-classloading.xml is parsed into.