enabling white-box reuse in a pure composition language

21
Enabling White-Box Reuse in a Pure Composition Language Andreas Schlapbach [email protected] January, 2003.

Upload: elliando-dias

Post on 14-Jul-2015

799 views

Category:

Technology


1 download

TRANSCRIPT

Enabling White-Box Reuse in aPure Composition Language

Andreas Schlapbach

[email protected]

January, 2003.

Overview

• Introduction

– Component-based software development.

– Roles of inheritance.

– Subclassing as a form of white-box reuse.

– Subclassing considered harmful.

• Goal

– To combine the power of inheritance with theease of scripting.

• Solution

– Piccola, our composition language.

– Introduce a language extension to JPiccola thatenables inheritance.

– Implementation and examples.

– Applications.

• Lessons Learned

• Questions & Comments

2

Component-based Software Development

• Modern applications must be flexible and

extendible to adapt to changing require-

ments.

• These requirements can be addressed best

by a component-oriented software devel-

opment approach.

• Component-oriented software development

shifts away from programming towards soft-

ware composition.

3

Scripting Real-World Components

• Applications = Components + Script

+ a Drop of Glue.

• We build applications by scripting compo-

nents.

• These components must adhere to a com-

positional style.

• In reality, such components often do not

exist.

� We have to adapt existing components, us-

ing a drop of glue.

4

Adaptation: Black-box versus White-box

White-box Reuse. Adapts a mismatched com-

ponent by either changing or overriding its

internal specification.

E.g.: Copy & Paste, Inheritance

Black-box Reuse. Adapts the interface of a

component only.

E.g.: Wrapping techniques, Reflective ap-

proach, Standardization

5

Roles of Inheritance

Inheritance is a key concept of object-oriented

languages and plays different roles:

Subclassing. At the implementation level, it

is a means for code reuse.

Subtyping. At the design level, it defines a

substitutability relationship.

Is-a Relationship. At the conceptual level, it

represents a conceptual specialization rela-

tionship.

These roles of inheritance can conflict.

6

Subclassing Considered Harmful

• Subclassing can break encapsulation by ac-

cessing internal implementation details of

an object.

• Subclassing introduces subtle dependencies

between base and extending classes.

• Subclassing is a white-box form of reuse.

� Let’s minimize the use of inheritance.

7

Goal: Migrate from Class Inheritance to

Object Composition

• There are many powerful object-oriented

frameworks we would like to reuse as black-

box components.

• We need inheritance to access their func-

tionality.

• Our approach is to gain access to the com-

ponents of a framework using inheritance,

wrap them and script those wrapped com-

ponents.

� We would like to have the power of inheri-

tance combined with the ease of scripting.

8

Piccola

• Piccola is a small, pure and general pur-

pose scripting language.

• Piccola is based on forms, agents and chan-

nels: Agents communicate by sending forms

along channels.

• Forms are extensible records unified with

services. Everything is a form.

• JPiccola is the Java-based implementation

of Piccola.

9

A Language Extension for JPiccola

We want to use Java frameworks in Piccola

using inheritance.

Key idea: Create Java objects implementing

a given type that delegate all calls to its meth-

ods to Piccola services.

up(args)

func(arg1, arg2,...,argn)

func(args):

...

result

Piccola

Java

down(result)

� We have to generate classes of a given type

at runtime.

10

Implementation I

The class generation process consists of three

steps:

1. Gather information on the structure of the

class.

2. Generate the class, using the BCEL byte

code engineering library.

3. Load the class into the Java Virtual Ma-

chine, using a custom class loader.

11

Structure of a Generated Class I

Let’s suppose we have class A with a methodplus(int i, int j) . We define a service plus

in Piccola to handle calls to this method.

plus(args):

’i = args.at(1)

’j = args.at(2)

i + j

We generate a subclass of A and redirect theJava call to a Piccola service:

public int plus(int j, int j) {Arguments args = new Arguments();

args.add(this);

args.add(new Integer(i));

args.add(new Integer(j));

return ((Integer) getService("plus")

.callback(args)).intValue();

}12

Structure of a Generated Class II

Actually, we generate byte code.

Method int plus(int, int)0 new #22 <Class ch.unibe.piccola.bridge.Arguments>3 dup4 invokespecial #23

<Method ch.unibe.piccola.bridge.Arguments()>7 astore 49 aload 4

11 aload_012 invokevirtual #27 <Method void add(java.lang.Object)>15 aload 417 new #56 <Class java.lang.Integer>20 dup21 iload_122 invokespecial #65 <Method java.lang.Integer(int)>25 invokevirtual #27 <Method void add(java.lang.Object)>28 aload 430 new #56 <Class java.lang.Integer>33 dup34 iload_235 invokespecial #65 <Method java.lang.Integer(int)>38 invokevirtual #27 <Method void add(java.lang.Object)>41 aload_042 ldc #75 <String "plus">44 invokevirtual #33

<Method ch.unibe.piccola.IFormgetService(java.lang.String)>

47 aload 449 invokeinterface (args 2) #39

<InterfaceMethod java.lang.Objectcallback(ch.unibe.piccola.bridge.Arguments)>

54 checkcast #56 <Class java.lang.Integer>57 invokevirtual #60 <Method int intValue()>60 ireturn

13

Example I

generateSubclassOfA():

newClass

name = "B"

superClassName = "A"

interfaceNames = [ ]

methods =

plus =

argumentTypeList =

[ Type.int, Type.int ]

returnType = Type.int

body(args): args.at(1) + args.at(2)

14

Implementation II

Often, we do not need to generate an arbitrary

class but implement an interface or generate a

direct subclass of an abstract class.

� We can use reflection to gather the infor-

mation needed to generate a class.

15

Example II

generateKeyListener():

newInterface

className = "java.awt.event.KeyListener"

methods =

keyPressed(args): println "Key Pressed"

keyReleased(args): println "Key Released"

keyTyped(args): println "Key Typed"

16

Applications

• Print Service

• Scripting an Event Based Parser

• Scripting Web Browser Frameworks

• GUI Event Composition Style

• . . .

� We use the language extension whenever we

need inheritance.

17

Role of Java Interfaces in Frameworks

• We seldom generate arbitrary classes, mostoften we just implement Java interfaces.Why is this?

• A framework consists of ready-to-use andhalf finished building blocks.

• While most parts are stable, it permits itsuser to adapt parts of it according to theirneeds. These are the hot spots of a frame-work.

• Superior to (abstract) classes, interfacesdo not impose a specific inheritance hier-archy.

� Java interfaces provide a good way to con-trol the type of adaptations compatible with aframework.

18

Closing Remarks

• The language extension integrates nicely

into JPiccola.

• Good components are hard to find.

• A framework is more than a bundle of classes.

19

Questions & Comments

20

ClassFile

ClassFile {u4 magic;u2 minor_version;u2 major_version;u2 constant_pool_count;cp_info constant_pool[constant_pool_count-1];u2 access_flags;u2 this_class;u2 super_class;u2 interfaces_count;u2 interfaces[interfaces_count];u2 fields_count;field_info fields[fields_count];u2 methods_count;method_info methods[methods_count];u2 attributes_count;attribute_info attributes[attributes_count];

}

21