This document describes a tool that automatically converts Java methods to default methods in interfaces. The tool is implemented as an Eclipse plugin and uses type constraints to identify methods that can be converted from skeletal implementation classes to default methods in corresponding interfaces according to Java 8 features. An evaluation found the tool successfully converted around 20% of candidate methods and was shown to produce compilable and semantically equivalent results through various testing techniques. Future work could include performing additional refactorings simultaneously during the conversion process.
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
Automatically Converting Java Methods to Default
1. Defaultification Refactoring: A Tool for
Automatically Converting Java Methods to
Default
Raffi Khatchadourian1,2
Hidehiko Masuhara3
International Conference on Automated Software Engineering, 2017
1
Computer Science, Hunter College, City University of New York, USA
2
Computer Science, The Graduate Center, City University of New York, USA
3
Mathematical and Computing Science, Tokyo Institute of Technology, Japan
3. Interfaces Are Traditionally Lists of Method Declarations
• Traditionally, an interface is a Java type that lists method
declarations.
interface Collection<E> {
int size();
void add(E elem);
boolean isEmpty();
int capacity();
abstract boolean atCapacity();} 1
4. Interfaces Are Traditionally Lists of Method Declarations
• Traditionally, an interface is a Java type that lists method
declarations.
• Clients are guaranteed that concrete interface implementers
provide implementations for all listed methods.
interface Collection<E> {
int size();
void add(E elem);
boolean isEmpty();
int capacity();
abstract boolean atCapacity();} 1
5. Some Interface Methods Are Optional
• Interface methods can be listed as optional operations.
interface Collection<E> {
// ...
void add(E elem); /* optional */ }}
2
6. Some Interface Methods Are Optional
• Interface methods can be listed as optional operations.
• Implementers may choose to support them or not.
interface Collection<E> {
// ...
void add(E elem); /* optional */ }}
class ImmutableList<E> implements Collection<E> {
// ...
}
2
7. Some Interface Methods Are Optional
• Interface methods can be listed as optional operations.
• Implementers may choose to support them or not.
• If operations are unsupported, they conventionally throw an
UnsupportedOperationException.
interface Collection<E> {
// ...
void add(E elem); /* optional */ }}
class ImmutableList<E> implements Collection<E> {
// ...
@Override public void add(E elem) {
throw new UnsupportedOperationException();}}
2
8. Skeletal Implementation Classes Help Implement Interfaces
• The skeletal implementation design pattern [Bloch, 2008] is
used to make implementing interfaces easier.
3
9. Skeletal Implementation Classes Help Implement Interfaces
• The skeletal implementation design pattern [Bloch, 2008] is
used to make implementing interfaces easier.
• Abstract skeletal implementation class provides partial
implementations.
abstract class AbstractImmutableList<E> implements
Collection<E> {
@Override public void add(E elem) {
throw new UnsupportedOperationException();}}
3
10. Skeletal Implementation Classes Help Implement Interfaces
• The skeletal implementation design pattern [Bloch, 2008] is
used to make implementing interfaces easier.
• Abstract skeletal implementation class provides partial
implementations.
• Implementers extend the skeletal implementation class rather
than directly implementing the interface.
abstract class AbstractImmutableList<E> implements
Collection<E> {
@Override public void add(E elem) {
throw new UnsupportedOperationException();}}
class ImmutableList<E> extends AbstractImmutableList<E>{
// ...
@Override public void add(E elem) {
throw new UnsupportedOperationException();}}}
3
11. The Skeletal Implementation Pattern Has Several Drawbacks
The skeletal implementation pattern has several drawbacks.
4
12. The Skeletal Implementation Pattern Has Several Drawbacks
The skeletal implementation pattern has several drawbacks.
Example
ImmutableList cannot:
4
13. The Skeletal Implementation Pattern Has Several Drawbacks
The skeletal implementation pattern has several drawbacks.
Example
ImmutableList cannot:
• Subclass another class.
4
14. The Skeletal Implementation Pattern Has Several Drawbacks
The skeletal implementation pattern has several drawbacks.
Example
ImmutableList cannot:
• Subclass another class.
• Inherit skeletal implementations split over multiple
classes [Horstmann, 2014].
4
15. The Skeletal Implementation Pattern Has Several Drawbacks
The skeletal implementation pattern has several drawbacks.
Example
ImmutableList cannot:
• Subclass another class.
• Inherit skeletal implementations split over multiple
classes [Horstmann, 2014].
• Inherit skeletal implementations for multiple interfaces.
4
16. Java 8 Default Methods Can Replace Skeletal Implementations
• Java 8 enhanced interfaces allow both method declarations and
definitions.
interface Collection<E> {
default void add(E elem) { // optional.
throw new UnsupportedOperationException();}}
5
17. Java 8 Default Methods Can Replace Skeletal Implementations
• Java 8 enhanced interfaces allow both method declarations and
definitions.
• Implementers inherit the (default) implementation if none
provided.
interface Collection<E> {
default void add(E elem) { // optional.
throw new UnsupportedOperationException();}}
class ImmutableList<E> implements Collection<E> {}
5
18. Java 8 Default Methods Can Replace Skeletal Implementations
• Java 8 enhanced interfaces allow both method declarations and
definitions.
• Implementers inherit the (default) implementation if none
provided.
• Original motivation to facilitate interface evolution.
interface Collection<E> {
default void add(E elem) { // optional.
throw new UnsupportedOperationException();}}
class ImmutableList<E> implements Collection<E> {}
5
19. Java 8 Default Methods Can Replace Skeletal Implementations
• Java 8 enhanced interfaces allow both method declarations and
definitions.
• Implementers inherit the (default) implementation if none
provided.
• Original motivation to facilitate interface evolution.
• Can also be used as a replacement of the skeletal
implementation pattern [Goetz, 2011].
interface Collection<E> {
default void add(E elem) { // optional.
throw new UnsupportedOperationException();}}
class ImmutableList<E> implements Collection<E> {}
abstract class AbstractImmutableList<E> implements
Collection<E> {
@Override public void add(E elem) {
throw new UnsupportedOperationException();}}
5
21. • Implemented as an open source plug-in for the Eclipse IDE
(available at http://cuny.is/interefact).
6
22. • Implemented as an open source plug-in for the Eclipse IDE
(available at http://cuny.is/interefact).
• Built on existing refactoring support in Eclipse.
6
23. • Implemented as an open source plug-in for the Eclipse IDE
(available at http://cuny.is/interefact).
• Built on existing refactoring support in Eclipse.
• Conceptual approach based on type-constraints [Palsberg and
Schwartzbach, 1994; Tip et al., 2011].
6
24. • Implemented as an open source plug-in for the Eclipse IDE
(available at http://cuny.is/interefact).
• Built on existing refactoring support in Eclipse.
• Conceptual approach based on type-constraints [Palsberg and
Schwartzbach, 1994; Tip et al., 2011].
• See ICSE 2017 paper [Khatchadourian and Masuhara, 2017] for
approach details.
6
25. • Implemented as an open source plug-in for the Eclipse IDE
(available at http://cuny.is/interefact).
• Built on existing refactoring support in Eclipse.
• Conceptual approach based on type-constraints [Palsberg and
Schwartzbach, 1994; Tip et al., 2011].
• See ICSE 2017 paper [Khatchadourian and Masuhara, 2017] for
approach details.
• Implementation is in procedural-style, similar to Pull Up
Method refactoring. 6
33. Architecture and Plug-In Dependencies
• Four plugins: two internal and two with UIs.
• Internal plug-ins include core and test plug-ins.
8
34. Architecture and Plug-In Dependencies
• Four plugins: two internal and two with UIs.
• Internal plug-ins include core and test plug-ins.
• 259 automated refactoring tests.
8
35. Architecture and Plug-In Dependencies
• Four plugins: two internal and two with UIs.
• Internal plug-ins include core and test plug-ins.
• 259 automated refactoring tests.
• UI plug-ins include both end-user tool and evaluator.
8
36. Architecture and Plug-In Dependencies
• Four plugins: two internal and two with UIs.
• Internal plug-ins include core and test plug-ins.
• 259 automated refactoring tests.
• UI plug-ins include both end-user tool and evaluator.
• Depends on Eclipse refactoring support. 8
38. Useful?
• Successfully converted ∼20%
of methods possibly
participating in the pattern to
default methods in
corresponding interfaces
(see [Khatchadourian and
Masuhara, 2017] for details).
9
39. Useful?
• Successfully converted ∼20%
of methods possibly
participating in the pattern to
default methods in
corresponding interfaces
(see [Khatchadourian and
Masuhara, 2017] for details).
• Many failures related to:
9
40. Useful?
• Successfully converted ∼20%
of methods possibly
participating in the pattern to
default methods in
corresponding interfaces
(see [Khatchadourian and
Masuhara, 2017] for details).
• Many failures related to:
• Inaccessibility of members
between skeletal
implementers and
interfaces.
9
41. Useful?
• Successfully converted ∼20%
of methods possibly
participating in the pattern to
default methods in
corresponding interfaces
(see [Khatchadourian and
Masuhara, 2017] for details).
• Many failures related to:
• Inaccessibility of members
between skeletal
implementers and
interfaces.
• Access to instance fields.
9
43. Correct?
• Ensured that no compilation
errors existed before and
after refactoring.
• Verified unit tests results
identical before and after the
refactoring.
10
44. Correct?
• Ensured that no compilation
errors existed before and
after refactoring.
• Verified unit tests results
identical before and after the
refactoring.
• Preliminary pull request
study ensures that the
automated results matched
what experienced developers
may have written.
10
45. Correct?
• Ensured that no compilation
errors existed before and
after refactoring.
• Verified unit tests results
identical before and after the
refactoring.
• Preliminary pull request
study ensures that the
automated results matched
what experienced developers
may have written.
• Four projects accepted our
pull requests so far.
10
47. Summary & Future Work
• A refactoring tool that migrates the skeletal implementation
pattern to instead use Java 8 default methods based on
type-constraints.
11
48. Summary & Future Work
• A refactoring tool that migrates the skeletal implementation
pattern to instead use Java 8 default methods based on
type-constraints.
• Implemented as an Eclipse IDE plug-in (available at
http://cuny.is/interefact).
11
49. Summary & Future Work
• A refactoring tool that migrates the skeletal implementation
pattern to instead use Java 8 default methods based on
type-constraints.
• Implemented as an Eclipse IDE plug-in (available at
http://cuny.is/interefact).
• Evaluated using several techniques.
11
50. Summary & Future Work
• A refactoring tool that migrates the skeletal implementation
pattern to instead use Java 8 default methods based on
type-constraints.
• Implemented as an Eclipse IDE plug-in (available at
http://cuny.is/interefact).
• Evaluated using several techniques.
• In the future, composite refactorings (field encapsulation, etc.).
11
51. For Further Reading
Joshua Bloch. Effective Java. Addison Wesley, 2 edition, 2008. ISBN 0321356683.
Brian Goetz. Interface evolution via virtual extensions methods. Technical report,
Oracle Corporation, June 2011. URL http://cr.openjdk.java.net/
~briangoetz/lambda/Defender%20Methods%20v4.pdf.
Cay S. Horstmann. Java SE 8 for the Really Impatient. Addison-Wesley Professional,
2014.
Raffi Khatchadourian and Hidehiko Masuhara. Automated refactoring of legacy Java
software to default methods. In International Conference on Software Engineering,
2017.
Jens Palsberg and Michael I. Schwartzbach. Object-oriented type systems. John Wiley
and Sons Ltd., 1994. ISBN 0-471-94128-X.
Frank Tip, Robert M. Fuhrer, Adam Kieżun, Michael D. Ernst, Ittai Balaban, and Bjorn
De Sutter. Refactoring using type constraints. ACM Transactions on Programming
Languages and Systems, 2011. doi: 10.1145/1961204.1961205.
12