2010-06-01 13 views
7

Recentemente ho iniziato a utilizzare lo strumento di analisi statica di findbug in una build java che stavo facendo. Il primo rapporto è tornato con un sacco di avvisi ad alta priorità. Essendo il tipo ossessivo di persona, ero pronto ad andare a buttarli tutti fuori. Tuttavia, mi deve mancare qualcosa. Ricevo la maggior parte degli avvertimenti quando si confrontano le cose. Come il seguente codice:Findbugs e confronto

public void setSpacesPerLevel(int value) 
    { 
     if(value >= 0) 
     { 
     spacesPerLevel = value; 
     } 
     else 
     { 
     spacesPerLevel = 0; 
     } 
    } 

produce un avviso di priorità alta nell'istruzione if che legge.

File: Indenter.java, Linea: 60, Tipo: BIT_AND_ZZ, Priorità: alta, Categoria: CORRETTEZZA Verificare se ((...) & 0) == 0 in campione. Indenter.setSpacesPerLevel (int)

Sto confrontando un int con un int, sembra una cosa comune. Ottengo un bel po 'di questo tipo di errore con simili confronti semplici.

Ho un sacco di altri avvisi ad alta priorità su quelli che sembrano essere semplici blocchi di codice. Mi sto perdendo qualcosa qui? Mi rendo conto che l'analisi statica può produrre falsi positivi, ma gli errori che sto vedendo sembrano troppo banali per essere un falso positivo.

Questo mi fa grattarmi anche la testa.

for(int spaces = 0;spaces < spacesPerLevel;spaces++) 
    { 
     result = result.concat(" "); 
    } 

che dà il seguente findbugs avvertimento:

File: Indenter.java, Line: 160, Type: IL_INFINITE_LOOP, Priority: High, Category: CORRECTNESS 

There is an apparent infinite loop in sample.Indenter.indent() 

This loop doesn't seem to have a way to terminate (other than by perhaps throwing an exception). 

Tutte le idee?

Quindi in pratica ho una manciata di file e 50-60 avvisi ad alta priorità simili a quelli precedenti. Sto usando findbugs 1.3.9 e chiamandolo dalle findbugs task ant

UPDATE: Ho questa build in esecuzione da un server Hudson e aveva il codice in fase di strumentato da Clover per la copertura del codice. Quando l'ho spento, tutti i miei avvisi con priorità alta sono scomparsi. Questo ha senso ora. Grazie per il feedback.

+0

Questo potrebbe essere un ciclo infinito se si modifica spacesPerLevel all'interno del ciclo es. spacesPerLevel = spaces + 2; o diminuendo gli spazi. – Anton

+0

Appena aggiornata la domanda per contenere più frammenti di codice –

+0

Stai compilando le informazioni di debug? – Anton

risposta

7

AGGIORNAMENTO: Il build è stato eseguito da un server hudson e il codice è stato strumentato da Clover per la copertura del codice. Quando l'ho spento, tutti i miei avvisi con priorità alta sono scomparsi. Questo ha senso ora. Grazie per il feedback.

1

Stai eseguendo Findbug tramite il plugin Eclipse, formica o gui? è possibile che il codice non sia ricompilato da quando lo hai eseguito (prima di apportare modifiche)?

se setSpacesPerLevel non sia troppo lungo, inviare l'output di

javap -v TheClassThatContainssetSpacerPerLevel

Per quanto riguarda il secondo bug, che avrebbe dovuto mostrare l'intero ciclo prima si potrebbe dire se fosse un problema.

+0

lo sto eseguendo da formica. L'obiettivo esegue una pulizia prima di eseguire qualsiasi analisi di build o statica. Lavorando sull'output di javap ... –

3

Una nota a margine:

for(int spaces = 0;spaces < spacesPerLevel;spaces++) 
{ 
    result = result.concat(" "); 
} 

Se result è un java.lang.String, questo può essere inefficiente, come si fa la seguente procedura per ogni carattere di spazio:

  1. creare un nuovo char[] per tenere la risultato della concatenazione
  2. creare una nuova istanza java.lang.String racchiusa nell'array di caratteri

Se lo si fa ripetutamente, specialmente quando result è già lungo, ci vuole molto tempo.

Se le prestazioni (sia di tempo che di memoria) sono importanti per questo metodo, è necessario prendere in considerazione l'utilizzo di StringBuilder (non thread-safe) o StringBuffer (thread-safe).

+0

Grazie! Ho portato questo codice da .NET (sono un po 'arrugginito nel dipartimento java). C'era un costruttore nella classe .net String che stavamo usando che ti permetteva di ripetere un carattere X numero di volte. Questa è stata la mia soluzione rapida e sporca, ma ha sbagliato dall'inizio. Grazie! –