These are good points that I've been trying to push off until a later release, but I
think it's important enough to address for the upcoming EmbeddedAS 1.0.0-alpha-1.
https://jira.jboss.org/jira/browse/EMB-73
A bit of an overview first.
Booting AS is a tricky business which involves careful placement of libraries into the
proper ClassLoaders. If we leak out references in a parent CL to something that's
visible to a child, then NCDFE pops up. This is why we have the ugly
DEFAULT_LIBRARY_BOOT_LIST in org.jboss.Main.
The first hacky solution was a sledgehammer approach where *all* AS dependencies make
their way into the application classpath, hence the AppCL can see everything. This is
what's done in the EmbeddedAS "testsuite" module for instance, where the
sole dependency declaration is upon "depchain".
EMB-73 introduces a better mechanism whereby the client becomes responsible for:
1) Putting EmbeddedAS APIs and referents on the application classpath (so the test may be
loaded)
2) Constructing a URLClassLoader armed with the AS boot libraries required for the server
to start
3) Loading a server instance and starting it within the context of that CL.
The overall process looks like this:
// Get JBOSS_HOME
| final URL jbossHome = this.getJBossHome();
|
| // Make the new ClassLoader
| final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
| final ClassLoader jbossHomeClassLoader =
JBossHomeClassLoader.newInstance(jbossHome, additionalUrls
| .toArray(new URL[]
| {}), oldCl);
|
| // Make Server
| server = JBossASEmbeddedServerFactory.createServer(jbossHomeClassLoader);
|
| // Start
| log.info("Starting Server: " + server);
|
| // Set TCCL
| Thread.currentThread().setContextClassLoader(jbossHomeClassLoader);
|
| try
| {
| // Start the Server
| server.start();
| log.info("...started.");
|
| // Test
| TestCase.assertEquals("Server did not report started as expected",
LifecycleState.STARTED, server.getState());
|
| // Shutdown if started
| if (server != null &&
server.getState().equals(LifecycleState.STARTED))
| {
| // Shutdown
| log.info("Shutting down server: " + server);
| server.shutdown();
| }
| }
| finally
| {
| // Reset the TCCL
| Thread.currentThread().setContextClassLoader(oldCl);
| }
And the application classpath has very little on it; only API-level stuff:
[alr@localhost testsuite-jbosshomecl]$ mvn dependency:tree
| [INFO] +- org.jboss.embedded:jboss-embedded-api:jar:1.0.0-SNAPSHOT:test
| [INFO] | +- org.jboss.bootstrap:jboss-bootstrap-api-as:jar:2.0.0-alpha-2:test
| [INFO] | | \- org.jboss.bootstrap:jboss-bootstrap-api:jar:2.0.0-alpha-2:test
| [INFO] | \- org.jboss.shrinkwrap:shrinkwrap-api:jar:1.0.0-alpha-2:test
| [INFO] \- junit:junit:jar:4.6:test
Note that no longer are we polluting the classpath or repackaging binaries in this
approach. Looking forward I want AS Main to build off this same structure.
Regarding your questions, in general doing the type of testing of AS internals is a bit
risky because if your test relies upon nonpublic code, it's likely that you'll
need to load in nearly all of AS libs on the AppCL. Even one reference to the MC Kernel
infers things like logging, jboss-man, jboss-dep, vfs, aop, etc...so for this usage I
think "depchain" is the easiest way to get everything in one go.
I don't have a specific solution to the versioning problems you illustrate. AS very
carefully selects its thirdparty dependencies and once we start changing things, I expect
havoc.
"Jaikiran" wrote : 1) Relying on Maven (or more generically a dependency
resolution tool) to bring in the right set of dependencies to boot the AS *from within
some other project* probably isn't the right thing? i.e. project A which is a client
of the Embedded server API, might need it's own version of an artifact which conflicts
with the AS required version of the same artifact. And then letting the build tool decide
which one is best out of these 2 versions could lead to issues.
| Infact, in this scenario, *both* the versions should be brought in, for both the AS
and the client application to work as expected (see #2 below).
Agreed. In the case of "depchain", I the idea isn't that the build tool is
deciding upon the dependencies, only that it's configured to pull in the same ones
that AS defines. You should get the dependency set of AS in the end. The other side of
the coin there is that if you override the version of some artifact which is defined by
AS, you open yourself to problems.
"jaikiran" wrote : 2) Theoretically, when the AS is being created/booted it
should use its own different classloader than the classloader of the application which is
triggering the boot. This way the client application can have it's own different
versions of the same artifacts which the AS requires. Probably, the Embedded server
implementation should internally create a classloader out of the right set of jars
(/locations) for the AS and then use that classloader for AS boot/deploy and other
operations. How to get hold of the right set of jars is a different step (step#3 below).
Yep; I just hadn't provided that until tonight. :) Your post here lead me to
reconsider the ship criteria for 1.0.0-alpha-1, so take a look at:
http://anonsvn.jboss.org/repos/jbossas/projects/embedded/trunk/testsuite-...
...to ensure this works similarly to how you'd expect as well.
"jaikiran" wrote : 3) Maybe if the Embedded server API knows of JBOSS_HOME
locations, then probably it can create the classpath for the AS based on the known library
locations of the AS (JBOSS_HOME/lib, JBOSS_HOME/common/lib etc...)? But this is going to
tie the Embedded server implementation to a specific version of AS, since if tomorrow the
AS decides to have it's libraries in a different location then Embedded server
implementation will be affected too. Actually, it needs a bit more thinking, to get a
solution.
I think this is the same/similar to your question and my proposed solution above, no?
Input welcomed, we release soon.
S,
ALR
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4268010#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...