Analisi del codice sorgente utilizzando le API Java 6

di Seema Richard, Deepa Sobhana

Hai mai pensato a come strumenti come Checkstyle o FindBugs eseguono un'analisi statica del codice, o come gli ambienti di sviluppo integrato (IDE) come NetBeans o Eclipse eseguono correzioni rapide del codice o trovano i riferimenti esatti di un campo dichiarato nel tuo codice? In molti casi, gli IDE hanno le proprie API per analizzare il codice sorgente e generare una struttura ad albero standard, chiamata Abstract Syntax Tree (AST) o "parse tree", che può essere utilizzata per un'analisi più approfondita degli elementi di origine. La buona notizia è che ora è possibile eseguire le suddette attività e molto altro con l'aiuto di tre nuove API introdotte in Java come parte della versione Java Standard Edition 6. Le API che potrebbero interessare gli sviluppatori di applicazioni Java che devono eseguire l'analisi del codice sorgente sono le API del compilatore Java (JSR 199),l'API Pluggable Annotation Processing (JSR 269) e l'API dell'albero del compilatore.

In questo articolo, esploriamo le funzionalità di ciascuna di queste API e procediamo allo sviluppo di una semplice applicazione demo che verifica alcune regole di codifica Java su una serie di file di codice sorgente forniti come input. Questa utility mostra anche i messaggi di violazione della codifica e la posizione del codice sorgente violato come output. Considera una semplice classe Java che sovrascrive il metodo equals () della classe Object. La regola di codifica da verificare è che ogni classe che implementa il metodo equals () dovrebbe sovrascrivere anche il metodo hashcode () con la firma appropriata. Puoi vedere che la classe TestClass di seguito non definisce il metodo hashcode (), anche se ha il metodo equals ().

public class TestClass implements Serializable { int num; @Override public boolean equals(Object obj)  } 

Andiamo avanti e analizziamo questa classe come parte del processo di compilazione con l'aiuto di queste tre API.

Invocare il compilatore dal codice: l'API del compilatore Java

Usiamo tutti lo javacstrumento della riga di comando per compilare i file di origine Java in file di classe. Allora perché abbiamo bisogno di un'API per compilare i file Java? Ebbene, la risposta è abbastanza semplice: come descrive il nome, questa nuova API standard ci permette di richiamare il compilatore dalle nostre applicazioni Java; vale a dire, è possibile interagire in modo programmatico con il compilatore e quindi rendere la compilazione parte dei servizi a livello di applicazione. Di seguito sono elencati alcuni usi tipici di questa API.

  • L'API del compilatore aiuta i server delle applicazioni a ridurre al minimo il tempo impiegato per distribuire le applicazioni, ad esempio, evitando il sovraccarico dell'utilizzo di un compilatore esterno per la compilazione delle origini servlet generate dalle pagine JSP.

  • Strumenti per sviluppatori come IDE e analizzatori di codice possono richiamare il compilatore dall'interno dell'editor o creare strumenti che riducono notevolmente il tempo di compilazione.

Le classi del compilatore Java sono contenute nel javax.toolspacchetto. La ToolProviderclasse di questo pacchetto fornisce un metodo chiamato getSystemJavaCompiler()che restituisce un'istanza di una classe che implementa l' JavaCompilerinterfaccia. Questa istanza del compilatore può essere utilizzata per creare un'attività di compilazione che eseguirà la compilazione effettiva. I file di origine Java da compilare verranno quindi passati all'attività di compilazione. Per questo, l'API del compilatore fornisce un'astrazione del file manager chiamata JavaFileManager, che consente di recuperare i file Java da varie origini, come il file system, i database, la memoria e così via. In questo esempio, utilizziamo StandardFileManagerun file manager basato su java.io.File. Il file manager standard può essere acquisito chiamando il getStandardFileManager()metodo diJavaCompileresempio. Di seguito è mostrato lo snippet di codice per i passaggi sopra indicati:

//Get an instance of java compiler JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //Get a new instance of the standard file manager implementation StandardJavaFileManager fileManager = compiler. getStandardFileManager(null, null, null); // Get the list of java file objects, in this case we have only // one file, TestClass.java Iterable compilationUnits1 = fileManager.getJavaFileObjectsFromFiles("TestClass.java"); 

Un ascoltatore diagnostico può essere facoltativamente passato al getStandardFileManager()metodo per produrre rapporti diagnostici di eventuali problemi non fatali. In questo frammento di codice, passiamo nullvalori, poiché non stiamo raccogliendo la diagnostica dallo strumento. Per i dettagli sugli altri parametri passati a questi metodi, fare riferimento all'API Java 6. Il getJavaFileObjectsfromFiles()metodo StandardJavaFileManagerrestituisce tutte le JavaFileObjectistanze che corrispondono ai file di origine Java forniti.

Leggi il resto di questo articolo

Questa storia, "Analisi del codice sorgente mediante API Java 6" è stata originariamente pubblicata da JavaWorld.