<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Compilezeit-Prüfung von Spring-Konfigurationen</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Konrad Fögen</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>foegen@swc.rwth-aachen.de</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Universität Münster</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>ERCIS</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>RWTH Aachen</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>SWC group</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Herbert Kuchen</institution>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>Vincent von Hof</institution>
        </aff>
      </contrib-group>
      <fpage>96</fpage>
      <lpage>108</lpage>
      <abstract>
        <p>Dependency Injection Frameworks wie das Spring Framework verlassen sich auf dynamische Sprachfähigkeiten von Java. Sofern diese Fähigkeiten auf unvorhergesehene Art und Weise eingesetzt werden, können Fehler auftreten, die zur Übersetzungszeit nicht vom Java-Compiler erkannt werden. Diese Arbeit diskutiert die Anwendung von statischer Programmcode-Analyse als Mittel, besagte ÜbersetzungszeitPrüfungen wiederherzustellen. Zuerst werden mögliche Fehler in der Konfiguration von Spring identifiziert und klassifiziert. Attributierte Grammatiken werden benutzt, um auf formale Art und Weise Fehler festzustellen. Anschließend wird eine prototypische CompilerErweiterung basierend auf der Java Pluggable Annotation Processing API vorgestellt.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Zusammenfassung</title>
      <p>1Siehe z.B. http://lang-index.sourceforge.net
Copyright c 2016 for the individual papers by the papers’ authors. Copying permitted for private and academic purposes. This
volume is published and copyrighted by its editors.</p>
      <p>Spring Context</p>
      <p>Abhängig Unabhängig
Oberhalb des Gruppe I Gruppe II
Methoden-Levels (13 Fehler) (13 Fehler)
Unterhalb des Gruppe III Gruppe IV</p>
      <p>Methoden-Levels (8 Fehler) (4 Fehler)</p>
      <sec id="sec-1-1">
        <title>Tabelle 1: Klassifikation von Konfigurationsfehlern.</title>
        <p>
          Es existieren bereits einige Tools für Statische Codeanalyse von Java-Programmen wie z.B. FindBugs [
          <xref ref-type="bibr" rid="ref2">2</xref>
          ],
Checkstyle [
          <xref ref-type="bibr" rid="ref4">4</xref>
          ], PMD [
          <xref ref-type="bibr" rid="ref18">18</xref>
          ], SonarQube [
          <xref ref-type="bibr" rid="ref21">21</xref>
          ], Java Language Extender [
          <xref ref-type="bibr" rid="ref23">23</xref>
          ], ESC/Java2 [
          <xref ref-type="bibr" rid="ref5">5</xref>
          ], JastAddJ
[
          <xref ref-type="bibr" rid="ref7">7</xref>
          ], JavaCOP [
          <xref ref-type="bibr" rid="ref13">13</xref>
          ], JQual [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ] und das Checker framework [
          <xref ref-type="bibr" rid="ref16">16</xref>
          ]. Alle diese Tools sind als generelle
Inspektionswerkzeuge konzipiert. Nach unserem Wissen existiert kein Tool, welches speziell die statische Überprüfung
von Fehlern bei der Konfiguration von Spring ermöglicht.
        </p>
        <p>Diese Arbeit ist wie folgt strukturiert. In Abschnitt 2 werden mögliche Fehler bei der Spring-Konfiguration
aufgezeigt und klassifiziert. In Abschnitt 3 werden daraufhin attributierte Grammatiken vorgestellt, welche formal
die Erkennung der Spring-Konfigurationsfehler beschreiben. Ausgehend von diesen attributierten
Grammatiken wird in Abschnitt 4 ein Prototyp einer Compiler-Erweiterung basierend auf Java’s Pluggable Annotation
Processing API beschrieben. Die durch die Entwicklung des Prototypen gewonnenen Erkenntnisse werden in
Abschnitt 5 genutzt, um den Ansatz zu bewerten. In Abschnitt 6 wird ein Fazit gezogen und es werden zukünftige
Betätigungsfelder aufgezeigt.
2</p>
      </sec>
    </sec>
    <sec id="sec-2">
      <title>Spring Konfigurationsfehler</title>
      <p>Das Spring Framework ist ein Open Source Framework, welches das Dependency-Injection-Entwurfsmuster
implementiert. Im Kern stellt die Spring Context Komponente nachgefragte und abhängige Objekte bereit. Diese
Objekte, so genannte Spring Beans, können jegliche Art von einfachen Plain Old Java Objects (POJOs) sein [24,
p.4].</p>
      <p>
        Verschiedene Implementierungen für den Spring -Kontext existieren, welche sich primär in der Art ihrer
Konfiguration unterscheiden, basierend auf z.B. Java oder Extensible Markup Language (XML). Im Allgemeinen
bestehen Konfigurationen sowohl aus Merkmalen, die sich direkt auf den Spring-Kontext beziehen, als auch aus
Definitionen für die Spring Beans. Spring bietet dabei drei verschiedene Möglichkeiten, Spring Beans zu
definieren: Explizite Konfiguration via Java und XML und/oder implizite Konfigurationen via Java Annotationen.
Diese Arbeit konzentriert sich auf annotations-basierte Konfigurationen. Für weitere Informationen zu Spring
siehe [
        <xref ref-type="bibr" rid="ref24">24</xref>
        ], [
        <xref ref-type="bibr" rid="ref19">19</xref>
        ] oder [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ].
      </p>
      <p>
        Um mögliche Fehlertypen zu identifizieren, wurde zuerst ein Literaturreview der
SpringReferenzdokumentation [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ] durchgeführt, gefolgt von Experteninterviews mit Entwicklern eines
SoftwareUnternehmens. In dieser Arbeit werden Core Container, für DI, und Datenzugriffs- und Integrations-Module
betrachtet, da diese in jeder Spring-basierten Java-Anwendung zur Verfügung stehen.
      </p>
      <p>Schlussendlich ergaben sich 38 unterscheidbare Fehlertypen. Diese Fehlertypen sind in Tabelle 1 in vier
Gruppen klassifiziert. Die vier Gruppen ergeben sich aus zwei Dimensionen, welche je zwei Ausprägungen annehmen
können. Die Klassifizierung hängt dabei einerseits von den wichtigsten Features des Spring-Frameworks ab. Die
Verwendung bestimmter Features bestimmt die Zuordnung eines Fehlers zu einer bestimmten Dimension.
Eine Spring Context benannte Dimension bestimmt, ob die Analyse Informationen benötigt, die aus dem Spring
Context abgeleitet werden. Analysis Level ist die zweite Dimension und sie bestimmt, ob für eine Analyse
Informationen bezüglich des Kontrollflusses von Sprachkonstrukten unterhalb des Methoden-Levels benötigt werden,
z.B. Methodenaufrufe oder Variablen-Zuweisungen.</p>
      <p>Im Folgenden werden mögliche Fehler beschrieben, um die Fehlertypen zu veranschaulichen.</p>
      <sec id="sec-2-1">
        <title>Gruppe I</title>
        <p>In diese Gruppe lassen sich Fehler einordnen, die vom Spring -Kontext und mindestens einer weiteren
Komponente, welche eine Spring-spezifische Annotation benutzt, abhängen. Diese Fehler treten oberhalb des
MethodenLevels auf, z.B. bei Deklarationen von Klassen, Methoden oder Attributen. Für sich betrachtet sind dabei die
Spring Context Konfiguration und die weitere Komponente jeweils sogar korrekt, allerdings ist zumindest die
Interaktion der beiden Elemente fehlerbehaftet.</p>
        <p>Als Beispiel sei Spring’s Transaktions-Infrastruktur genannt. Sie kapselt spezifische Transaktions-Management
APIs und bietet ein deklaratives Modell zur Integration in Anwendungen [10, chap.12.3]. Sowohl ein Spring
Context, der einen Transaktions-Manager deklariert, als auch eine @EnableTransactionManagement Annotation
müssen vorhanden sein, um das Transaktions-Management benutzen zu können. Sobald dies geschehen ist, lassen
sich Methoden per @Transactional annotieren, um Transaktions-Management-Funktionalität für diese Methode
zu aktivieren. Die korrekte Verwendung ist in Listing 1 dargestellt.</p>
        <sec id="sec-2-1-1">
          <title>Listing 1: Darstellung von Spring’s Transaktionsmanagement.</title>
          <p>In dieser Situation kann dann ein Fehler auftreten, wenn das Transaktionsmanagement aktiviert ist, jedoch
nicht verwendet wird, da keinerlei Methoden mit @Transactional versehen sind, z.B. wenn in Listing 1 die Zeile
10 fehlen würde. Auch kann die umgekehrte Situation eintreten und zu einem Fehlerzustand führen, wenn per
@Transactional annotierte Methoden existieren und gleichzeitig das Transaktionsmanagement deaktiviert ist,
weil z.B. Zeile 2 vergessen wurde.</p>
        </sec>
      </sec>
      <sec id="sec-2-2">
        <title>Gruppe II</title>
        <p>Fehler in Gruppe II sind unabhängig vom Spring Context und treten oberhalb des Methoden-Levels auf. Sie
umfassen Sprachkonstrukte mit Annotation, die gleichzeitig weitere Attribute oder Annotationen aufweisen, die
inkompatibel mit der ersten Annotation sind.</p>
        <p>Zum Beispiel benutzt das Spring Framework die @Autowired Annotation, um Methoden oder Felder zu
markieren, die als Injection Point in Frage kommen [24, p.39]. Zum Teil können Abhängigkeiten auch mehrdeutig
sein, sodass der Spring Context mehrere Bean Definitionen vorfindet, die einem Injection Point genügen. In dem
Falle wird eine der passenden Beans ausgewählt [24, p.75]. Die @Qualifier Annotation kann im Zusammenspiel
mit @Autowired genutzt werden, um die Ergebnismenge einzuschränken. Allerdings resultiert es in einem Fehler,
@Qualifier ohne eine entsprechende @Autowired Annotation zu verwenden.</p>
        <p>Des Weiteren kann die @Qualifier Annotation auch indirekt genutzt werden. Es macht keinen Unterschied, ob
@Qualifier direkt oder aber eine Annotations-Klasse verwendet wird, welche wiederum mit @Qualifier versehen
ist. Sowohl ein entsprechender Fehler als auch die indirekte Nutzung von @Qualifier sind in Listing 2 dargestellt.
1 @ Q u a l i f i e r
2 @ i n t e r f a c e DinA4Format {. . . }
3
4 @Component
5 @DinA4Format
6 c l a s s DinA4DocFormatter implements DocFormatter {. . . }
7
8 @Component
9 c l a s s P r i n t S e r v i c e {
10 // @Autowired f e h l t
11 @DinA4Format
12 public P r i n t S e r v i c e ( DocFormatter f ) {. . . }
13 }</p>
      </sec>
      <sec id="sec-2-3">
        <title>Gruppe III</title>
        <p>Wie Fehler aus Gruppe I beruhen auch Fehler der Gruppe III auf speziellen Spring Context Konfigurationen.
Allerdings hängen sie zusätzlich von Sprachkonstrukten unterhalb des Methoden-Levels ab. Zum Beispiel wird der
Lebenszyklus einer Bean über eine Bean Definition geregelt. Er beginnt, nachdem der zugehörige Spring-Kontext
initialisiert wurde, und endet, wenn besagter Kontext abgeschaltet wird. Innerhalb dieses Zeitraumes wird der
Lebenszyklus einer Bean über einen Scope, d.h. einen Gültigkeitsbereich, definiert [24, p.81]. Standardmäßig, d.h.
ohne weitere Konfiguration, befindet sich eine Bean im Singleton Scope. In diesem Scope existiert eine einzige,
gemeinsam genutzte Instanz der Bean (pro Spring-Kontext) und diese existiert, bis der Spring-Kontext beendet
wird [10, chap. 5.5.1]. Im Gegensatz dazu werden Beans, die mit dem Prototype Scope definiert sind, bei jeder
Anfrage neu erstellt.</p>
        <p>Ein wichtiger Aspekt bezüglich des Prototype Scope ist, dass der Spring-Kontext den Lebenszyklus solcher
Beans nicht überwacht. Obwohl Prototype und Singleton Beans auf gleiche Art und Weise initialisiert werden,
ist ihre Zerstörung unterschiedlich. Da der Spring Context keine Referenzen auf Prototype Beans speichert, kann
er trivialerweise auch ihre Zerstörung nicht steuern.</p>
        <p>Eine Spring-Bean-Definition gilt als entweder explizit definiert, wenn eine Methode direkt per @Bean
Annotation versehen wird, oder sie ist impliziert definiert, wenn eine Klasse direkt per @Component annotiert wird. Des
Weiteren erlaubt es Spring sogenannte Lifecycle Callbacks zu definieren, wodurch Methodenaufrufe durch den
Spring-Kontext zu bestimmten Phasen des Lebenszyklus einer Bean ausgelöst werden [24, p.33]. Unter anderem
existieren hierzu Methoden-Annotationen für die Lebenszyklus-Events @PostConstruct und @PreDestroy, d.h.
Methoden, die vor der Erstellung respektive Zerstörung einer Bean ausgeführt werden sollen.</p>
        <p>Da der Spring-Kontext allerdings, wie beschrieben, nicht über die Zerstörung von Prototype Beans wacht,
müssen Annotationen, welche mit dem Lifecycle Event der Zerstörung in Verbindung stehen, für Prototype
Beans als fehlerhaft angesehen werden. Listing 3 illustriert diesen Fehler, da dort eine Komponente eine close
Methode besitzt, die zum Freisetzen von Ressourcen dient, allerdings auf Grund des gesetzten Prototype Scopes
niemals zur Ausführung kommen wird.
1 @ C o n f i g u r a t i o n
2 public c l a s s S p r i n g C o n f i g {
3 @Bean
4 @Scope ( " p r o t o t y p e " )
5 public P r i n t S e r v i c e p r i n t S e r v i c e ( ) {
6 return new P r i n t S e r v i c e ( ) ;
7 }
8 }
9
10 public c l a s s P r i n t S e r v i c e {
11 @PreDestroy
12 public void c l o s e ( ) { // n i c h t a u f g e r u f e n !
13 t h i s . usbConnection . c l o s e ( ) ;
14 }
15 }</p>
        <sec id="sec-2-3-1">
          <title>Listing 3: Lebenszyklus von Beans mit prototype scope.</title>
        </sec>
      </sec>
      <sec id="sec-2-4">
        <title>Gruppe IV</title>
        <p>Gruppe IV beinhaltet Fehler, die unterhalb des Methoden-Levels auftreten und nicht vom Spring Context
abhängen. Ein Beispiel lässt sich bei Spring’s JdbcTemplate Komponente finden, welche eine Abstraktionsebene
über Java’s JDBC API darstellt. In diesem Beispiel wird SQL genutzt, um mit einer Datenbank zu interagieren.
Der korrespondierende Code ist sprachlich gesehen von dem ihn umgebenden Java-Code getrennt. Der
JavaCompiler kann nicht überprüfen, inwiefern der verwendete SQL-Code den Sprachdefinitionen von SQL genügt.
Der klassische Anwendungsfall hierfür involviert einen Entwickler, der seine SQL-Statements händisch mit
einem Tool gegen eine Datenbank testet, um den SQL-Code schlussendlich in Java als String zu hinterlegen. Eine
einfache Restriktion in diesem Kontext ist die Notwendigkeit, das SQL-Statement im Tool mit einem Semikolon
zu beenden. Ein Semikolon am Ende eines SQL-Strings hat in Java allerdings einen Laufzeitfehler zur Folge.</p>
        <p>
          Diese Art von Problemen lässt sich erkennen, indem Pluggable Type Systems ähnlich dem Checker-Framework
für reguläre Ausdrücke verwendet werden [
          <xref ref-type="bibr" rid="ref22">22</xref>
          ]. Die Diskussion dieses Fehlertyps ist nicht Bestandteil dieser
Arbeit.
3
        </p>
        <p>
          Fehlererkennung mit Hilfe von attributierten Grammatiken
Knuth führte 1968 mit Attributierten Grammatiken eine formale Herangehensweise zur Beschreibung und
Handhabung von semantischen Aspekten von Programmiersprachen ein [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ]. Attributierte Grammatiken sind
kontextfreie Grammatiken, die mit Attributen und semantischen Regel erweitert werden [20, pp.66-67]. Jedes
Nichtterminal einer kontextfreien Grammatik kann mehrere Attribute besitzen. Jedes Attribut kann entweder synthetisiert
(synthesized) oder vererbt (inherited) sein und besitzt einen Wert, der durch eine semantische Regel definiert
wird, die einer Regel einer kontextfreien Grammatik zugeordnet wird.
        </p>
        <p>Sei A ::= B1 : : : Bn (für n 2 IN) eine kontextfreie Regel mit den Nichtterminalen A; B1; : : : ; Bn, welche jeweils
ein synthetisiertes Attribut s und ein vererbtes Attribut i besitzen, so gilt, dass die korrespondieren semantischen
Regeln die Werte der Attribute A:s; B1:i; : : : ; Bn:i wie folgt definieren:</p>
        <p>
          A:s
Bj :i
f (A:i; B1:s; : : : ; Bn:s)
g(A:i; B1:s; : : : ; Bj 1:s; Bj+1:s; : : : ; Bn:s)
(1)
(2)
wobei f und g Funktionen sind, die Attributwerte auf andere Attributwerte abbilden, und j 2 f1; : : : ; ng.
Wenn die kontextfreien Regeln Terminale enthalten und/oder wenn Nichtterminale mehrere synthetisierte und
vererbte Attribute besitzen, so müssen die Formeln (1) und (2) entsprechend verallgemeinert werden (s. [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ] für
eine vollständige Beschreibung von attributierten Grammatiken).
        </p>
        <p>Die folgende Notation wird in dieser Arbeit genutzt, um Attribute und semantische Regeln darzustellen.
Semantische Regeln werden in geschweifte Klammern eingefasst und hinter den Rumpf der zugehörigen
kontextfreien Regel geschrieben. $0:a referenziert das Attribute a des Symbols auf der linken Seite der kontextfreien
Regel, $1:a bezeichnet das Attribut a des ganz links stehenden Symbols auf der rechten Seite der kontextfreien
Regel und so weiter. Jede semantische Regel a e besteht aus einem Attribut a auf der linken Seite und einem
Ausdruck e bestehend aus Attributen, Operationssymbolen und Konstanten auf der rechten Seite. Sie
repräsentiert eine Wertzuweisung des Werts von e an das Attribut a auf der linken Seite. Für den Ausdruck auf der
rechten Seite benutzen wir eine Syntax ähnlich wie in C oder Java.</p>
        <p>Nachdem ein Syntaxbaum (nach lexikalischer und syntaktischer Analyse) aufgebaut wurde, können die Werte
der Attribute der Nichtterminalsymbole des Baumes durch das Anwenden der semantischen Regeln abgeleitet
werden [1, p.54]. Die Reihenfolge, in welcher die Attribute ausgewertet werden, muss dabei den durch die
semantische Regeln induzierten Abhängigkeiten folgen. Im Allgemeinen gibt es allerdings keine Garantie, dass eine
Reihenfolge existiert, durch die alle Attribute von allen Knoten evaluiert werden können. Es existieren aber
Klassen von attributierten Grammatiken, welche die Benutzung der Attribute und semantischen Regeln einschränken,
um die Existenz einer Auswertungsreihenfolge zu garantieren [1, p.313].</p>
        <p>
          Für diese Arbeit relevant sind insbesondere S- und L-attributierte Grammatiken. S-attributierte
Grammatiken verwenden ausschließlich synthetisierte und keine vererbten Attribute [1, p.313]. Sie erlauben eine von
unten-nach-oben (bottom-up) verlaufende Evaluation von Attributen. L-attributierte Grammatiken erlauben
eine Auswertung der Attribute von links nach rechts; siehe [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ] für Details. Bereits mit S-attributierten Grammatiken
lassen sich alle in Programmiersprachen erforderlichen semantischen Überprüfungen durchführen. Die
relevanten Informationen müssen dann ggf. bis zur Wurzel durchgereicht und dort überprüft werden. L-attributierte
Grammatiken erlauben dies durch ihre größere Flexibilität manchmal etwas eleganter zu bewerkstelligen.
        </p>
        <p>Im Folgenden wird eine LL(1)-konforme kontextfreie Grammatik vorgestellt, welche die Untermenge von Java
Sprachkonstrukten beschreibt, die für das Erkennen von Spring-Konfigurationsfehlern relevant ist. Abbildung 1
gibt einen Überblick über die Produktionen, welche für eine erfolgreiche Analyse benötigt werden.</p>
        <p>Die semantischen Regeln, die für die attributierten Grammatiken genutzt werden, basieren auf den folgenden
Konstanten und Operationen: error wird genutzt, um anzuzeigen, dass ein Fehler festgestellt wurde, emptySet
erstellt eine leere Menge, newSet erstellt ein Menge mit einem einzelnen Element, intersects gibt an, ob die
Schnittmenge zweier Mengen nicht leer ist, und union errechnet die Vereinigungsmenge zweier Mengen. Die
Funktion value gibt für identifier den korrespondierenden String zurück.</p>
        <p>Im Folgenden wird beispielhaft eine attributierte Grammatik vorgestellt, die es erlaubt, den Fehler zu erkennen,
der in Listing 1 demonstriert wurde.</p>
        <p>Spring-Kontext-abhängige Fehler, die oberhalb des Methoden-Levels auftreten, zeichnen sich typischerweise
durch die An- oder Abwesenheit spezifischer Annotationen aus (Gruppe I). Die An- oder Abwesenheit lässt sich
durch zwei synthetisierte boolesche Attribute enabled und used ausdrücken.</p>
        <p>Der Fehler, der in Listing 1 demonstriert wurde, kann wie folgt erkannt werden. Das Attribut enabled evaluiert
zu true, sofern eine Spring-Konfiguration existiert und diese mit @EnableTransactionManagement annotiert ist.
Das Attribut used evaluiert zu true, sofern eine Methode existiert, die mit @Transactional annotiert ist. Ein
Fehler zeigt sich, wenn enabled ^ :used wahr ist.</p>
        <p>Die Erkennung lässt sich durch eine S-attributierte Grammatik mit vier synthetisierten Attributen enabled, used,
hroot i ::= htypedecllist i</p>
        <p>| $
htypedecllist i ::= htypedecl i htypedecllist i</p>
        <p>| "
htypedecl i ::= hmodifiers i htypedecltypei
hmodifiers i ::= ‘public’
| ‘private’
| hannotationi hmodifiers i
| "
htypedecltypei ::= hannotypedecl i
| hclassdecl i
| hinterfacedecl i
hannotypedecl i ::= ‘@interface’ hidentifier i ‘{’ hannotypebody i ‘}’
hclassdecl i ::= ‘class’ hidentifier i hsuperclass i hinterfaces i ‘{’ hclassbody i ‘}’
hinterfacedecl i ::= ‘interface’ hidentifier i hsuperinterfacei ‘{’ hinterfacebody i ‘}’
hclassbody i ::= hmodifiers i htypei hidentifier i hclassbodytypei hclassbody i
| "</p>
        <p>Abbildung 1: (Vereinfachte) Java-Grammatik in BNF-Notation (Ausschnitt).
name und names ausdrücken, wobei enabled auf das Vorhandensein von EnableTransactionManagement und
analog used auf @Transactional hindeutet. name bezeichnet einen identifier einer Annotation und names eine
Menge von Annotationsnamen.</p>
        <p>Im Folgenden werden die semantischen Regeln detailliert beschrieben. Tabelle 2 gibt einen Überblick über
die relevanten Nichtterminale und ihre synthetisierten Attribute. Abbildung 2 und 3 zeigen eine
korrespondierende S-attributierte Grammatik. Die Auswertung startet mit dem Sammeln von hannotationi-Namen. Jedes
hannotationi-Element gibt seinen name an das umschließende hmodif iersi-Element weiter, welches die Namen
sammelt. Für hclassbodyi und hinterf acebodyi wird das Attribut used auf true gesetzt, wenn die Menge der
gesammelten modifiers die @Transactional Annotation beinhalten.</p>
        <p>Danach wird der Wert der used -Attribute über hclassdecli und hinterf acedecli an htypedecltypei
weitergereicht (s. Abbildung 3). Der Wert des used -Attributs für Annotationstypen ist immer false, da sie die
@Transactional Semantik nicht nutzen können. htypedecltypei propagiert den used -Wert an die einschließende htypedecli.
hannotationi ::= ‘@’ hidentifier i</p>
        <p>f$0:name value($1); g
hmodifiersi ::= ‘public’</p>
        <p>f$0:names emptySet(); g
| ‘private’</p>
        <p>f$0:names emptySet(); g
| hannotationi hmodifiersi</p>
        <p>f$0:names union(newSet($1:name); $2:names); g
| "</p>
        <p>f$0:names emptySet(); g
hclassbodyi ::= hmodifiersi htypei hidentifier i hclassbodytypei hclassbodyi</p>
        <p>f$0:used intersects(newSet(‘Transactional’); $1:names) k $5:used; g
| "</p>
        <p>f$0:used f alse; g
hinterfacebodyi ::= hmodifiersi htypei hidentifier i hmethoddecl i hinterfacebody i</p>
        <p>f$0:used intersects(newSet(‘Transactional’); $1:names) k $5:used; g
| "
f$0:used f alse; g</p>
        <p>Abbildung 2: S-attributierte Grammatik zur Detektierung von Transactional-Fehlern (Ausschnitt 1).
Zusätzlich wird überprüft, ob die Typdeklaration selbst die @Transactional Annotation benutzt. Auch wird
überprüft, ob die Typdeklaration tatsächlich eine Spring-Kontext-Konfigurationsklasse ist und, falls dem so ist, ob
das Transaktionsmanagement aktiviert ist. Das enabled -Attribut repräsentiert das Ergebnis dieser Überprüfung.</p>
        <p>Für jede htypedecllisti werden die Attribute jeder eingeschlossenen Typdeklarationen zusammengefasst.
Schließlich findet die finale Überprüfung an der Wurzel des Syntaxbaums statt. Ein Fehler wird erkannt, wenn
das Transaktionsmanagement aktiviert ist, jedoch keine vorhandene Methode die @Transactional Annotation
verwendet (also: enabled ^ :used).</p>
        <p>Mit diesen semantischen Regeln ergibt sich für das Beispiel in Listing 1 eine Atributierung des abstrakten
Syntaxbaums (ASB), wie sie ausschnittsweise in Abbildung 4 zu sehen ist.</p>
        <p>
          Weitere Fehler oberhalb des Methoden-Levels lassen sich durch ähnliche attributierte Grammatiken erkennen.
Für Fehler der Gruppe II verwenden wir L-attributierte Grammatiken. Für Fehler, die unterhalb des
MethodenLevels (Gruppe III &amp; IV) auftreten, erzeugt eine L-attributierte Grammatik zunächst einen Kontrollfluss-Graphen
(KFG) [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ], anhand dessen dann eine Analyse erreichender Definitionen (reaching definitions)[14, p.218]
durchgeführt wird. Hiermit lassen sich dann z.B. Fehler bezüglich Objekt-zestörender Methoden bei Beans mit
Gültigkeitsbereich prototype feststellen, wie sie in Listing 3 auftreten.
        </p>
        <p>Der KFG mit den Ergebnissen der Analyse erreichender Definitionen für das Beispiel in Listing 4 findet sich
in Abbildung 5. Anzumerken ist, dass bei diesem konstruierten Beispiel die Analyse auf einen
Konfigurationsfehler hinweist, der in der Praxis nicht auftreten kann, da die korrespondierende Bedingung nie erfüllt wird (if
(false)), was aber von der Analyse ignoriert wird.
1 @Configuration
2 public c l a s s S p r i n g C o n f i g {
3 @Bean
4 @Scope ( " p r o t o t y p e " )
5 public P r i n t S e r v i c e p r i n t S e r v i c e ( ) {
6 P r i n t S e r v i c e p = new P r i n t S e r v i c e ( ) ;
7 i f ( f a l s e )
8 p = new L a s e r P r i n t e r S e r v i c e ( ) ;
9 return p ; }
10 }
11
12 public c l a s s P r i n t S e r v i c e {. . . }
13
14 public c l a s s L a s e r P r i n t e r S e r v i c e
15 extends P r i n t S e r v i c e {
hclassdecl i ::= ‘class’ hidentifier i hsuperclass i hinterfaces i ‘{’ hclassbody i ‘}’</p>
        <p>f$0:used $4:used; g
hinterfacedecl i ::= ‘interface’ hidentifier i hsuperinterfacei ‘{’ hinterfacebody i ‘}’</p>
        <p>f$0:used $3:used; g
htypedecltypei ::= hannotypedecl i</p>
        <p>f$0:used f alse; g
| hclassdecl i</p>
        <p>f$0:used $1:used; g
| hinterfacedecl i</p>
        <p>f$0:used $1:used; g
htypedecl i ::= hmodifiers i htypedecltypei
f$0:used $2:used k intersects(newSet(‘Transactional’); $1:names);
$0:enabled intersects(newSet(‘Configuration’); $1:names)</p>
        <p>&amp;&amp; intersects(newSet(‘EnableTransactionManagement’); $1:names); g
| "
f$0:enabled
$0:used</p>
        <p>f alse;
f alse; g
htypedecllist i ::= htypedecl i htypedecllist i
f$0:enabled $1:enabled k $2:enabled;
$0:used $1:used k $2:used; g
hroot i ::= htypedecllist i</p>
        <p>fif ($1:enabled &amp;&amp; !$1:used)ferror(); gg
| $
16
17
18 }
Abbildung 3: S-attributierte Grammatik zur Detektierung von Transactional-Fehlern (Ausschnitt 2).</p>
        <sec id="sec-2-4-1">
          <title>Listing 4: Bean mit Gültigkeitsbereich prototype.</title>
          <p>4</p>
        </sec>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>Prototypische Implementierung</title>
      <p>
        Ausgehend von den oben erläuterten attributierten Grammatiken wurde in Java eine prototypische
Implementierungen der Annotations-Analyse mit Hilfe der Java Pluggable Annotation Processing API umgesetzt. Diese
API ist durch die Java Specification Request (JSR) 269 spezifiziert und erlaubt die Verarbeitung von
Annotationen während der Compilezeit [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. Sie definiert ein Sprachmodell des verarbeiteten Java-Codes, das auf dem
Kompositum-Entwurfsmuster [8, p.183] beruht. Basierend auf einem Ansatz, wie er in [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] vorgestellt wurde,
wird eine Art abstrakter Syntaxbaum zur Verfügung gestellt. Außerdem definiert diese API, wie
CompilerErweiterungen zu deklarieren und auszuführen sind. Abbildung 6 illustriert die Architektur des Java-Compilers.
Sie basiert auf dem Pipe- und Filter-Architekturmuster [12, p.432]. Die Abbildung zeigt, wie unser Prototyp
sich in den Übersetzungsprozess über die Pluggable Annotation Processing API einfügt. Sobald in diesem
Prozess die lexikalische und syntaktische Analyse des Quellcodes abgeschlossen ist, wird der Prototyp durch das
Plugin-Interface aufgerufen. Die Transformation der Gesamtheit der erstellten attributierten Grammatiken in
Compiler-Plugins erfolgte von Hand, lässt sich aber in zukünftigen Arbeiten automatisieren. Gefundene Fehler
werden durch die Messager -Komponente zu den Fehlermeldungen des Compilers hinzugefügt.
      </p>
      <p>Die Pluggable Annotation Processing API stellt lediglich eine Untermenge von Java bereit. Sprachkonstrukte,
die sich innerhalb von Methodenrümpfen finden, wie z.B. Zuweisungen oder Methodenaufrufe, sind nicht
enthalten. Um Letztere zu bearbeiten, wird eine weitere API verwendet. Oracle’s javac-Compiler stellt hierfür eine
Compiler-spezifische API namens Compiler Tree API bereit. Diese Low-Level API stellt eine Struktur bereit,
Abbildung 4: Annotierter Syntax-Baum (Ausschnitt).</p>
      <p>08</p>
      <p>&lt;p; LaserPrintService&gt;
entry
06
09
exit
empty
&lt;p; PrintService&gt;
&lt;p; PrintService,</p>
      <p>LaserPrintService&gt;</p>
      <sec id="sec-3-1">
        <title>Abbildung 5: KFG für eine prototypische Bean Definition.</title>
        <p>die dem benötigten vollständigen ASB entspricht. Hierauf aufbauend lassen sich der KFG erstellen und die in
Abschnitt 3 erwähnte Datenfluss-Analyse durchführen.
5</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Evaluierung</title>
      <p>Der entwickelte Prototyp wurde in mehreren Java-Projekten eingesetzt, um seine Funktionalität zu demonstrieren
und die Performance zu evaluieren.</p>
      <p>Alle Beispielanwendungen basieren auf dem Spring Framework in Version 3.11: Die Spring Pet Clinic2 ist
eine Beispielanwendung, die durch das Spring Framework selbst bereitgestellt wird. Sie wurde ausgewählt, da
hier jegliche Spring Features vorkommen, die durch den Annotations-Prozessor berücksichtigt werden können,
wie Dependency Injection, Transaktionsmanagement und Caching. Broadleaf Commerce3 ist ein Open-Source
E-Commerce Framework basierend auf Java und Spring und besteht aus 115:000 Zeilen Quellcode. Es
repräsentiert eine realitätsnahe Anwendung. Zusätzlich werden 12 Beispiele4 berücksichtigt, die jeweils genau eine
Instanz der zu identifizierenden Spring-Konfigurations-Fehlertypen beinhalten. Sie repräsentieren zwar keine
reaSiehe https://github.com/spring-projects/spring-petclinic
Siehe https://github.com/BroadleafCommerce/BroadleafCommerce
Siehe https://github.com/vvhof/DetectingSpringConfigurationErrorsExamples</p>
      <sec id="sec-4-1">
        <title>Abbildung 6: Pipe- und Filter-Architektur des Java-Compilers.</title>
        <p>litätsnahen Anwendungsfälle, sind allerdings hilfreich, um zeigen zu können, dass der Prototyp die verschiedenen
Fehlertypen korrekt erkennen kann.</p>
        <p>Um die Performance zu messen, werden die Build-Zeiten der Projekte jeweils mit und ohne Prototyp verglichen.
Da alle in Frage kommenden Projekte auf Maven basierend, können die Zeiten direkt in Maven selbst gemessen
werden. Um sicherzustellen, dass die Zeiten vergleichbar sind, werden alle Builds auf derselben Maschine mit
identischer Konfiguration durchgeführt. Zusätzlich werden die Builds mehrfach ausgeführt, um den Einfluss
externen Faktoren, wie z.B. anderer Systemprozesse, zu minimieren.</p>
        <p>Für jedes Projekt werden 41 Builds ausgeführt. Der erste Build wird nicht mitgemessen, da Maven beim
ersten Durchlauf ggf. Pakete herunterladen muss, was die Build-Zeit verfälscht. Des Weiteren benötigt die Java
Virtual Machine einige Zeit zur Initialisierung, was wiederum die Resultate verfälschen kann. 40 zusätzliche
Builds werden daraufhin durchgeführt, um daraus die tatsächlichen Build-Zeiten zu errechnen. 20 dieser Builds
werden mit dem Prototypen und 20 ohne den Prototypen durchführt.</p>
        <p>Da es sich bei Broadleaf Commerce (in Version 3.1.0-ALPHA3) und der Spring Pet Clinic um gut ausgetestete
Anwendungen handelt, zeigen sich hier natürlich keine Spring-spezifischen Fehler. Hier interessieren daher nur
die ermittelten Build-Zeiten. Alle Fehler in den konstruierten Beispielen werden problemlos gefunden.</p>
        <p>Die Laufzeiten der Build-Prozesse mit aktiviertem und deaktiviertem Prototypen unterscheiden sich nicht
signifikant (siehe Tabelle 3). Die Unterschiede betragen weniger als eine Sekunde für kleine Projekte. Misst man
die Zeiten für einen Annotations-Prozessor, der keinerlei Überprüfungen durchführen muss, ergeben sich dabei
vergleichbare Werte. Daher liegt der Schluss nahe, dass ein Großteil der Differenz auf den Annotations-Prozessor
selbst und nicht auf den Algorithmus für die Analyse entfällt. Die größte absolute Differenz tritt beim Broadleaf
Commerce auf und äußert sich bei diesem Projekt mit 115:000 LoC in einer Steigerung der Build-Zeit um 2
Sekunden und damit 3%. Es sei angemerkt, dass dieses Projekt aus sieben modularen Maven-Projekten besteht
und das Java-Plugin für jedes dieser Projekte gestartet werden muss. Daher wird auch der Prototyp sieben Mal
lokalisiert und initialisiert.</p>
        <p>Bisher kann unser Prototyp mit 12 verschiedenen Fehlertypen umgehen und er kann, wie unsere Experimente
zeigen, Fehlerinstanzen der Fehlertypen erfolgreich aufspüren. Die Implementierung weiterer Fehlertypen steht
noch aus.</p>
        <p>Folgendes lässt sich in Bezug auf die Korrektheit und Vollständigkeit unseres Tools anmerken. Oberhalb des
Methoden-Levels werden alle Fehler korrekt erkannt und es werden keine Fehler irrtümlich gemeldet. Unterhalb
des Methoden-Levels benutzen wir die erwähnte statische Analyse basierend auf dem Kontrollfluss-Graphen.
Durch den damit verbundenen (und unvermeidbaren) Präzisionsverlust kann es vorkommen, dass Fehler gemeldet
werden, die auf Grund von Datenabhängigkeiten allerdings niemals auftreten können. Das Beispiel in Listing 4</p>
        <sec id="sec-4-1-1">
          <title>Projekt LoC</title>
          <p>Fehlertyp 1 29
Fehlertyp 2 156
Fehlertyp 3 36
Fehlertyp 4 37
Fehlertyp 5 37
Fehlertyp 6 69
Fehlertyp 7 56
Fehlertyp 8 53
Fehlertyp 9 39
Fehlertyp 10 39
Fehlertyp 11 54
Fehlertyp 12 54
Spring PetClinic 1 390
Broadleaf Commerce 115 902
hat dies veranschaulicht. Erfreulicherweise treten solche Probleme in der Praxis selten auf, da es schlechter
Programmierstil wäre, die Korrektheit einer Konfiguration von Kontroll- und Datenfluss abhängig zu machen.
Man könnte sogar einen Schritt weiter gehen und argumentieren, dass dies tatsächlich auch als Fehler gemeldet
werden sollte, damit solche stilistischen Vergehen behoben werden können.</p>
          <p>Unsere aktuelle Implementierung unterstützt bisher noch keine Analyse über Methodengrenzen hinweg.
Dementsprechend werden Fehler, die ausschließlich durch solch eine Analyse erkannt werden können, zur Zeit
noch nicht entdeckt.</p>
          <p>Abschließend seien zwei Einschränkungen für den durch uns gewählten Ansatz genannt. Die verwendete
Pluggable Annotation Processing API macht es zwingend erforderlich, einen Java-Compiler zu verwenden, der diese
unterstützt. Dadurch dass die Compiler Tree API verwendet wird, muss es sich hierbei weiterhin auf den
Oraclespezifischen Java-Compiler javac handeln.
6</p>
        </sec>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>Fazit und zukünftige Betätigungsfelder</title>
      <p>Dependency Injection ist ein elegantes Entwurfsmuster. Bei seinem Einsatz können allerdings
Konfigurationsfehler auftreten, welche nicht durch den Java-Compiler erkannt werden. Diese fehlerhaften Konfigurationen sind
daher erst zur Laufzeit erkennbar, weswegen ein kompliziertes Debugging erforderlich wird, was zu
Verzögerungen bei der Softwareentwicklung führt. In dieser Arbeit wurde ein selbst entwickeltes Compiler-Plugin für den
javac-Compiler vorgestellt, welches es erlaubt, fehlerhafte Konfigurationen bereits zur Compilezeit zu erkennen.
Konzeptionell basiert das Plugin auf attributierten Grammatiken und verschiedenen APIs des Java-Compilers.</p>
      <p>In einem ersten Schritt wurde für das weit verbreitete Framework Spring basierend auf durchgeführten
Literaturreviews und Experteninterviews eine Menge von 38 verschiedenen Fehlertypen zusammengestellt.
Anschließend wurden diese Fehlertypen in vier Kategorien unterteilt. Die Klassifikation basiert auf zwei Dimensionen.
Die erste Dimension beschäftigt sich mit der Frage, ob eine Überprüfung des Fehlers oberhalb oder unterhalb des
Methoden-Levels stattfinden muss. Die Zweite unterscheidet, ob der Fehlertyp vom gewählten Spring-Kontext
abhängig ist oder nicht. Für jede dieser vier Fehlerklassen wurde ein Schema für eine S- oder L-attributierte
Grammatik entwickelt und anschließend für jeden möglichen Fehler instanziiert. Durch die Kombination der
attributierten Grammatiken aller Fehlertypen wurde eine übergreifende L-attributierte Grammatik zur
Fehlererkennung erzeugt. Für Fehler, die vom Kontroll- und Datenfluss abhängen, wurde eine Analyse erreichender
Definitionen (reaching definitions) basierend auf dem Kontrollfluss-Graphen durchgeführt.</p>
      <p>In Experimenten mit zwei großen und verschiedenen kleineren Spring-Applikationen konnte nachgewiesen
werden, dass das entwickelte Plugin lediglich einen geringen Mehraufwand in der Build-Phase induziert. Außerdem
konnte das Plugin alle vorhandenen Konfigurationsfehler erkennen. Im Prinzip können bei aufgrund von
Datenabhängigkeiten unerreichbaren Code-Teilen irrtümliche Fehlermeldungen (false-positives ) auftreten. Diese haben
sich im praktischen Einsatz des Werkzeugs bisher allerdings noch nicht bemerkbar gemacht.</p>
      <p>Unser Plugin stellt ein hilfreiches Tool für die Spring-Entwicklung dar und wird vom Projektpartner aktuell
erfolgreich in der Praxis eingesetzt. Dort unterstützt es das Softwareentwicklungs-Team dabei, Spring-basierte
Projekte schneller zu realisieren.</p>
      <p>Die aktuelle Implementierung kann 12 der 38 identifizierten Fehlertypen erkennen. In zukünftigen Arbeiten
soll das Plugin erweitert werden, sodass zusätzlich die noch fehlenden Fehlertypen erkannt werden. Für alle
bis auf 5 Fehlertypen ist dies nach dem existierenden Schema ein einfaches Unterfangen. Die verbleibenden 5
Fehlertypen werden sich nur durch eine Analyse über Methodengrenzen hinweg erkennen lassen.
7</p>
    </sec>
    <sec id="sec-6">
      <title>Danksagung</title>
      <sec id="sec-6-1">
        <title>Wir danken der viadee GmbH für ihre Zusammenarbeit.</title>
      </sec>
    </sec>
    <sec id="sec-7">
      <title>Literatur</title>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>A. V.</given-names>
            <surname>Aho</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. S.</given-names>
            <surname>Lam</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Sethi</surname>
          </string-name>
          , and
          <string-name>
            <given-names>J. D.</given-names>
            <surname>Ullman</surname>
          </string-name>
          . Compilers: Principles, Techniques, &amp;
          <string-name>
            <surname>Tools</surname>
          </string-name>
          . AddisonWesley Publishing Company, USA, 2nd edition,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>N.</given-names>
            <surname>Ayewah</surname>
          </string-name>
          ,
          <string-name>
            <given-names>W.</given-names>
            <surname>Pugh</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J. D.</given-names>
            <surname>Morgenthaler</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Penix</surname>
          </string-name>
          , and
          <string-name>
            <given-names>Y.</given-names>
            <surname>Zhou</surname>
          </string-name>
          .
          <article-title>Evaluating static analysis defect warnings on production software</article-title>
          .
          <source>In Proceedings of the 7th ACM SIGPLAN-SIGSOFT workshop on Program analysis for software tools and engineering</source>
          , pages
          <fpage>1</fpage>
          -
          <lpage>8</lpage>
          . ACM,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>G.</given-names>
            <surname>Bracha</surname>
          </string-name>
          and
          <string-name>
            <given-names>D.</given-names>
            <surname>Ungar</surname>
          </string-name>
          . Mirrors:
          <article-title>Design Principles for Meta-level Facilities of Object-oriented Programming Languages</article-title>
          .
          <source>SIGPLAN Not</source>
          .,
          <volume>39</volume>
          (
          <issue>10</issue>
          ):
          <fpage>331</fpage>
          -
          <lpage>344</lpage>
          , Oct.
          <year>2004</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>O.</given-names>
            <surname>Burn</surname>
          </string-name>
          . Checkstyle,
          <year>2003</year>
          . https://checkstyle.sourceforge.net.
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>D. R.</given-names>
            <surname>Cok</surname>
          </string-name>
          and
          <string-name>
            <given-names>J. R.</given-names>
            <surname>Kiniry</surname>
          </string-name>
          . ESC/Java2:
          <article-title>Uniting ESC/Java and JML</article-title>
          .
          <source>In Construction and Analysis of Safe, Secure, and Interoperable Smart Devices</source>
          , pages
          <fpage>108</fpage>
          -
          <lpage>128</lpage>
          . Springer,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>J. D.</given-names>
            <surname>Darcy</surname>
          </string-name>
          ,
          <year>2006</year>
          . https://www.jcp.org/en/jsr/detail?id=
          <fpage>269</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>T.</given-names>
            <surname>Ekman</surname>
          </string-name>
          and
          <string-name>
            <surname>G. Hedin.</surname>
          </string-name>
          <article-title>The Jastadd Extensible Java Compiler</article-title>
          .
          <source>In Proceedings of the 22nd annual ACM SIGPLAN conference on Object-oriented programming systems and applications</source>
          ,
          <source>OOPSLA '07</source>
          , pages
          <fpage>1</fpage>
          -
          <lpage>18</lpage>
          , New York, NY, USA,
          <year>2007</year>
          . ACM.
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>E.</given-names>
            <surname>Gamma</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Helm</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Johnson</surname>
          </string-name>
          , and
          <string-name>
            <given-names>J.</given-names>
            <surname>Vlissides</surname>
          </string-name>
          . Design Patterns:
          <article-title>Elements of Reusable Object-oriented Software</article-title>
          .
          <article-title>Addison-Wesley Longman Publishing Co</article-title>
          ., Inc., Boston, MA, USA,
          <year>1995</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>D.</given-names>
            <surname>Greenfieldboyce</surname>
          </string-name>
          and
          <string-name>
            <given-names>J. S.</given-names>
            <surname>Foster</surname>
          </string-name>
          .
          <article-title>Type qualifier inference for Java</article-title>
          .
          <source>In ACM SIGPLAN Notices</source>
          , volume
          <volume>42</volume>
          , pages
          <fpage>321</fpage>
          -
          <lpage>336</lpage>
          . ACM,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <surname>R.</surname>
          </string-name>
          <year>e</year>
          . a. Johnson. Spring Framework Reference Documentation,
          <year>2015</year>
          . http://docs.spring.io/spring/ docs/3.2.11.RELEASE/spring-framework-reference/htmlsingle/.
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <given-names>D. E.</given-names>
            <surname>Knuth</surname>
          </string-name>
          .
          <article-title>Semantics of Context-Free Languages</article-title>
          .
          <source>In Mathematical Systems Theory</source>
          , pages
          <fpage>127</fpage>
          -
          <lpage>145</lpage>
          ,
          <year>1968</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <given-names>J.</given-names>
            <surname>Ludewig</surname>
          </string-name>
          and
          <string-name>
            <given-names>H.</given-names>
            <surname>Lichter</surname>
          </string-name>
          . Software Engineering: Grundlagen, Menschen, Prozesse, Techniken. dpunkt. verlag,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <given-names>S.</given-names>
            <surname>Markstrum</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Marino</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Esquivel</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Millstein</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Andreae</surname>
          </string-name>
          , and
          <string-name>
            <surname>J. Noble.</surname>
          </string-name>
          <article-title>JavaCOP: Declarative pluggable types for Java</article-title>
          .
          <source>ACM Transactions on Programming Languages and Systems (TOPLAS)</source>
          ,
          <volume>32</volume>
          (
          <issue>2</issue>
          ):
          <fpage>4</fpage>
          ,
          <year>2010</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>S. S.</given-names>
            <surname>Muchnick</surname>
          </string-name>
          .
          <article-title>Advanced Compiler Design and Implementation</article-title>
          . Morgan Kaufmann Publishers Inc., San Francisco, CA, USA,
          <year>1997</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>Oracle</given-names>
            <surname>Corporation</surname>
          </string-name>
          .
          <article-title>Package java</article-title>
          .
          <source>lang.reflect</source>
          ,
          <year>2015</year>
          . https://docs.oracle.com/javase/8/docs/api/ java/lang/reflect/package-summary.html.
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <surname>M. M. Papi</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          <string-name>
            <surname>Ali</surname>
            ,
            <given-names>T. L.</given-names>
          </string-name>
          <string-name>
            <surname>Correa</surname>
            , Jr.,
            <given-names>J. H.</given-names>
          </string-name>
          <string-name>
            <surname>Perkins</surname>
            , and
            <given-names>M. D.</given-names>
          </string-name>
          <string-name>
            <surname>Ernst</surname>
          </string-name>
          .
          <article-title>Practical Pluggable Types for Java</article-title>
          .
          <source>In Proceedings of the 2008 International Symposium on Software Testing and Analysis</source>
          ,
          <source>ISSTA '08</source>
          , pages
          <fpage>201</fpage>
          -
          <lpage>212</lpage>
          , New York, NY, USA,
          <year>2008</year>
          . ACM.
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [17]
          <string-name>
            <surname>Pivotal</surname>
            <given-names>Sofware</given-names>
          </string-name>
          , Inc. Spring Framework,
          <year>2015</year>
          . http://openjdk.java.net/projects/compiler-grammar/.
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [18]
          <string-name>
            <surname>PMD. Pmd</surname>
          </string-name>
          ,
          <year>2015</year>
          . http://pmd.sourceforge.net.
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [19]
          <string-name>
            <given-names>D. R.</given-names>
            <surname>Prasanna</surname>
          </string-name>
          . Dependency Injection. Manning Publications Co.,
          <string-name>
            <surname>Greenwich</surname>
            ,
            <given-names>CT</given-names>
          </string-name>
          , USA, 1st edition,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          [20]
          <string-name>
            <given-names>K.</given-names>
            <surname>Slonneger</surname>
          </string-name>
          and
          <string-name>
            <given-names>B.</given-names>
            <surname>Kurtz</surname>
          </string-name>
          .
          <article-title>Formal Syntax and Semantics of Programming Languages: A Laboratory Based Approach</article-title>
          . Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA, 1st edition,
          <year>1995</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          [21]
          <string-name>
            <surname>SonarSource S.A. SonarQube</surname>
          </string-name>
          ,
          <year>2015</year>
          . http://www.sonarqube.org.
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          [22]
          <string-name>
            <given-names>E.</given-names>
            <surname>Spishak</surname>
          </string-name>
          ,
          <string-name>
            <given-names>W.</given-names>
            <surname>Dietl</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M. D.</given-names>
            <surname>Ernst</surname>
          </string-name>
          .
          <article-title>A Type System for Regular Expressions</article-title>
          .
          <source>In Proceedings of the 14th Workshop on Formal Techniques for Java-like Programs</source>
          ,
          <source>FTfJP '12</source>
          , pages
          <fpage>20</fpage>
          -
          <lpage>26</lpage>
          , New York, NY, USA,
          <year>2012</year>
          . ACM.
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          [23]
          <string-name>
            <surname>E. Van Wyk</surname>
          </string-name>
          ,
          <string-name>
            <given-names>L.</given-names>
            <surname>Krishnan</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Bodin</surname>
          </string-name>
          , and
          <string-name>
            <given-names>E.</given-names>
            <surname>Johnson. Adding</surname>
          </string-name>
          Domain-specific and
          <article-title>General Purpose Language Features to Java with the Java Language Extender</article-title>
          . In Companion to the
          <source>21st ACM SIGPLAN Symposium on Object-oriented Programming Systems, Languages, and Applications</source>
          , OOPSLA '
          <volume>06</volume>
          , pages
          <fpage>728</fpage>
          -
          <lpage>729</lpage>
          , New York, NY, USA,
          <year>2006</year>
          . ACM.
        </mixed-citation>
      </ref>
      <ref id="ref24">
        <mixed-citation>
          [24]
          <string-name>
            <given-names>C.</given-names>
            <surname>Walls</surname>
          </string-name>
          . Spring in Action. Manning Publications Co.,
          <string-name>
            <surname>Greenwich</surname>
            ,
            <given-names>CT</given-names>
          </string-name>
          , USA, 4th edition,
          <year>2014</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>