[jboss-dev] AS ClassLoading in Embedded Environments

Andrew Lee Rubinger andrew.rubinger at redhat.com
Fri Jan 29 22:01:22 EST 2010


Yes, this is exactly what we do presently.

Either:

1) Everything on --classpath[1]
2) Require the user to set TCCL to a special ClassLoader[2]

I was hoping that 2) could still be a phased CL model where the special 
ClassLoader (JBossHomeClassLoader) is still a more minimal set to start 
MC and let jboss-cl take over at the appropriate time.

Instead I think due to class references leaking we need to make 
JBossHomeClassLoader a more flat CL model equipped with everything in 
common/lib, lib, and server/name/lib.  This should still give us a 
smaller runtime launch dependency.

Agree with your points on the Maven plugin and O'Reilly EJB3 examples. 
In fact, it's my work w/ the book examples that keep showing me places 
we can/must improve usability in this area.  I want even setting the 
TCCL to be abstracted out, and we've got a couple ways to do this:

1) Maven Plugin does it
2) Arquillian does it
3) Hardcode a bootstrap lifecycle callback to do it. :)
4) User manually does it

My concern really is with this flat, everything-up-at-a-parent-CL 
approach.  Failing separation in the subprojects JARs though, I don't 
think it can be avoided now.

S,
ALR

[1] http://community.jboss.org/docs/DOC-14441
[2] http://community.jboss.org/docs/DOC-14447




On 01/29/2010 09:42 PM, Bill Burke wrote:
> I think what I did for old EMbedded JBoss was to have everything in
> system classpath.
>
> This won't work though I think because some components will require
> isolation.
>
> Why not just require the user to do:
>
> Thread.currentThread().setContextClassLoader(EmbeddedClassloader);
>
> ???
>
> If a maven plugin is ever created, the maven plugin could do this.
> Maybe take an existing application (like from the O'Reilly EJB3 book or
> something) and decide how you as a user would like it to be and go from
> there?
>
> Andrew Lee Rubinger wrote:
>> Open call for comments/suggestions.  I'm running low on ideas.
>>
>> ClassLoading in AS has a few phases:
>>
>> 1) Launch (application classpath, run.jar, some minimal APIs only)
>> 2) Bootstrap (A bunch of JARs in $JBOSS_HOME/lib, enough to start the
>> Kernel and deploy the bootstraps)
>> 3) Service Deployments (jboss-cl takes over, adding in support from
>> $JBOSS_HOME/common as appropriate)
>>
>> In an Embedded environment, the client is in the same JVM as the server.
>>    The TCCL of the Main Thread needs to be able to:
>>
>> * Establish a JNDI Context via "new InitialContext();"
>> * Deploy
>>
>> For these, TCCL needs to have access to runtime internals provided via
>> jbossall-client.jar.  If this is loaded by a parent CL of something it
>> references, we get NCDFE.  For instance:
>>
>> java.lang.NoClassDefFoundError:
>> org/jboss/deployers/vfs/spi/client/VFSDeploymentFactory
>> 	at
>> org.jboss.embedded.core.server.JBossASEmbeddedServerImpl.deploy(JBossASEmbeddedServerImpl.java:256)
>>
>> Here the AS deployment mechanism is loaded in a ClassLoader higher in
>> the hierarchy than VFS Deployers SPI.  I could move where we load VFS
>> Deployers SPI higher up, which would then leak out something else, and
>> on and on.
>>
>> I currently cannot concoct an environment where:
>>
>> * User has a minimal application ClassPath
>> * Other ClassLoading is transparent
>> * Everything works
>>
>> Some attempt to use an isolated ClassLoader result in ClassCastException
>> when equal FQNs end up w/ separate defining ClassLoaders.
>>
>> I believe I'm trying in vain to hack around the underlying problem where
>> the AS module system is not separated out to support this kind of use.
>> We have ClassLoading requirements not being met:
>>
>> * JARs safe for client use at all CL levels (ie. no references to
>> outside dependencies which would also need to be loaded by the same CL)
>> * JARs for compilation only, and runtime will be provided by the
>> container (ie. Maven scope "provided")
>> * JARs used by AS internals *only*.
>>
>> For now I think the only way forward is to either put:
>>
>> 1) Every single one of AS's dependencies on the application ClassPath
>>     * http://community.jboss.org/docs/DOC-14441
>> 2) Use a JBossHomeClassLoader which refers out to every AS runtime
>> dependency in $JBOSS_HOME/lib, $JBOSS_HOME/common/lib, and the server libs.
>>
>> S,
>> ALR
>>
>

-- 
Andrew Lee Rubinger
Sr. Software Engineer
JBoss by Red Hat
http://exitcondition.alrubinger.com
http://twitter.com/ALRubinger



More information about the jboss-development mailing list