Download - Statische Analyse von Java-Code in der Praxis

Transcript
Page 1: Statische Analyse von Java-Code in der Praxis

Statische Analyse von Java-Codein der Praxis

Vortragsreihe Tools in der Softwareentwicklung

Roland Ewald

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 1

Page 2: Statische Analyse von Java-Code in der Praxis

Hintergrund

• Modellierungs- und Simulationsframework JAMES II(http://jamesii.org)

• Konzipiert von Jan Himmelspach; entwickelt über neun Jahre mit> 40 Leuten

• Zwar nicht groß für Industrieverhältnisse, aber auch nicht mehr trivialklein:

• 396.326 LoC

• 782.583 Zeilen insgesamt, in

• 6.699 Quelldateien (Stand: 24. 5. 2012 / Revision 28784)

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 2

Page 3: Statische Analyse von Java-Code in der Praxis

Warum statische Codeanalyse?

SonarEingebundene WerkzeugeIntegration mit anderen Werkzeugen

Beispiele, Beispiele, Beispiele

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 3

Page 4: Statische Analyse von Java-Code in der Praxis

Warum statische Codeanalyse?

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 4

Page 5: Statische Analyse von Java-Code in der Praxis

The most important thing I have done as a programmerin recent years is to aggressively pursue static codeanalysis.

Even more valuable than the hundreds of serious bugs Ihave prevented with it is the change in mindset aboutthe way I view software reliability and code quality.

John Carmackhttp://www.altdevblogaday.com/2011/12/24/static-code-analysis

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 5

Page 6: Statische Analyse von Java-Code in der Praxis

http://en.wikipedia.org/wiki/John_D._Carmack

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 6

Page 7: Statische Analyse von Java-Code in der Praxis

Was ist statische Codeanalyse?

• Code wird analysiert, ohne ihn auszuführen

• Meist automatisiert, d.h. durch Software(ansonsten: Code Review, z.B. http://codereview.stackexchange.com)

• Automatische Analyse ist schwer bzw. unmöglich(Satz von Rice, Halteproblem)

⇒ Heuristiken, Auffinden von Anti-Patterns, Metriken

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 7

Page 8: Statische Analyse von Java-Code in der Praxis

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 8

Page 9: Statische Analyse von Java-Code in der Praxis

Code-Metriken?

• Größe: z.B. Zeilen pro Datei/Klasse/Methode

• Komplexität: z.B. Anzahl Parameter pro Methode

• Dokumentation: z.B. Anzahl an Kommentaren

• Homogenität: z.B. Bennenung von Variablen

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 9

Page 10: Statische Analyse von Java-Code in der Praxis

Technical Debt

Photo: Andres Rueda / flickr.com

E. Allman: Managing technical debt. Commun. ACM, vol. 55, no. 5, pp. 50-55, May 2012.

http://dx.doi.org/10.1145/2160718.2160733

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 10

Page 11: Statische Analyse von Java-Code in der Praxis

Problem: Geschwindigkeit der Analyse

• Viele Metriken sind wichtig

• Laufzeit: mehrere Stunden

• Lästig→ wird ignoriert

• Integration in den Arbeitsablauf

• Continuous Inspectionhttp://xkcd.com/303

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 11

Page 12: Statische Analyse von Java-Code in der Praxis

(Open Source, kommerzielle Zusatzkomponenten)

http://www.sonarsource.com

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 12

Page 13: Statische Analyse von Java-Code in der Praxis

Sonar integriert existierende Werkzeuge

• PMD, CPD, Findbugs, Checkstyle, Clover, etc. ...

• Web-Anwendung (’lokale’ Installation einfach möglich)

• Außerdem: Historie, zusätzliche Metriken, Code Reviews

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 13

Page 14: Statische Analyse von Java-Code in der Praxis

http://nemo.sonarsource.org

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 14

Page 15: Statische Analyse von Java-Code in der Praxis

Integration ins Build-System

• Maven-Support: mvn sonar:sonar

(Alternativ: Ant Task, „Java Runner“)

• Plug-in für Jenkins vorhanden

• E-Mail Benachrichtigungen bei ’Events’

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 15

Page 16: Statische Analyse von Java-Code in der Praxis

IDE Integration

• Plugins für Eclipse, IntelliJ IDEA, NetBeans (in der Entwicklung)

• Anzeige der Probleme im Editor, zusätzliche Filter

• Lokale Analyse möglich

• Code Reviews als Mylyn-Tasks einbindbar

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 16

Page 17: Statische Analyse von Java-Code in der Praxis

Beispiele1,2,3

1 — Beispiele sind von mir.

2 — Oder ausgedacht/adaptiert.

3 — Wenn ausgedacht: in der Form schon mal gefunden.

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 17

Page 18: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?

1 //...

2 public class PerfDBImplementation implements IPerformanceDatabase {

3

4 /**

5 * Performance database to be used

6 */

7 PerformanceDatabase perf_db = null;

8

9 public void init(DBConnectionData dbConn) throws Exception {

10 perf_db = new PerformanceDatabase(dbConn);

11 Object[] params = null;

12 perf_db.createBase(params);

13 }

14

15 //...

16 }

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 18

Page 19: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?1 //...

2 public class FilePerformanceExtractor extends

AbstractPerformanceExtractor {

3 /** The delimiter for creating the output file. */

4 private final char DELIMITER = '\t';

5 //...

6 private void writeToFile(StringBuilder stringBuilder, String

fileName) {

7 BufferedWriter writer = null;

8 try {

9 writer = new BufferedWriter(new FileWriter(fileName));

10 writer.append(stringBuilder);

11 } catch (Throwable t) {

12 t.printStackTrace();

13 }

14 }

15 //...

16 }

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 19

Page 20: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?1 protected BenchmarkModel getEntityByResultSet(ResultSet rs) throws

Exception {

2 return new BenchmarkModel(new URI(rs.getString(2)), rs.getString(3),

3 rs.getString(4), rs.getString(5));

4 }

5 //...

6 public PortfolioPerformanceData(Double[][] perfMatrix,

7 SelectionTree[] configs) {

8 performances = perfMatrix;

9 configurations = configs;

10 }

11 //...

12 public interface IBogusSimulatorProperties extends Serializable {

13 //...

14 final Integer DEFAULT = 1;

15 //...

16 public int getLoadPerSteps(Map<String, Serializable> modelContent);

17 }

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 20

Page 21: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?

1 class FooBar implements Serializable {

2 //...

3

4 public static final String DATABASE_PWD = "kommtIhrNieDrauf";

5

6 private FileReader fileReader;

7

8 private HashMap<String, Serializable> value = new HashMap<String,

Serializable>();

9

10 ReplicatedSimExecThread repThread = (ReplicatedSimExecThread) thread;

11

12 Vector<Integer> bestAlgorithms = new Vector<Integer>();

13

14 //...

15 }

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 21

Page 22: Statische Analyse von Java-Code in der Praxis

Was noch gefunden werden kann...

• Unsaubere Multi-Thread ProgrammierungInconsistent synchronization of x.y.z.foo; locked 83% of time

• Manchmal: EndlosschleifenAnsonsten mit //NOSONAR Entwarnung geben.

• DuplikationenAuch über mehrere Projekte.

• Klassen, die das Single-Responsibility-Prinzip verletzenMomentan: LCOM4.

• Zirkuläre Abhängigkeiten zwischen Paketen

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 22

Page 23: Statische Analyse von Java-Code in der Praxis

Was noch gefunden werden kann...

• Ungenutzte Variablen

• Zu wenig geschweifte Klammern

• Einrückungen mit <TAB> (→ Versionskontrolle!)

• equals() & hashCode()

• Redundante null/instanceof-checks, redundanter Kontrollfluss,Nullpointer-Dereferenzen

• == vs. equals()

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 23

Page 24: Statische Analyse von Java-Code in der Praxis

Zusammenfassung: Statische Codeanalyse ...

• hilft typische Bugs zu findenund zu vermeiden

• ist automatisierbar

• sollte in bestehendeArbeitsabläufe integriert werden

• erfasst Technical Debt

Photo: OnFoot4now (Didi) / flickr.com

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 24

Page 25: Statische Analyse von Java-Code in der Praxis

Studenten gesucht:JAMES II weiterentwickeln undErfahrung sammeln mit...

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 25

Page 26: Statische Analyse von Java-Code in der Praxis

Dieses Werk ist unter einer Creative Commons Lizenz vom Typ Namensnennung 3.0 Deutschland zugänglich. Um eine Kopie dieser Lizenz

einzusehen, konsultieren Sie http://creativecommons.org/licenses/by/3.0/de/ oder wenden Sie sich brieflich an

Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 26

Page 27: Statische Analyse von Java-Code in der Praxis

Noch mehr Beispiele

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 27

Page 28: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?

1 if ((elem.getLong(2) == id) && (elem.getDouble(3) == time))

2 //...

3 MyState pState = null;

4 try {

5 pState = (MyState) proc.getState();

6 } catch (Exception e) {

7 e.printStackTrace();

8 }

9 pState.setMediator(new Mediator());

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 28

Page 29: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?

1 public int compare(Map<String, Double> list1, Map<String, Double>

list2) {

2 for (int i = 0; i < list1.size(); i++) {

3 if (list1.get(i) < list2.get(i)) {

4 //...

5 }

6 }

7 }

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 29

Page 30: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?

1 Object input = port.read();

2 if (input instanceof Boolean) {

3 Boolean move = (Boolean) input;

4 if (phase == ACTIVE) {

5 if ((move != null) && move) {

6 //...

7 }

8 }

9 }

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 30

Page 31: Statische Analyse von Java-Code in der Praxis

Wo ist das Problem?

1 //...

2 ExampleComponent c = manager.getComponentForExample(o);

3 if (c == null) {

4 Connection con = manager.getComponentForConnection(o);

5 con.call();

6 if (con == null) {

7 //...

8 }

9 } else {

10 c.call();

11 }

31. 5. 2012 c© 2012 UNIVERSITÄT ROSTOCK | LEHRSTUHL FÜR MODELLIERUNG & SIMULATION (PROF. UHRMACHER) 31