tifyty

pure Java, what else ?

Logger, logger.. te miért jársz ide?

Mindegy milyen loggert használunk minden egyes osztálynál a logger inicializálása fájdalom a szamárban (gy.k: pain in the donkey). Mert lehet a logger példányváltozó, és tudom, tudom, hogy premature optimization meg társai, de akkor is pazarékoskodunk az erőforrásokkal. Persze akkor lehet IOC konténerből injektálni. De azért csak lehetne az a nyomorult static változó, és mindegyik loggoló frémvörk esetében a logger neve az osztály neve. Ami már csak ezért is bosszantó, mert kénytelen vagyok leírni még egyszer az osztály nevét, egy sorral az osztály neve alatt.

public class PurchaseOrder {
	private static Logger log = Logger.getLogger(PurchaseOrder.class
			.getCanonicalName());

Akkor most programozunk, vagy hímzünk? Kódot írunk, vagy sormintát? (Mondjuk találkoztam már olyan programozóval, akinek a lelkétől nem állt távol a sorminta.)

Persze, persze tudom: ez legyen a legnagyobb problémám és ez legyen az ami miatt inszomniásan forgolódom éjszaka az ágyamban. First world problem.

Eleddig nem is vettem komolyan ezt a fajta nyűglődést, mert azért lássuk be: ez csak nyűglődés. Írtam egyszer egy annotációs interfészt is, amelyik alapján egy osztály szépen betölti a statikus mezőbe refleksőnnel a loggert, de ez inkább csak ujjgyakorlat vala. Komoly projektben nem használtam, mert nem lövünk ágyúval verébre, műveltebben szólva aquila non captat muscas. (Ennek a latin szólásnak a népszerű félrefordításait most kihagyom, túl olcsó poén lenne.)

aztán jött a Java 7 és a BA…

…és jött vele az invokedynamic. Miért érdekes ez? Hát a loggoláshoz ennek magának nincs sok köze, ilyen kódot nem is generál a javac, ám ami ezzel együtt jött járulékos veszteségként a JDK-ban, az többek között a MethodHandles osztály. Ezzel egy MethodHandles.lookup().lookupClass() hívással hozzájutunk az éppen futó osztály objektumhoz statikus környezetben is. Itt a mintakód:

package dustin.examples.methodhandles;

import java.lang.invoke.MethodHandles;
import java.util.logging.Logger;

/**
 * Demonstrating use of MethodHandles with java.util.logging.
 * 
 * @author Dustin
 */
public class MethodHandlesLoggerJavaUtilLogging {
	/** Use Java 7 MethodHandles to get my class name for logger. */
	private static final Logger LOGGER = Logger.getLogger(MethodHandles
			.lookup().lookupClass().getCanonicalName());

	public static void main(final String[] arguments) {
		final String msg = "Hello World: Using MethodHandles for Class to associate with java.util.logging logger.";
		LOGGER.info(msg);
	}
}

Akit részletesebben érdekel, az megtalálja az eredeti cikket a JavaWorld oldalain.

Csak nehogy úgy járjatok, hogy elkezded olvasni és azt veszed észre, hogy már többet tudsz az inkovedynamic-ról, mint amennyit valaha is tudni akartál.

Aki először beírja kommentbe, hogy mi az a BA, az megkapja tőlem a hét geekja megtisztelő címet.

14 responses to “Logger, logger.. te miért jársz ide?

  1. Kofa január 15, 2013 2:54 du.

    “Mert lehet a logger példányváltozó, és tudom, tudom, hogy premature optimization meg társai, de akkor is pazarékoskodunk az erőforrásokkal.”
    Ezt nem értem. Hol pazarolsz? A plusz 1 db. referenciával/objektumpéldány? Mert a logger ugyaz lesz.
    Egyébként abstract osztályban szoktam példányváltozó loggert csinálni, Logger.getLogger(this.getClass()) formában, így a logba már típushelyesen kerül az üzenet (látom, melyik leszármazott osztály küldi).

    Általában a következő Eclipse template-et [Window->Preferences->Java->Editor->Templates, vagy Ctrl+3, templates] használom:
    private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(${enclosing_type}.class);
    (OK, ez kódgenerálás, és nem copy-paste-álló)

    • v január 15, 2013 3:54 du.

      “A plusz 1 db. referenciával/objektumpéldány?” igen. De nem a memória az ami az érdekes, hanem a logger megszerzése. Az általában legalább egy valamilyen Map lookup. És ha nem static, akkor nem csak osztálybetöltéskor, hanem minden egyes példány létrehozásakor.

      Az abstract osztályoknál a this.getClass() működik, de tényleg azt akarod? Amikor kiíratsz valamit, akkor nem az érdekel, hogy a forráskód szerint melyik osztály írta ki? Mert akkor pont nem azt fogod látni. Ha meg üzemeltető vagy, akkor majdnem mindegy, hogy melyik logger, maximum log level konfigurálási kérdés.

      Persze apróság az egész, inkább csak érdekesség.

  2. Pitta január 15, 2013 4:46 du.

    AspectJ? Lehet vele static tagot generálni és a logger megkaphatja a típusnevet. Aztán meg az egyszeri programozó néz, hogy honnan jön a LOG mező. Vagy miért nem jön.

  3. Pitta január 15, 2013 4:48 du.

    BA:
    – British Airways
    – Business Analyst
    – Bachelor of Arts

    • v január 15, 2013 4:50 du.

      Ha esetleg elmagyaráznád, hogy ezek közül melyiknek mi köze van a cikk témájához, akkor valamilyen “megtisztelő” címet neked is adhatok. 🙂

  4. Pozsi január 15, 2013 5:52 du.

    0xba az invokedynamic opcodeja java 7-ben, de a cimet nem en erdemlem hanem a google 🙂

  5. Pats január 15, 2013 6:25 du.

    You are in the future 🙂
    Péter az időgépben : JANUÁR 15, 2013 – 5:55 DU.
    and the time is now : 5:25

  6. István Benedek január 21, 2013 11:59 du.

    ejj… java 7,8,9… aztan ertelmes loggolas nyelvi szinten tamogatva meg sehol se.. de assert az van… ejj

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s

%d blogger ezt kedveli: