[Geoserver-devel] Some concerns about AspectJ vrt weaving

Hi,
I've been looking a bit more into AspectJ and in the
way aspects can be woven into the existing code.

There are two ways:
- load time weaving, where a Java Agent loaded into
   the JVM at startup time applies the aspect during
   classloading
- compile time weaving, where classes are modified
   in a post-compilation step

Gabriel suggested to use load time weaving. I'm however
quite worried about the use of the agent.
Using an agent means passing the entire JVM a parameter
like:

–javaagent:<path-to>/aspectjweaver-<version>.jar

that will will perform the classes transformations.
What worries me is that the agent loading is global,
affects not only GeoServer but all of the other applications
deployed alongside GeoServer. The main issues are:
- cautious admin will may refuse to change the JVM
   configuration and attach something that might actively
   perform changes on loaded classes. However, if they
   don't to it monitoring won't be enabled
- even if rarely used in practice, other applications
   might be using AspectJ as well, and a different version
   from us (older, newer)

Compile time weaving on the other side works at
build time and the webapp admin won't even know AspectJ.
The downside is that we have to apply aspects contained
into a plugin into the "main" jar. We cannot do so by
default.
However, it seems it's possible to generated a weaved
jar starting from a plain one using a maven plugin:
http://mojo.codehaus.org/aspectj-maven-plugin/weaveJars.html

If this works we could instruct the adminstrator to remove
the normal GeoServer main jar and install the woven
one in its place when adding the monitoring plugin,
and on uninstall, swap back the normal one (but never have
both in the classpath).

Development wise things might get a little hairy though,
as main is a basic dependency for... everything.
I guess development wise we could just run with load
time weaving instead?

Cheers
Andrea

I think this begs the question is the risk worth the reward. If there is anything I have learned from seeing to new developers trying to develop with GeoServer is is that the learning curve in GeoServer is high enough as it is with spring, maven, etc...

I fear that introducing yet another technology (and one that is here sounding a bit invasive) will make that learning curve even higher.

There is also the issue of different environments. Different JVM's and different servlet containers. Are we really set up with enough test coverage in different environments to be confident that the necessary changes to support aspectj will not introduce any issues on those platforms. I fear sadly that we are not.

I think this reinforces the argument to use spring aop. For sure it is not as flexible but seems much safer in the long run imo as it is already been thoroughly tested in those environments.

Anyways, I leave it up to the PSC to make the decision but I fear that providing more power and flexibility now will lead to headaches down the road trying to help users with deployment issues.

2c.

-Justin

On 1/25/10 11:17 AM, Andrea Aime wrote:

Hi,
I've been looking a bit more into AspectJ and in the
way aspects can be woven into the existing code.

There are two ways:
- load time weaving, where a Java Agent loaded into
    the JVM at startup time applies the aspect during
    classloading
- compile time weaving, where classes are modified
    in a post-compilation step

Gabriel suggested to use load time weaving. I'm however
quite worried about the use of the agent.
Using an agent means passing the entire JVM a parameter
like:

–javaagent:<path-to>/aspectjweaver-<version>.jar

that will will perform the classes transformations.
What worries me is that the agent loading is global,
affects not only GeoServer but all of the other applications
deployed alongside GeoServer. The main issues are:
- cautious admin will may refuse to change the JVM
    configuration and attach something that might actively
    perform changes on loaded classes. However, if they
    don't to it monitoring won't be enabled
- even if rarely used in practice, other applications
    might be using AspectJ as well, and a different version
    from us (older, newer)

Compile time weaving on the other side works at
build time and the webapp admin won't even know AspectJ.
The downside is that we have to apply aspects contained
into a plugin into the "main" jar. We cannot do so by
default.
However, it seems it's possible to generated a weaved
jar starting from a plain one using a maven plugin:
http://mojo.codehaus.org/aspectj-maven-plugin/weaveJars.html

If this works we could instruct the adminstrator to remove
the normal GeoServer main jar and install the woven
one in its place when adding the monitoring plugin,
and on uninstall, swap back the normal one (but never have
both in the classpath).

Development wise things might get a little hairy though,
as main is a basic dependency for... everything.
I guess development wise we could just run with load
time weaving instead?

Cheers
Andrea

------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
Geoserver-devel mailing list
Geoserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

--
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

Justin Deoliveira ha scritto:

I fear that introducing yet another technology (and one that is here sounding a bit invasive) will make that learning curve even higher.

Citing straight from the "AspectJ in Action" book that I'm reading:

-----------------------------------------------------------------------

Some of the costs associated with AOP are the usual suspects associated with any new technology:
- Making an investment in learning AOP
- Hiring skilled programmers

...

AOP abstracts away program flow even further. You may not know (except through good tooling support) that a crosscutting action will take place in a certain part of the code. Many programmers new to AOP get stuck until they realize that this separation of concerns is the whole point. If you insist on understanding the exact program flow, it’s a sign that you need to reflect a little longer on the core ideas of AOP. But just as OOP requires a few years of practice before you understand the underlying core ideas, most developers get AOP eventually.

-----------------------------------------------------------------------

I too fear we'd be cornering us with a tool that few people
understand and create others "one man" modules

Cheers
Andrea

Justin Deoliveira ha scritto:

I think this reinforces the argument to use spring aop. For sure it is not as flexible but seems much safer in the long run imo as it is already been thoroughly tested in those environments.

Btw, thinking about using just spring aop, and looking at Gabriel
prototype using AspectJ, I see things that seem to translate naturally
to Spring AOP, like the advices around the Dispatcher, since the
latter is declared in the Spring Context and we are just advising
methods with before/after/around advices, but there are things
that we cannot do too.

For example, in monitoring it's insteresting to know which layers
each request accessed, and eventually what area of the layer was
accessed too. To support the former Gabriel added an aspect
around FeatureTypeInfo and CoverageInfo in the places where the
actual feature sources/coverages are gathered.
With AspectJ that requires only a handful of lines of code.
If we wanted to do the same with Spring AOP I guess we'd have to:
- declare an advice around the catalog methods
- wrap the returned FeatureTypeInfo and CoverageInfo with proxies
- have those proxies notify the data gathering module that
   the actual data has been accessed

And if we wanted to know the actual area accessed I guess
we'd have to also proxy the returned feature source and so on.

Or, alternatively, work against the request objects, which is
probably easier, but has the drawback that you can monitor
only what you already know about: e.g., you can add support
for WMS and WFS, tomorrow comes WPS and whoops, you do not
have a way to monitor those (which also means, the monitoring
code needs to have dependencies towards all services to
parse their requests).

Suggestions on how to make this better?

Cheers
Andrea

Andrea Aime ha scritto:

Justin Deoliveira ha scritto:
For example, in monitoring it's inseresting to know which layers
each request accessed, and eventually what area of the layer was
accessed too. To support the former Gabriel added an aspect
around FeatureTypeInfo and CoverageInfo in the places where the
actual feature sources/coverages are gathered.
With AspectJ that requires only a handful of lines of code.
If we wanted to do the same with Spring AOP I guess we'd have to:
- declare an advice around the catalog methods
- wrap the returned FeatureTypeInfo and CoverageInfo with proxies
- have those proxies notify the data gathering module that
   the actual data has been accessed

And if we wanted to know the actual area accessed I guess
we'd have to also proxy the returned feature source and so on.

Which is something we can do to some extend, though it might become
messy quickly. To do run time weaving you need a factory that wraps
the targets into proxies applying the desired aspects.
The Spring application context is one of such factories.

The catalog subsystem can be seen as another, in the end the catalog
is the one returning the FeatureTypeInfo, and it's already applying
home made aspects in terms of the modification proxies.
I guess we could make that pluggable, make it look for specific
aspects in the spring context that need to be applied before returning
FeatureTypeInfo and CoverageInfo, and use Spring ability to apply
those aspects programmatically:
http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html#aop-prog

As said, this approach can quickly get hairy if you want to play
that dance at multiple levels (FeatureTypeInfo can apply proxies
to FeatureSource, which in turn may have to apply proxies to FeatureCollection and so on, depending on how deep the actual
aspects need to be applied)

Cheers
Andrea