1 / 22

JTL – The Java Tools Language

JTL is a logic query language for Java programs that offers a readable syntax and powerful querying capabilities to find code elements with precision. It simplifies code lookup, pattern detection, and static pointcuts, embedded within Java.

jeason
Download Presentation

JTL – The Java Tools Language

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. JTL – The Java Tools Language An intuitive query language for Java programs By Tal Cohen ,Yossi Gil and Itay Maman Presented at OOPSLA 2006 Presented by Eyal Dror

  2. Why a Query Language Over Code? • The idea is not new; Existing solutions: • CodeQuest, BDDBDDB, XIRC, JQuery, … • A software engineering tool • Code lookup, Pattern detection (code smells), … • Embedded in programming languages • Static pointcuts in aspect-oriented programming • Type requirements in Concepts and Mixins • And more …

  3. Queries Embedded in the Program • Java 5 already provides code queries • Syntax close to Java • Limited expressive power • A hypothetical alternative (SQL) • Syntax significantly diverts from Java • Difficult to write/read public<T extends Cloneable & Serializable> void f(T ts) { ... } public<SELECT * FROM extends WHERE (super = 'Cloneable' or super = 'Serializeable') and subclass='T' ...> void f(T ts) { … }

  4. More Embedded Queries • Find classes that define a static method that returns int • The regular expression approach: • Very inaccurate • The XQuery approach • Too complicated to be used interactively • And then there’s JTL… static.*int.*\(.*\) • /class/method • [./return/@type=“int" and @modifiers="static"]

  5. So, What IS JTL? • A logic query language over Java programs • As strong as Datalog (implemented over it) • Has an intuitive and readable syntax • Has a simple data model (Three types) • The other solutions fall short

  6. JTL: Unary Predicates • A simple predicate: • Three sub-queries • Space (and comma) denotes conjunction • The subject variable • The hash symbol, #, or “This” denotes the subject variable • A variable in prefix position becomes the subject of the callee • If not specified, defaults to # (the subject) • static, final, etc. are library predicates, not keywords const := static final field; const := # static # final # field;

  7. JTL: Binary Predicates • Binary predicates • Accepts a subject and an additional parameter (in a postfix position) • (Names of Variables/Parameters must begin with a capital letter) • Subject chaining: Repeatedly using a variable as a subject • Can be rewritten using the ampersand operator: has_static_member[X] := class declares X, X static; extends+ Y := extends Y | extends Y', Y' extends+ Y; my_generic_method T := method(T), T extends Serializable, T extends Cloneable; my_generic_method T := method(T), T extends Serializable & Cloneable;

  8. JTL: Quantification { } my_class := class { static int field; field => private; many method; } • Quantifying the members of a class • Subject variable iterates over a set • Each condition must hold • Quantifiers: • Unary: exists, all, no, one, many • Binary: => (implies) • Quantifying with a generator • Default generator for classes: members: • Default quantifier: exists no_abstract_super := class extends+: { no abstract; }

  9. JTL: Matching Java Elements Type literal • Type literals • Passes an exact value to a predicate • Name matching • The subject must match the regular expression • Method signature • The subject must match both expression and argument list sortable_list := class extends /java.util.ArrayList { static final long field 'SerialVersionUID; public void sort(boolean); } Name matching (Regular expression) Method signature pattern

  10. JTL: The Type System • Only three types: • MEMBER • Constructors, methods, fields • TYPE • Interfaces, classes, primitive types, enum types, annotation types • SCRATCH • Used in querying the code dataflow • More about it later …

  11. JTL: Querying Imperative Code • Query access to fields • Field reads and writes • Query method invocation • From interfaces, the declaring type, … unused_private_member := private field, This is F, declared_in C, C inners*: { all !access[F]; } access F := read F | write F;

  12. JTL: Dataflow Analysis (1) • The SCRATCH type • Symbolic names for intermediate computation results • Holds values of temporary variables: • Constants • Method parameters • Results of expression calculation • Values pushed onto the stack by JVM instructions • Library predicates for checking whether a scratch is: • Copied from another scratch • A result of a calculation • Written to/Read from a field • Stored to/loaded from the local variable array • A game of code locations, not of actual values

  13. JTL: Dataflow Analysis (2) • A “chain” method – always returns “this” • Not only by “return this;” • Also captures “ret = this; return ret;” • “scratches:” – The default generator of a method. copy* S := is S | copy S | copy S', S' copy* S; chain_method := !void method { returned => copy* S, S this; }; !void method scratches: { … };

  14. Sample applications of JTL (1) • Pointcut specifications in AOP • Required: primitive fields read/write access • AspectJ: • JTL: get(public boolean *) || set(public boolean *) || get(public byte *) || set(public byte *) || get(public char *) || set(public char *) || get(public double *) || set(public double *) || get(public float *) || set(public float *) || get(public int *) || set(public int *) || get(public long *) || set(public long *) || get(public short *) || set(public short *); primitive := boolean | byte | char | double | float | int | long | short; ppf := public primitive field; pointcut prim_acc() : get(ppf) || set(ppf);

  15. Sample applications of JTL (2) • Generics requirements • C++’s implicit requirements – problematic • Java’s interface requirement – too restrictive • JTL: template<typename T> class ElementPrinter { public: void print(T element) { element.print(); }} interface Printable { void print(); }; (class | interface) { print(); };

  16. Sample applications of JTL (3) • Micro-patterns • Design patterns for classes/interfaces • Taylor the type’s structure according to its use • The “Trait” micro-pattern: • “an abstract class with no instance fields, at least one abstract method, and at least one public concrete instance method which was not inherited from Object.” • JTL’s definition of “Trait”: trait := abstract { no instance field; abstract method; public concrete instance method !declared_in[Object]; }

  17. Sample applications of JTL (4) • Lint-like tests • Detecting undesired coding habits • Loose coupling: Field declarations of concrete Collection types instead of the corresponding interfaces • PMD implements this test as a 45-lines Java class • JTL’s test: loose_coupling := (class | interface) { T method | T field | method(*, T, *); }, T implements /java.util.Collection;

  18. JTL’s Evaluation Scheme • JTL is translated into Datalog • The Datalog program is evaluated top-down • “need to know basis” • The JTL evaluation algorithm does not see more information than it needs • Only necessary facts are extracted from the native predicates • No database setup is needed • The database is built lazily (starts empty!) • A bottleneck in similar applications

  19. Why Relational Model? (vs. AST) • Support for unsorted set metaphor • Sets of packages, classes, members, etc. • Ease of search • Relational model supported by many searching theories • AST search done by cumbersome Visitor design-pattern • Model complexity reflected in the syntax • “avoid hiding inherited instance fields” – more then 30 lines of Java code vs. “class{ field overrides[_] }” • Caching and query optimization • Database query optimization is well established • And more …

  20. A Subtle Issue: Fragility (1) • Q: What’s special about p2? • A: The result of p2 is infinite • The result of p3 MAY be infinite, depending on p4 • Consequences: • Exhaustive Iteration over a closed world, usually the classpath – Performance penalty • Results are fragile! • Dependent on the definition of the world p1 := # extends A, A abstract; p2 := A extends #, A abstract; p3 := A extends #, A abstract, # p4 A; p4 := ...

  21. A Subtle Issue: Fragility (2) • Can we determine whether a query is fragile? • In the general case: No • In JTL’s case: Yes • Requires the native predicates to maintain a simple property • Recently proven by Gil and Zarivach • JTL’s current implementation is more conservative • Subject is not known  a runtime error • Works well in most practical situations

  22. Special Thanks To Itay Maman – My presentation is largely based on his JTL presentation

More Related