Newsgroup: it.comp.java
Titolo: L'ideona del loggingDecorator

Oggi ho partorito l'ideona del loggingDecorator.
Anche se sono sicuro che è già venuta a mille altre persone ve la dico 
lo stesso.
Fate finta che vi serve aggiungere ad ogni metodo dei messaggi di debug 
del tipo "sono entrato nel metodo", "sto uscendo dal metodo" o simili.
Uno con poca fantasia farebbe così:
public void someMethod() {
   logger.debug("Begin of someMethod()");
   ... // corpo del metodo
   logger.debug("End of someMethod()");
}
Io pero' dovevo debbuggare le chiamate a una classe che aveva molti 
metodi e non volevo usare il copia incolla. Ho preferito scomodare il 
Design Pattern chiamato Decorator e la Java Reflection.
Ho usato:
   EntityManager em = ...
   em  = LoggingDecorators.loggingDecorator(em)
Avendo precedentemente definito:
public class LoggingDecorators {
   private static final Logger logger =
           Logger.getLogger(LoggingDecorators.class.getName());
   public static <T> T loggingDecorator(
               final T target,
               final Class<T> targetClass) {
       return (T) Proxy.newProxyInstance(targetClass.getClassLoader(),
               new Class[] { targetClass}, new InvocationHandler() {
           public Object invoke(Object proxy, Method method, Object[] 
args) throws Throwable {
 
logger.info
("Begin of " + method);
               try {
                   return method.invoke(target, args);
               } catch(InvocationTargetException ex) {
                   throw ex.getCause();
               } finally {
 
logger.info
("End of " + method);
               }
           }
       });
   }
}
Commenti?
--
Andrea Francia
http://andreafrancia.blogspot.com/2008/07/lideona-del-loggingdecorator.html

 Commenti?
Ti direi di a dare una occhiata all'aspect proframming ed alla sua 
implementazione aspectj (plug-in di eclipse)... il tuo è un caso tipico 
di uso... esso usa però un preprocessore evitando l'uso della reflection.
-- 
Il mio nome è legione


Hai fatto 30, fai 31: indicami un riferimento con un esempio o postalo 
se ti va.
Personalmente preferisco l'uso della reflection a quello del preprocessore.
-- 
Andrea Francia
http://andreafrancia.blogspot.com/2008/06/relazioni-molti-molti-con-jpa.html

 LoggingDecorators.class.getName()
eh ma considerazioni sull'uso della reflection a parte, ti prendi sempre lo
stesso logger per classi diverse ?
io in genere evito messaggi di log tipo "entro nel metodo" "esco dal metodo" 
e preferisco fare uso del debug. cmq capisco che dipende sempre dal
contesto.
-- 
Davide Consonni

 contesto.
Il comportamento problematico si effettuava su un ambiente su cui non 
potevo fare il debug mentre non capitava nell'ambiente di sviluppo.
E poi non era comodo farlo con il debug.
Avevo capito che probabilmente c'era un deadlock e volevo capire quali 
erano i metodi che venivano bloccati. Alla fine l'ho scoperto. Mi è 
bastato andare a vedere quali metodi avevano il "Begin of method" e non 
il "End of method".


 Secondo me dovresti darci un'occhiata, anche se è difficile da digerire
E' un po' che cerco di farlo ma non ce l'ho ancora fatta.
Il fatto che si tratta di un linguaggio alla fine non è Java ma una sua 
modificazione non mi va troppo giù perché temo (magari in modo 
infondato) problemi di manutenibilità e di compatibilità.
Un conto è usare una libreria non supportata da Sun, un conto un intero 
linguaggio.
Poi per riuscire a capire gli esempi sembra che sia necessario sapere 
pure la teoria della programmazione orientata agli aspetti, e io mi 
chiedo sempre perché devo andare a studiare questa "yet another oriented 
programming" quando i libri piu' nuovi di ingegneria del software non la 
considerano ancora?
Esiste anche la programmazione orientata ai concetti e altre diavolerie 
non ancora affermate, una cosa che mi tiene lontano dalla programmazione 
orientata agli aspetti è la domanda "perché devo studiarmi proprio la 
AOP e non un'altra delle nuove diavolerie?"


 potevo fare il debug mentre non capitava nell'ambiente di sviluppo.
eh si era esattamente questo che intendevo.
ad esempio qui da noi facevamo cosi quando dovevamo fare dei deploy su
websphere portal e non ci davano la possibilità di fare debug.
io poi ho risolto spostando lo sviluppo su una mia istanza di jboss portal.
chi fa da se ... :D
-- 
Davide Consonni

 
anche io su questa cosa sono un po combattuto, nel senso che non mi
piace "applicare" del codice in una logica fuori da java al codice java,
anche se capisco che effettivamente l'aop è/può essere comoda.
quindi mi sa che per ora aspetterò ad usarla. magari aspettando qualche jsr
che faccia della cosa uno standard.
-- 
Davide Consonni

 Se hai realmente bisogno di tutto ciò, un pensierino fallo.
Sì, sì, il pensiero di studiare la cosa lo sto già facendo.
Penso che quando conoscerò meglio AspectJ e AOP mi sarà più facile 
decidere se usarli in un certo progetto o meno.
Certo che ci sono mille cose da studiare!

 
Secondo me vale la pena studiare quello che si usa ora, e ora si usa la AOP.
L'AOP è abbastanza recente, ma è stata integrata subito in tanti framework
(vedi sopra). A mio avviso se quelli che scrivono i framework (gente che sa
programmare e soprattutto progettare) usa l'AOP allora significa che è
buona. 
Luca

 ...
Grazie per tutte le tue altre opinioni.
-- 
Andrea Francia
http://www.andreafrancia.it/

 
Javassist, veramente molto valida, usata anche in jboss.
Luca

 Secondo me vale la pena studiare quello che si usa ora, e ora si usa la AOP.
Francamente non vedo tutta questa necessita' di studiare AOP, in
quanto lo ritengo compito degli sviluppatori di framework e non di
normali sviluppatori. Un po' come le annotations non sono solitamente
scritte da sviluppatori di normali applicazioni, ma da progettisti di
framework.
Ad esempio, usando Spring puoi gia' fare logging e sicurezza in
maniera trasparente.
Non vorrei mai vedere un programmatore che si mettesse a sviluppare
usando AOP invece di OOP: sarebbe follia pura e inutile perdita di
tempo.

 aspectwerkz
no, fermi tutti, voglio scendere :D
io una cosa cosi non la voglio proprio vedere 
    /**
     * @Before logSet || logGet
     */
    public void logEntry(final JoinPoint joinPoint) throws Throwable {
-- 
Davide Consonni

 nuova.
Allora magari parto da aspectwerkz ad imparare.



Tenendo conto che alcuni come me non hanno idea del significato di 
questa dichiarazione di metodo, cosa c'e' di brutto?
Da profano dell'AOP posso dire che avere l'annotation nel commento non 
mi piace.


 maniera trasparente.
Stai dicendo che avrei potuto risolvere con spring il problema che ho 
risolto con il decorator?
Sarebbe stato più semplice con spring?


Andrea Francia wrote:

č proprio questo che non mi piace aop o non aop, voglio dire un commento č
un commento e basta ..
-- 
Davide Consonni

 
Beh tu hai risolto brillantemente mi pare anche senza...ma in generale 
ecco un esempio di logging con AOP in Spring (trovato googlando):
http://www.devx.com/Java/Article/30799/0/page/2

 
http://www.devx.com/Java/Article/30799/0/page/2
Grazie per il link, cosě posso finalmente avvicinarmi a spring partendo 
da qualcosa di semplice.


 problemi di manutenibilità e di compatibilità.
.com/2008/06/relazioni-molti-molti-con-jpa.html
Condivido le tue perplessità, la technologia è nuova.. quanlche baco non 
manca ma è il nuovo parto del Xerox Palo Alto Research Center creatori del 
di Nonno Smaltalk e delle interfaccia ad oggetti. Senza le loro intuizioni 
java e la metafora del desktop non esisterebbero,
per i link 
http://www.eclipse.org/aspectj/
Il bello che non sostituisco java ma lo complementa.

>
In un gruppo puoi mettere l'aspectista... gli altri possono cotinuare a 
lavorare in java. Questo per la natura "ortogonale" della programmazione 
degli aspetti rispetto la logico di businnes.
Con AOP si esegue tipicamente:
- Sicurezza
- Caching
- Tracing
- Distribuzione
Tutti problemi che sono attinenti alla sfera del designer che dell'analista 
funzionale..
Colgo l'occasione per domandare se qualcuno l'ha usato in progetti RAD6 e 
webSphere...
Saluti 

 
Non necessariamente. I commenti, prima di Java 5, erano un ottimo posto 
dove inserire del meta-code. Ad esempio, i tag javadoc XDoclet per 
Hibernate, erano una cosa utilissima.
In ogni caso anche il compilatore Java ha sempre usato i commenti per 
"marcare" i metodi deprecated con tag javadoc @deprecated, a cui in Java 
5 si è affiancata l'annotation @Deprecated.
Per chi è costretto ancora ad usare Java pre-5, i tag javadoc sono una 
manna dal cielo. L'alternativa sarebbe mettere le informazioni 
aggiuntive della classe in file di configurazione staccati dal sorgente 
della classe (chi ha detto XML? :) brrr....), che finisce ben presto in 
qualcosa di totalmente immanutenibile.
-- 
Lucio Benfante
JUG Padova           
http://www.parancoe.org
 ...have a look at it!
www.jugpadova.it
 
http://www.jugevents.org

 
A dire il vero un commento (javadoc) è una forma particolare di annotazione.
Non vedo francamente dove sia il problema: sei libero di commentare il
codice (documentazione) e inserire informazioni per strumenti esterni senza
intaccare il codice.
Luca

 tempo.
Guarda, io uso AOP in diversi progetti e mi trovo molto bene, poi come ho
detto sopra, sta a te decidere dove e quando sia opportuno applicarla. 
Certo è che se per te AOP è follia pura e perdita di tempo allora fai bene a
rimanere confinato nell'OOP continuando a scrivere tonnellate di classi per
ottenere gli stessi risultati.
Luca

 detto sopra, sta a te decidere dove e quando sia opportuno applicarla.
Per curiosita', in che cosa l'hai usato?

 Per curiosita', in che cosa l'hai usato?
Ho fatto la scalata classica: sono partito dal logging e dal tracing. Poi
l'ho usato per scrivere un mini-framework per l'implementazione di regole
locali a codice installato da terze parti, ora lo applico per gestire la
sicurezza e l'ho anche usato in un progetto "ereditato" per muovere il
sistema di serializzazione da "semplice sql" a hibernate.
Luca

 locali a codice installato da terze parti,
Questo mi interessa. E' una specie di rule engine, magari dove le api
somogliano a qualcosa tipo
@ApplyRule("setStato")
void setStato(int stato) {
  this.stato = stato;
}
?

cicap wrote:

QUalcosa del genere, con le regole che in realtà diventano regola-azione.
@precondition(
    classname = "x"
    methodname = "y"
    continueIfFails = "false"
)
@postcondition(
  classname = "z"
  methodname = "k"
)
public void query()
Quindi praticamente prima di ogni chiamata a query viene eseguito x.y(), e
se fallisce si rinuncia a chiamare query, altrimenti si procede e dopo si
chiama z.k(). 
Luca


Con OOP potrebbe diventare
public void query() {
  new RuleTemplate() {
    public void pre() {new x().y();}
    public void post() {return new z().k();}
    public void body() {
      //body
    }
  };
}
Meno elegante certo.