There is a fundamentally bad assumption going on with AOP usage of classloadingand scoping. The problem is exemplified by this code in ScopedClassLoaderDomain(but it is a more general issue that I will explain as I go on):

The above code is like using Class.forName() instead of the context classloader. It assumes co-location (either aspect and code or aspect and config or config and code) which just isn't true in all cases.

When I say co-location I'm really talking about what AOP calls Domains although the way this currently implemented, it is closely related to classloading.

In fact, the way AOP tries to guess what is going on and create domains itself based on "hardwired rules" is clearly wrong.

The only reason it works is because of the "big ball mud" classloading model currently used by JBoss or the standalone classpath specified on the command line.

It is also exemplified by the conflicting (overloaded) usage of Domains: 1) As a scoped configuration repository for the user 2) As a way to scope classloading where a class is deployed multiple times in different deployments 3) Like (1) but done by us, e.g. the ejb3 confurgation domain

Before I explain what I would like to see, let me explain some of the use cases which are either not supported or at least difficult to do.

1) I going to be loose with what I explain, and try to explain it from a user's pointof view. e.g. If talk about intercepting database calls on Oracle, the useris unlikely to know that Oracle is the implementing class and insteadspecify join points on the jdbc interfaces. In the following I'll probably say bothbut it is really the same thing, hopefully you can follow this loose speakwithout pulling me up on what is done technically.

2) Some of what I describe as not possible can be done, but it is eithernot easy or not obvious how to do it. e.g. In some scoping situationsyou can make it work by using the MC's aop-mc-int and use proxies to get"instance level adivce stacks" but I'm not assuming that is what will be or wewant to be used in all cases?

The requirement here is that all deployment situations that should workwill work as expected.

Typically there are three items in the mix(I'll explain the AOP terminology as well for those readers that are not familiar with it)

1) The class being "modified" (I'll call this the "advised class"), e.g. this wouldbe Oracle's Connection class2) The advice (or interceptor if you like) which is the what "modification" you wantto make to the class3) The configuration, i.e. what are the advices, to which classes do they apply and where in that class they are made (called joinpoints in AOP)

The use case comes when these are not all in the same deployment or you wantto do different things in different deployments.

e.g. Use Case 1: Different advices in different deploymentsSuppose I have Oracle's jdbc jar deployed such that everybody can see the classesand I want to advise those classes in different ways in different applications

Currently, the advices are linked to the class through what JBoss AOP callsthe advisor. That is every joinpoint has a list of advices (could be no list if thejoinpoint is not advised).

None of those lists can be changed at the deployment level.

There is a notion perJVM, perClass, perInstance, but this is more abouthow instances of the advice you get, not what the advice is or does.

e.g. Use Case 2: Different configuration in different deploymentsThis is similar to use case 1, but the advices are classes that are also globally available.But the configuration (the -aop.xml) is different in the different deployments.

e.g. Use Case 3: Different advised classes in different deploymentsSuppose I deploy different Oracle jars in different applicationsand then specify global/local advices and global/local configuration.This is the kind of thing that will work "out-of-the-box" becausethere are multiple versions of the classes to add advisors to.

e.g. Use Case X: Other variantsThere are other variants some of which may or may not make sense,but those that do are probably unlikely to work just by looking at the classloaderof the advised class or advice to determine what configuration to use.

We already have a concrete version of this in EJB3where the EJB3 containers have a specific domain for the aop config.But it is a hardwired implementation with no general support for this featureto be used by other subsystems

Use Case 1: Adding advices for the JCA stack

I already prototyped a version of the JCA stacks through AOP.e.g. You can define what behaviour to add in front of the jdbc apifor the jdbc outbound rarbut again this is a hardwired use of domains.

The key thing here is that we want the JCA advices (pooling, security, transactionenlistment) only for the outbound jdbc rar. We don't want these advicesto apply to none JCA usage of jdbc.

Use Case 2: Different JCA stacks at the deployment level

The JCA stacks could actually be deployment specific themselves.e.g. there is a local-jdbc.rar and an xa-jdbc.rarwhich have different requirements

Use Case 3: Differfent JCA stacks at the instance level

The JCA stacks could even change for a specific data-source deployment in a -ds.xmlThat is for this datasource only I want to add to or change the advice stack.

public interface DomainContextFactory
{
// Get the domain from the current context (e.g. a thread local)
Domain getDomain();
// Get the domain for a specific scope
// Not sure if you really need this but you have a getTopLevelClassLoader()
// in the old api - not sure what is for?
Domain getDomain(Scope scope);
}

You might have guessed from the signature that I'm suggesting using the MetaDataRepository as the implementation of this api inside JBoss.

The idea being that a Domain can be added to different scopes and populated by the AOPDeployer(s).

e.g. the default scope (what is currently now the AspectManager) would be something like (pseudo code - not the real api for simplicity)

The issue as it appears to me in the AOP config is that it is generally storingthings at the class(loader) level.

This is a reasonable strategy to avoid memory leaks. Once the class(loader)is GCed the WeakReference is removed.

But in general this leads to the wrong configuration or wrong advices gettingused. What is required is a different strategy where *logically* the advice stacks (andother info?) are at the scope/class level.

Of course, we should still need to optimize away duplicates where thereis no override at more finer grained scopes. If it just took the simplistic approachthen you have an advice stack per instance which wouldn't scale at all. :-)

I'm not sure what the best way to implement this is efficently.You obviously don't to be doing a scope access on every method/field callto see whether there is an override for that scope.And in fact, that might lead to wrong semantics where an object fromone application is passed to another application.It could suddenly start using the wrong advices.

That is why I emphasised "logically" above.

It seems to me that the best way to do this would be like MC instance levelaop.

That is if the config/advices/class are all in the same scope/domainthen we just need a normal Advisor.

If however we are going to override a class's configuration in a child scope/domain(maybe even the class is not advised in its own scope) then we use theproxy stuff like the MC work.

Finally, the other advantage of using Scopes when they are integrated into thedeployers is that there is a pretty trivial point during the undeploy whenyou know the information can be released and what information needs to bereleased.