2005 oopsla classboxj

25
Classbox/J: Controlling the Scope of Change in Java Alexandre Bergel, Stéphane Ducasse and Oscar Nierstrasz [email protected]

Upload: bergel

Post on 18-Dec-2014

1.844 views

Category:

Business


0 download

DESCRIPTION

Unanticipated changes to complex software systems can introduce anomalies such as duplicated code, suboptimal inheritance relationships and a proliferation of run-time downcasts. Refactoring to eliminate these anomalies may not be an option, at least in certain stages of software evolution. Classboxes are modules that restrict the visibility of changes to selected clients only, thereby offering more freedom in the way unanticipated changes may be implemented, and thus reducing the need for convoluted design anomalies. In this paper we demonstrate how classboxes can be implemented in statically-typed languages like Java. We also present an extended case study of Swing, a Java GUI package built on top of AWT, and we document the ensuing anomalies that Swing introduces. We show how Classbox/J, a prototype implementation of classboxes for Java, is used to provide a cleaner implementation of Swing using local refinement rather than subclassing.

TRANSCRIPT

Page 1: 2005 Oopsla Classboxj

Classbox/J: Controlling the Scope of Change in Java

Alexandre Bergel, Stéphane Ducasse and Oscar Nierstrasz

[email protected]

Page 2: 2005 Oopsla Classboxj

Alexandre Bergel

Outline

1. AWT and Swing Anomalies

2. Classbox/J

3. Properties of Classboxes

4. Swing as a Classbox

5. Implementation

6. Conclusion

2

Page 3: 2005 Oopsla Classboxj

Alexandre Bergel

java.awt

Presentation of AWT

Component

ButtonContainerWindowFrame

• In the AWT framework:– Widgets are components (i.e., inherit from Component)– A frame is a window (Frame is a subclass of Window)

3

Page 4: 2005 Oopsla Classboxj

Alexandre Bergel

javax.swing

java.awt

Problem: Broken Inheritance in Swing

Component

ButtonContainerWindowFrame

JButton

4

JComponentJWindowJFrame

Page 5: 2005 Oopsla Classboxj

Alexandre Bergel

java.awt

Problem: Code Duplication

Component

ButtonContainerWindowFrame

javax.swing

JButton

5

accessibleContextrootPaneupdate()setLayout()...

accessibleContextrootPaneupdate()setLayout()...

accessibleContextupdate()

Code Duplication

JComponentJFrame JWindow

Page 6: 2005 Oopsla Classboxj

Alexandre Bergel

public class Container extends Component { Component components[] = new Component [0]; public Component add (Component comp) {...}}

public class JComponent extends Container { public void paintChildren (Graphics g) { for (; i>=0 ; i--) { Component comp = getComponent (i); isJComponent = (comp instanceof JComponent); ... ((JComponent) comp).getBounds(); } }}

Problem: Explicit Type Checks and Casts

6

Page 7: 2005 Oopsla Classboxj

Alexandre Bergel

We need to Support Unanticipated Changes

• AWT couldn’t be enhanced without risk of breaking existing code.

• Swing is, therefore, built on the top of AWT using subclassing.

• As a result, Swing is a big mess internally!

• We need a mechanism to support unanticipated changes.

7

Page 8: 2005 Oopsla Classboxj

Alexandre Bergel

Classbox/J

• Module system for Java allowing classes to be refined without breaking former clients.

• A classbox is like a package where:

– a class defined or imported within a classbox p can be imported by another classbox (transitive import).

– class members can be added or redefined on an imported class with the keyword refine.

– a refined method can access its original behavior using the original keyword

8

Page 9: 2005 Oopsla Classboxj

Alexandre Bergel

Refining Classes (1 / 2)

A classbox widgetsCB

package widgetsCB;

public class Component { public void update() {this.paint();} public void paint () {/*Old code*/}}

public class Button extends Component { ...}

9

Page 10: 2005 Oopsla Classboxj

Alexandre Bergel

Refining Classes (2 / 2)

Widget enhancements defined in NewWidgetsCB:

package NewWidgetsCB;import widgetsCB.Component;import widgetsCB.Button;

refine Component { /* Variable addition */

private ComponentUI lookAndFeel;

/* Redefinition of paint() */ public void paint() { /* Code that uses lookAndFeel*/ }}

10

Page 11: 2005 Oopsla Classboxj

Alexandre Bergel

Multiple Versions of Classes

NewWidgetsCBwidgetsCB

paint()update()

Component

paint()

Component

lookAndFeel

Button

Import

C class refinement

11

new Button(“Ok”).update() new Button(“Ok”).update()

Button

Page 12: 2005 Oopsla Classboxj

Alexandre Bergel

Import over InheritanceImport

12

Lookup of the update() method triggered within enhWidgetsCB. 1

NewWidgetsCBwidgetsCB

paint()update()

Component

paint()

Component

lookAndFeel

Button

C class refinement

new Button(“Ok”).update() new Button(“Ok”).update()

Button1

3

2

4

Page 13: 2005 Oopsla Classboxj

Alexandre Bergel

But update() calls paint()Import

13

Lookup of the paint() method triggered within enhWidgetsCB

1

NewWidgetsCBwidgetsCB

paint()update()

Component

paint()

Component

lookAndFeel

Button

C class refinement

new Button(“Ok”).update() new Button(“Ok”).update()

Button12

3

Page 14: 2005 Oopsla Classboxj

Alexandre Bergel

Old and New Clients at the Same TimeImport

14

OldGUIAppCB

Button OldGUIApp

NewGUIAppCB

Button NewGUIApp

NewWidgetsCBwidgetsCB

paint()update()

Component

paint()

Component

lookAndFeel

Button

C class refinement

Button

Page 15: 2005 Oopsla Classboxj

Alexandre Bergel

Properties of Classboxes

15

• Minimal extension of the Java syntax (transitive import, refine and original keywords).

• Refinements are confined to the classbox that define them and to classboxes that import refined classes.

• Method redefinitions have precedence over previous definitions.

• Classes can be refined without risk of breaking former clients.

Page 16: 2005 Oopsla Classboxj

Alexandre Bergel

Swing Refactored as a Classbox

16

AwtCB

Component

ContainerWindow

SwingCB

Component

Button

Frame WindowrootPane

setLayout()setRootPane()setContentPane()...

accessibleContextcomponent

update()add(Component)remove(Component)

FrameButton

Page 17: 2005 Oopsla Classboxj

Alexandre Bergel

Swing Refactoring

17

• 6500 lines of code refactored over 4 classes.

• Inheritance defined in AwtCB is fully preserved in SwingCB:– In SwingCB, every widget is a component (i.e., inherits from the

extended AWT Component).– The property “a frame is a window” is true in SwingCB.

• Removed duplicated code: the refined Frame is 29 % smaller than the original JFrame.

• Explicit type checks like obj instanceof JComponent and (JComponent)obj are avoided.

Page 18: 2005 Oopsla Classboxj

Alexandre Bergel

Naive Implementation

18

• Based on source code manipulation.

• The method call stack is introspected to determine the right version of a method to be triggered.

• No cost for method additions, however slowdown of 1000 times when calling a redefined method.

• However, much better results were obtained in Smalltalk. 5 byte-codes are added to redefined methods (see our previous work).

Page 19: 2005 Oopsla Classboxj

Alexandre Bergel

Conclusion

• Classboxes delimit visibility of a change and avoid impacting clients that should not be affected.

• Java is extended with two new keywords and transitive import.

• Large case study showing how classboxes can be more powerful than inheritance to support unanticipated changes.

• Performance could be improved by modifying the VM.

19

Page 20: 2005 Oopsla Classboxj

Alexandre Bergel

We need an alternative to inheritance to support unanticipated changes!

Alexandre Bergel:[email protected]

google “classboxes”

20

Page 21: 2005 Oopsla Classboxj

Alexandre Bergel

END

21

Page 22: 2005 Oopsla Classboxj

Alexandre Bergel

java.awt

A JWidget is not necessary a JComponent

Component

ButtonContainerWindowFrame

javax.swing

JComponent

JButtonJWindowJFrame

Are not subclasses of JComponent

22

Page 23: 2005 Oopsla Classboxj

Alexandre Bergel

java.awt

A JFrame is not a JWindow

Component

ButtonContainerWindowFrame

javax.swing

JComponent

JButtonJWindowJFrame

Missing inheritance link between JFrame and JWindow

23

Page 24: 2005 Oopsla Classboxj

Alexandre Bergel

AWT and Swing Anomalies

• Features defined in JWindow are duplicated in JFrame (half of JWindow code is in JFrame).

• The Swing design breaks the AWT inheritance relation:– AWT: a Window is a Component– Swing: a JWindow is not a JComponent

• Need of explicit type checks and casts in Swing:– For instance a JWindow needs to check if its elements are issued

from Swing or not before rendering them– 82 type checks (instanceof) and 151 cast to (JComponent)

24

Page 25: 2005 Oopsla Classboxj

Alexandre Bergel

Method Call Stack Introspected

NewWidgetsCB and WidgetsCB define the paint method:package WidgetsCB;public class Component { public void paint() {

if (ClassboxInfo.methodVisible ( “NewWidgetsCB”, “Component”, “paint”)){ //Enhanced paint } if (ClassboxInfo.methodVisible ( “WidgetsCB”, “Component”, “paint”)){ //Original paint }}}

25