Slide 1 (of 21)
MULTIVIE
WRemoving Duplication from java.io: a Case Study using
TraitsEmerson R. Murphy-Hill, Philip J. Quitslund, Andrew P.
BlackMaseeh College of Engineering and Computer Science
Portland State University
Slide 2 (of 21)
MULTIVIE
W
Introduction
• Duplication: widespread and problematic
• Here we demonstrate it• Look through some well-weathered
code• Try to factor out encountered
duplication with traits
Slide 3 (of 21)
MULTIVIE
W
Traits
• A trait is a collection of pure methods• Classes “use” traits• Traits can be used to supply the
same methods to multiple classes in the inheritance hierarchy
Slide 4 (of 21)
MULTIVIE
W
Duplication: Problem
ZooDweller
Mammal Bird
Platypus
Insect ...
Bear void reproduce(){ copulate(getMate()); if(this.isMale()) return; layEggs(); }
void reproduce(){ copulate(getMate()); if(this.isMale()) return; layEggs(); }
Trait TEggLaying void reproduce(){ copulate(getMate()); if(this.isMale()) return; layEggs(); } abstract void layEggs();
and Solution
Slide 5 (of 21)
MULTIVIE
W
Some Trait Implementations
• Original implementation in Squeak Smalltalk
• Also in Perl, Scala, and C#• Our implementation in Java, on top of
Eclipse– Traits represented as abstract classes– No compiler modification
Slide 6 (of 21)
MULTIVIE
W
java.ioOutputStream
FileOutputStream ByteArrayOutputStream FilterOutputStream ObjectOutputStream PipedOutputStream
BufferedOutputStream DataOutputStream PrintSteam
InputStream
ByteArrayInputStream FileInputStream FilterInputStream
BufferedInputStream DataInputStream LineNumberInputStream PushbackInputStream
ObjectOutputStream PeekInputStream PipedInputStream PipedInputStream SequenceInputStream StringBufferInputStream
Reader
CharArrayReader FilterReader
PushbackReader
BufferedReader InputStreamReader
FileReader
PipedReader StringReader
Writer
BufferedWriter CharArrayWriter FilterWriter OutputStreamWriter
FileWriter
PipedWriter PrintWriter StringWriter
LineNumberReader
Slide 7 (of 21)
MULTIVIE
W
The Plan
9 AMFind duplication
9:15 AMRemove duplication using Traits
11:15 AMPat selves on back; go home early
Slide 8 (of 21)
MULTIVIE
W
Finding Duplication
• We identified some duplication detection tools:– Duplication Management Framework– SimScan– PMD’s Copy-Paste Detector (CPD)
• Some obvious duplication found, but that was just the tip of the iceberg…
Slide 9 (of 21)
MULTIVIE
W
Interesting Detected Duplication
• Other throwers of IndexOutOfBoundsException?
} else if (b == null) { throw new NullPointerException();} else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();} else if (len == 0) { return 0;}
Slide 10 (of 21)
MULTIVIE
W
Detection Effectiveness
3
26
Matchesfoundby CPD
Matchesfound
by hand
Differences in:
•Semantics
•Structure
•Efficiency
•Miscellaneous
Slide 11 (of 21)
MULTIVIE
W
Semantic differences
(StringReader>>read(...))if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();} else if (len == 0) { return;}
(StringWriter>>write(...)) if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();} else if (len == 0) { return 0;}
Slide 12 (of 21)
MULTIVIE
W
Structural Differences(ByteArrayOutputStream>>write(...)) if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();} else if (len == 0) { return;}
(ByteArrayInputStream>>read(...)) if (b == null) { throw new NullPointerException();} else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();}if (pos >= count) { return -1;}if (pos + len > count) { len = count - pos;}if (len <= 0) { return 0;}
Slide 13 (of 21)
MULTIVIE
W
Exception Handling Differences(ByteArrayOutputStream>>write(...)) if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();} else if (len == 0) { return;}
(ByteArrayInputStream>>read(...)) if (b == null) { throw new NullPointerException();} else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();}if (pos >= count) { return -1;}if (pos + len > count) { len = count - pos;}if (len <= 0) { return 0;}
Suppose
b == null AND off == -1
?
Slide 14 (of 21)
MULTIVIE
W
Efficiency Differences
(ByteArrayOutputStream>>write(...)) if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException();} else if (len == 0) { return;}
(PipedWriter>>write(...)) if (sink == null) { throw new IOException("Pipe not connected");} else if ((off | len | (off + len) |
(cbuf.length - (off + len))) < 0)throw new IndexOutOfBoundsException();
Bounds check changed in 1.3, but in exactly 3 of 26 cases!
Slide 15 (of 21)
MULTIVIE
W
Miscellaneous Differences
(PushbackReader>>read(...)) try { if (len <= 0) { if (len < 0) { throw new IndexOutOfBoundsException(); } else if ((off < 0) || (off > cbuf.length)) { throw new IndexOutOfBoundsException(); } return 0; } //...actual work...} catch (ArrayIndexOutOfBoundsException e) { throw new IndexOutOfBoundsException();}
Slide 16 (of 21)
MULTIVIE
W
What did we Learn?
• Duplication occurs non-uniformly– So we can’t detect it easily using tools– And we can’t easily remove it
• We can’t tell the difference between intentional and accidental differences
Slide 17 (of 21)
MULTIVIE
W
Our Refactoring
InputStream
ByteArrayInputStream StringBufferInputStreamFileInputStreamFileOutputStream PipedInputStream
LineNumberInputStream
FilterInputStream
TSkip
Provideslong skip(long)
Requiresint read(byte,int,int)
int getSKIP_BUFFER_SIZE()byte[] getSkipBuffer
void setSkipBuffer(byte[])
TInputStream
Provides-
Requires-
TChannelClose
Providesvoid close()
Requiresvoid close0()
FileChannel getChannel()
To TClosing
TArrayBufferInputStream
Provideslong skip(long)int available()
Requiresint getPos()
int getCount()void setPos(long)
TReadProvides
int read(byte, int, int)Requiresint read()
Legend
Class A extends Class B
Class or Trait A uses Trait T
T
A
A
B
TBoundsCheck
Providesboolean boundsCheck(byte,off,len)
Requires-
PipedReader
Reader
LineNumberReader
BufferedReader
TSkip2Provides
long skip(long)Requires
int read(char,int,int)Object getLock
char[] getSkipBuffervoid setSkipBuffer(char[])
int getMaxSkipBufferSize()
TClosing
Provides-
Requires-
TRecievedLastProvides
void receivedLast()Requires
void setClosedByWriter(boolean)
TCloseProvides
void close()Requires
void setIn()void setClosedByReader(boolean)
From PipedInputStream
PrintStream PrintWriter
TPrinting
Provides-
Requires-
TPrintln
Providesvoid println()
void println(boolean)void println(int)
void println(long)void println(double)
void println(float)void println(char[])void println(String)void println(Object)
Requiresvoid newLine()
Object getLock()void print(boolean)
void print(int)void print(long)
void print(double)void print(float)
void print(char[])void print(String)void print(Object)
TPrint
Providesvoid print(boolean)
void print(int)void print(long)
void print(double)void print(float)
void print(char[])void print(String)void print(Object)
Requireswrite(char[])write(String)
TIOOperationProvides
void ensureOpen()boolean checkError()
RequiresObject getOut()
void flush()boolean getTrouble()
Slide 18 (of 21)
MULTIVIE
W
The Plan
9 AMFind duplication
9:15 AMRemove duplication using Traits
11:15 AMPat selves on back; go home early
Slide 19 (of 21)
MULTIVIE
W
Conclusion
• Finding duplication during the maintenance stage of software development is hard– Intentional and accidental differences
• Traits can factor out duplication in a commercial code base
• If coders use traits while programming, the need to duplicate is reduced
Slide 20 (of 21)
MULTIVIE
W
Related Work
• Related Studies– “Applying traits to the smalltalk collection
classes,” OOPSLA 2003.
• Related Approaches– Multiple Inheritance, Mixins, Delegation– Static Utility Classes– AOP
• AspectJ, CME(Hyper/J), etc.
• Any more?
Slide 21 (of 21)
MULTIVIE
W
Questions?