Сей опус появился в связи со статьей habrahabr.ru/blogs/java/74208
UPD. Гораздо более подходящий вариант решения и его обсуждение — habrahabr.ru/blogs/java/74208/#comment_2141270
Ниже приведена информация как оно задумано, но пока не работает (может быть и вообще не заработает :( ). Нам нужно сделать 3 вещи:
Во-первых, мы создаем интерфейс и хотим, чтобы класс
Во-вторых, нам необходимо где-то сохранять значение
В-третьих, нужно каким-то образом «взлететь со всей этой херней».
Первые 2 пункта решаются следующим образом:
Создаем класс
И говорим JBoss AOP, что мы хотим смешать наши интерфейс
И заключительная «нерабочая» часть (пункт 3).
Взлетаем мы с этим как обычно — при помощи javaagent-а:
Агент сам уже прочитает содержимое файла myapp.jar!/META-INF/jboss-aop.xml и выполнит необходимые манипуляции с байткодом.
А теперь самое печальное — судя по всему JBoss AOP не хочет работать с JRE классами, хотя с проектными классами всё работает отлично (ну или я «не умею его готовить»). Может кто-нибудь подскажет решение? У AspectJ по крайней мере в документации прямо написано, что системные классы они не поддерживают (все, у которых classLoader == null).
UPD. Гораздо более подходящий вариант решения и его обсуждение — habrahabr.ru/blogs/java/74208/#comment_2141270
Ниже приведена информация как оно задумано, но пока не работает (может быть и вообще не заработает :( ). Нам нужно сделать 3 вещи:
Во-первых, мы создаем интерфейс и хотим, чтобы класс
java.lang.Thread
его реализовывал:
public interface TreeInfo {
public Thread getParentThread();
}
Во-вторых, нам необходимо где-то сохранять значение
Thread.currentThread()
при вызове конструктора класса Thread.В-третьих, нужно каким-то образом «взлететь со всей этой херней».
Первые 2 пункта решаются следующим образом:
Создаем класс
public class ThreadTreeMixin {
Object target;
Thread parent;
public ThreadTreeMixin(Object target)
{
this.target = target;
this.parent = Thread.currentThread();
}
public Thread getParentThread() {
return parent;
}
}
//* поле Object target не обязательно - оставил его лишь для "примера".
И говорим JBoss AOP, что мы хотим смешать наши интерфейс
TreeInfo
и класс ThreadTreeMixin
с java.lang.Thread
. Для этого мы создаем файл META-INF/jboss-aop.xml в ресурсах программы со следующим содержимым:
<aop>
<introduction class="java.lang.Thread">
<mixin>
<interfaces>
threadtree.TreeInfo
</interfaces>
<class>threadtree.aspects.ThreadTreeMixin</class>
<construction>new threadtree.aspects.ThreadTreeMixin(this)</construction>
</mixin>
</introduction>
</aop>
И заключительная «нерабочая» часть (пункт 3).
Взлетаем мы с этим как обычно — при помощи javaagent-а:
java -javaagent:jboss-aop-single.jar -classpath myapp.jar:... myapp.Main
Агент сам уже прочитает содержимое файла myapp.jar!/META-INF/jboss-aop.xml и выполнит необходимые манипуляции с байткодом.
А теперь самое печальное — судя по всему JBoss AOP не хочет работать с JRE классами, хотя с проектными классами всё работает отлично (ну или я «не умею его готовить»). Может кто-нибудь подскажет решение? У AspectJ по крайней мере в документации прямо написано, что системные классы они не поддерживают (все, у которых classLoader == null).