Proxy a agenty

Ciele

  1. Vyskúšať vytváranie dynamického proxy.
  2. Vyskúšať vytváranie proxy pomocou knižnice Javassist.
  3. Vyskúšať modifikovanie tried pomocou Java agentov.

Postup

Krok 1: Dynamické proxy

Úloha 1.1

Stiahnite si kostru projektu.

Projekt obsahuje 3 podprojekty:

  • metrics — kostra knižnice pre zaznamenávanie počtu volaní a času vykonávania metód,
  • agent — kostra implementácie Java Agenta pre automatické modifikovanie tried,
  • example — príklad použitia knižnice.

Implementácia knižnice obsahuje triedu MetricsCollector, ktorá slúži na zber údajov o volaniach metód. Napríklad, metóda report(String methodName, long duration) pridáva záznam o volaní metódy a metóda printMetrics() vypisuje štatistiky volaní.

Úloha 1.2

Implementujte vytváranie dynamických proxy pre zaznamenávanie metrík o volaní metód.

Potrebujete implementovať metódy v triede MetricsProxy metódy:

  • wrapInProxy pre vytvorenie dynamického proxy,
  • MetricsIH.invoke pre meranie času vykonávanie metódy.

Na meranie času vykonávanie metódy potrebujete zaznamenať čas pred jej volaním:

long traceTimeStart = System.nanoTime();

Po vykonaní metódy zaznamenajte informácie a celkový čas vykonávania:

MetricsCollector.report(
    className + "." + method.getName(),
    System.nanoTime() - traceTimeStart);

Pre vyskúšanie implementácie doplňte v metóde Main.main príkladu vytvorenie proxy a volanie metódy na ňom:

Hello helloProxy = (Hello) MetricsProxy.wrapInProxy(hello);
helloProxy.sayHello();

Krok 2: Proxy pomocou Javassist

Okrem zabudovaného mechanizmu dynamických proxy, podobný efekt môžeme dosiahnuť aj pomocou externých knižníc, napríklad Javassist Výhodou je to, že pomocou Javassist môžeme vytvoriť proxy, ktoré dedí od zadanej triedy a nielen implementuje rozhrania.

Úloha 2.1

Implementujte novú verziu proxy pomocou knižnice Javassist.

Na vytvorenie proxy použite triedu ProxyFactory. Na spracovanie volaní metód musíte vytvoriť objekt implementujúci rozhranie MethodHandler.

Na overenie fungovania tohto riešenia skúste zabaliť do proxy objekt greater triedy ListGreater, ktorá neimplementuje žiadne rozhranie.

Krok 3: Java agenty

Alternatívou k vytváraniu proxy počas behu aplikácie je modifikácia bajtkódu priamo pri jej spúšťaní. Na to môžeme využiť mechanizmus Java Agentov.

Úloha 3.1

Skúste pripojiť pripraveného Java agenta pri spúšťaní aplikácie.

Pripojenie agenta sa zapína prepínačom -javaagent, napríklad

-javaagent:agent/target/agent-1.0-SNAPSHOT.jar

Poznámka

Pred samotným spustením potrebujete vytvoriť súbory JAR. Použite pritom príkaz mvn package. V IntelliJ IDEA môžete v paneli Maven zvoliť LifecyclePackage.

Poznámka

V IntelliJ IDEA môžete tento prepínač nastaviť v nastavenia spúšťania (Run Configuration):

Vyber možnosti „Add VM options“ v menu „Modify options“
Obr. 1: Vyber možnosti „Add VM options“ v menu „Modify options“

Nastavenie agenta
Obr. 2: Nastavenie agenta

Po spustení aplikácie by ste mali vidieť výpis zo spusteného agenta.

Úloha 3.2

Vytvorte Java agenta, ktorý bude modifikovať kód načítavaných tried tak, aby zaznamenávali metriky o vykonávaní metód. Modifikovanie sa má týkať všetkých metód s anotáciou CollectMetrics.

Použite knižnicu Javaasist na to, aby ste doplnili meranie času a zaznamenanie volania priamo do metód. Môžete využiť napríklad tieto metódy:

Zdroje

  1. Ivan Yurchenko. Java agents, Javassist and Byte Buddy
  2. Package java.lang.instrument