Hi Andy!

Usually when I try to help people who do not clearly describe their problem, I 
tell them to share more information or just ask smarter. Thank you for not 
lecturing me on that (even though probably you should have) but trying instead 
to make educated guesses about my assumed problems and goals. Maybe I can do 
better this time. :-)

>>> If you add "-Xbootclasspath/p:<path_to_aspects.jar>" JVM option, then you 
>>> can instrument inside the JDKs and also instrument already loaded classes.
> 
> Not sure that statement is quite correct.  You cannot just do that to
> instrument already loaded classes

Actually I do not use the command line option, I just quoted the full sentence. 
I am only interested in instrumenting already loaded classes. So here is my 
situation:

I have written a little playground application:

Eclipse project "main" (AspectJ):
  - class Application
  - interface Plugin
 - aspect ApplicationAccessorAspect
 - aspect PluginMonitorAspect

Eclipse project "plugin 1"  (Java):
  - class MyPlugin1 implements Plugin
Eclipse project "plugin 2"  (Java):
  - class MyPlugin2 implements Plugin
Eclipse project "plugin 2b"  (Java):
  - class MyPlugin2 implements Plugin

ApplicationAccessorAspect monitors calls (not executions!) to getters/setters 
in Application.

PluginMonitorAspect monitors executions (yes, this time) of two Plugin+ methods.

I successfully tested the whole setup with a WeavingURLClassLoader which weaves 
all plugins upon class-loading. Log output shows that all my intercepted calls 
and executions in both the main application and the plugins are triggered 
perfectly. I even verified that MyPlugin2 (same class & package name in two 
projects "2" and "2b", just slightly different log output so I can 
differentiate them) are loaded separately because I am creating a new 
WeavingURLClassLoader instance each time I load a plugin. Thus, the plugins run 
in isolation from one another. I have basically created mini containers.

Wonderful! Piece of cake! :-) But...

But now I was getting ambitious with my next project:

Eclipse project "plugin 3"  (AspectJ):
  - class HackyPlugin implements Plugin
  - class AspectJLTW (basically the class I quoted in my previous mail with 
slight changes)
  - aspect ApplicationHackerAspect

Okay, you see where I am going. I am trying to write a plugin which manipulates 
(advises, in AOP terms) its container's classes. For that purpose I need to be 
able to redefine an already loaded class. Because a plugin cannot just start a 
Java agent, I tried to do that manually utilising my version of AspectJLTW. 
Actually I want to redefine class Application, but because the loaded plugin is 
being advised by both PluginMonitorAspect and ApplicationAccessorAspect, plus 
the Application itself is also being advised by ApplicationAccessorAspect, I 
thought that for the first try I should rather advise another sibling class of 
the main project. So I added class Foo to the main project. It just has one 
static method returning a String, and I want to intercept its execution and 
manipulate the return value. (Are you still following?)

What I managed to do so far is load Foo.class from disk into a byte[] and 
manually weave it with ApplicationHackerAspect. The advice is triggered, so far 
so good. I can use before or after, but when I use around I can only do that 
when I skip proceed(). As soon as I call proceed() I am running into

java.lang.reflect.InvocationTargetException
(...)
Caused by: java.lang.NoSuchMethodError: 
de.scrum_master.aop.ltw_dynamic.Foo.getText_aroundBody0()Ljava/lang/String;
        at de.scrum_master.aop.ltw_dynamic.Foo$AjcClosure1.run(Foo.java:1)
        at 
com.vendor3.ApplicationHackerAspect.ajc$around$com_vendor3_ApplicationHackerAspect$1$30d0d5e4proceed(ApplicationHackerAspect.aj:8)
        at 
com.vendor3.ApplicationHackerAspect.ajc$around$com_vendor3_ApplicationHackerAspect$1$30d0d5e4(ApplicationHackerAspect.aj:9)
        at de.scrum_master.aop.ltw_dynamic.Foo.getText(Foo.java:4)

Somehow there seems to be a class-loading issue. Probably this is because I 
don't know sh** about class-loading and LTW, weaving adapters and the JDK's 
instrumentation interface. Furthermore, I have no idea how to manually 
redefine/replace the original class Foo because mi woven version exists in a 
separate classloader, i.e. also somehow in isolation.

Maybe I should have zipped up my Eclipse projects and attached them here, but I 
thought I should give it a try and explain in prose what I have accomplished 
and what remains to be achieved. My whole purpose is not to hack a server or 
anything, but to see how far I can push the limits of LTW and - foremost - to 
learn.

I would be glad to get any new hints about what my class-loading issue with 
proceed() could be (and how to solve it) and what I need to do to really 
replace my wonderfully woven Foo class (later maybe even the Application class) 
in the main application context instead of creating a clone. In Star Trek TNG 
speak: I want to improve Data's programming, not replace him by his evil twin 
Lore. ;-)

Cheers
--
Alexander Kriegisch
_______________________________________________
aspectj-users mailing list
aspectj-users@eclipse.org
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to