Subsystems: Improved exception handling for Java (DRAFT) - PowerPoint PPT Presentation

About This Presentation
Title:

Subsystems: Improved exception handling for Java (DRAFT)

Description:

A Typical Try-Catch Pattern. class Widget { ... } class WidgetManager { int count; ... class WidgetManager { Subsystem s = Subsystem.getCurrent(); int count; ... – PowerPoint PPT presentation

Number of Views:41
Avg rating:3.0/5.0
Slides: 35
Provided by: bartj8
Category:

less

Transcript and Presenter's Notes

Title: Subsystems: Improved exception handling for Java (DRAFT)


1
Subsystems Improved exception handling for Java
(DRAFT)
  • Bart Jacobs, Frank Piessens

2
Outline
  • Try-Catch Problem Solution
  • Locking Problem Solution
  • Cancellation Problem Solution
  • Cleaning Up Problem Solution

3
Outline
  • Try-Catch Problem Solution
  • Locking Problem Solution
  • Cancellation Problem Solution
  • Cleaning Up Problem Solution

4
Problem StatementA Typical Try-Catch Pattern
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • void removeWidget(Widget w)
  • class Program
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)

This program is broken! Why?
5
Problem StatementAn OutOfMemoryError
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • void removeWidget(Widget w)
  • class Program
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)

m.count 11 m.widgets.length 10
6
Problem StatementAn OutOfMemoryError
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • void removeWidget(Widget w)
  • class Program
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)

3
4
1
2
m.count 11 m.widgets.length 10
7
Problem StatementAn OutOfMemoryError
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • void removeWidget(Widget w)
  • class Program
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)

3
4
1
2
5
m.count 12 m.widgets.length 10
8
Problem StatementA Typical Try-Catch Pattern
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • void removeWidget(Widget w)
  • class Program
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)

9
Proposed SolutionRe-entering the Owner Subsystem
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount
    2
  • System.arraycopy(widgets, 0, ws,
    0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • void removeWidget(Widget w)
  • class Program
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)

child subsystem
root subsystem
10
Proposed SolutionRe-entering an Outer Subsystem
  • class Program
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount
    2
  • System.arraycopy(widgets, 0, ws,
    0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • void removeWidget(Widget w)

11
Subsystems Basic Operation
  • class Program
  • public static void main(String args)
  • Subsystem s Subsystem.getCurrent()
  • try
  • reenter (s)
  • throw new RuntimeException()
  • catch (Throwable t)
  • System.out.println(t was
    caught.)

Not caught
12
Subsystems Basic Operation
  • class Program
  • public static void main(String args)
  • try
  • Subsystem s Subsystem.getCurrent()
  • try
  • reenter (s)
  • throw new RuntimeException()
  • catch (Throwable t)
  • System.out.println(t caught
    by inner.)
  • catch (Throwable t)
  • System.out.println(t caught by
    outer.)

Caught by outer
13
Subsystems Implementation
  • class Subsystem
  • static StackltSubsystemgt stack new
    StackltSubsystemgt()
  • static stack.push(new Subsystem()
  • Throwable exception
  • Subsystem parent
  • ListltSubsystemgt children new
    ArrayListltSubsystemgt()
  • static Subsystem getCurrent() return
    stack.peek()
  • static void enterNew()
  • Subsystem s new Subsystem()
  • s.parent getCurrent()
    getCurrent().children.add(s)
  • stack.push(s)
  • static void reenter(Subsystem s)
  • s.checkNotFailed() stack.push(s)
  • static void exit(Throwable e)
  • if (e ! null) getCurrent().setFailed(e)
  • stack.pop() getCurrent().checkNotFailed()
  • void setFailed(Throwable e)
  • Expansion try S catch (Throwable e) S
  • Subsystem.enterNew()
  • Throwable t null
  • try
  • S
  • catch (Throwable e)
  • t e
  • Subsystem.finish(t)
  • if (t ! null) Throwable e t S
  • Expansion reenter (s) S
  • Subsystem.reenter(s)
  • Throwable t null
  • try
  • S
  • catch (Throwable e)
  • t e

14
Outline
  • Try-Catch Problem Solution
  • Locking Problem Solution
  • Cancellation Problem Solution
  • Cleaning Up Problem Solution

15
Problem StatementA Typical Locking Pattern
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • synchronized void
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • new Thread()
  • public void run()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • .start()

This program is broken! Why?
16
Problem StatementAn OutOfMemoryError
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • synchronized void
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • new Thread()
  • public void run()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • .start()

In thread 1
m.count 11 m.widgets.length 10
17
Problem StatementAn OutOfMemoryError
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • synchronized void
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • new Thread()
  • public void run()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • .start()

In thread 1
In thread 2
m.count 12 m.widgets.length 10
18
Subsystems To The Rescue
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount
    2
  • System.arraycopy(widgets, 0, ws,
    0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • new Thread()
  • public void run()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • .start()

19
Subsystems To The Rescue
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount
    2
  • System.arraycopy(widgets, 0, ws,
    0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • new Thread()
  • public void run()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • .start()

In thread 1
20
Subsystems To The Rescue
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount
    2
  • System.arraycopy(widgets, 0, ws,
    0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • new Thread()
  • public void run()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • .start()

In thread 2
In thread 1
21
Subsystems To The Rescue
In main thread
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount
    2
  • System.arraycopy(widgets, 0, ws,
    0,
  • widgets.length)
  • widgets ws
  • widgetscount 1 w
  • return w
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • new Thread()
  • public void run()
  • try
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • showErrorMessage(t)
  • .start()

In thread 2
In thread 1
22
Subsystems
  • When an exception occurs in a subsystem s
  • For safety New attempts to enter s (or a
    descendant) rethrow the exception, and
  • For liveness Computations executing in s (or a
    descendant) in other threads are stopped
  • I.e. In each thread that is executing in s (or a
    descendant), an exception is thrown (using
    Thread.stop()), which is caught when leaving s

23
Outline
  • Try-Catch Problem Solution
  • Locking Problem Solution
  • Cancellation Problem Solution
  • Cleaning Up Problem Solution

24
Problem StatementA Typical Cancellation Pattern
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • ListltTaskgt tasks new ArrayListltTaskgt()
  • while (true)
  • String cmd getUserCommand()
  • if (cmd.equals(cancelAll))
  • for (Task t tasks) t.cancel()
    continue
  • final Task task new Task()
    tasks.add(task)
  • new Thread()
  • public void run()
  • try
  • task.setThread(Thread.curr
    entThread())
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • class Task
  • boolean cancel
  • Thread thread
  • synchronized void cancel()
  • cancel true if (thread ! null)
    thread.stop()
  • synchronized void setThread(Thread t)
  • thread t if (cancel) throw new
    ThreadDeath()
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,

This program is broken! Why?
25
Problem StatementA ThreadDeath
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • ListltTaskgt tasks new ArrayListltTaskgt()
  • while (true)
  • String cmd getUserCommand()
  • if (cmd.equals(cancelAll))
  • for (Task t tasks) t.cancel()
    continue
  • final Task task new Task()
    tasks.add(task)
  • new Thread()
  • public void run()
  • try
  • task.setThread(Thread.curr
    entThread())
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • class Task
  • boolean cancel
  • Thread thread
  • synchronized void cancel()
  • cancel true if (thread ! null)
    thread.stop()
  • synchronized void setThread(Thread t)
  • thread t if (cancel) throw new
    ThreadDeath()
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,

ThreadDeath in thread 1
m.count 11 m.widgets.length 10
26
Problem StatementA ThreadDeath
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • ListltTaskgt tasks new ArrayListltTaskgt()
  • while (true)
  • String cmd getUserCommand()
  • if (cmd.equals(cancelAll))
  • for (Task t tasks) t.cancel()
    continue
  • final Task task new Task()
    tasks.add(task)
  • new Thread()
  • public void run()
  • try
  • task.setThread(Thread.curr
    entThread())
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • class Task
  • boolean cancel
  • Thread thread
  • synchronized void cancel()
  • cancel true if (thread ! null)
    thread.stop()
  • synchronized void setThread(Thread t)
  • thread t if (cancel) throw new
    ThreadDeath()
  • class Widget
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,

ThreadDeath in thread 1
In thread 2
m.count 12 m.widgets.length 10
27
Proposed SolutionSubsystem Cancellation
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • ListltTaskgt tasks new ArrayListltTaskgt()
  • while (true)
  • String cmd getUserCommand()
  • if (cmd.equals(cancelAll))
  • for (Task t tasks) t.cancel()
    continue
  • final Task task new Task()
    tasks.add(task)
  • new Thread()
  • public void run()
  • try
  • task.setSubsystem(Subsyste
    m.getCurrent())
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • class Task
  • boolean cancel
  • Subsystem subsystem
  • synchronized void cancel()
  • cancel true if (subsystem ! null)
    subsystem.cancel()
  • synchronized void setSubsystem(Subsystem s)
  • subsystem s if (cancel) throw new
    ThreadDeath()
  • class Widget
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)

28
Proposed SolutionSubsystem Cancellation
  • class Program
  • public static void main(String args)
  • final WidgetManager m new
    WidgetManager()
  • ListltTaskgt tasks new ArrayListltTaskgt()
  • while (true)
  • String cmd getUserCommand()
  • if (cmd.equals(cancelAll))
  • for (Task t tasks) t.cancel()
    continue
  • final Task task new Task()
    tasks.add(task)
  • new Thread()
  • public void run()
  • try
  • task.setSubsystem(Subsyste
    m.getCurrent())
  • m.allocWidget()
  • m.removeWidget()
  • catch (Throwable t)
  • class Task
  • boolean cancel
  • Subsystem subsystem
  • synchronized void cancel()
  • cancel true if (subsystem ! null)
    subsystem.cancel()
  • synchronized void setSubsystem(Subsystem s)
  • subsystem s if (cancel) throw new
    ThreadDeath()
  • class Widget
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • synchronized Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)

(Child subsystem is cancelled)
ThreadDeath on entry to child
29
Outline
  • Try-Catch Problem Solution
  • Locking Problem Solution
  • Cancellation Problem Solution
  • Cleaning Up Problem Solution

30
Problem StatementA Typical Cleanup Pattern
  • class Widget implements Closeable
  • WidgetManager m
  • Widget(WidgetManager m) this.m m
  • public void close() m.removeWidget(this)
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • class Program
  • static Widget allocGreenWidget(WidgetManager
    m)
  • Widget w m.allocWidget()
  • w.setColor(Color.green)
  • return w
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • Widget w allocGreenWidget(m)
  • try
  • finally w.close()
  • catch (Throwable t)
  • showErrorMessage(t)

This program is broken! Why?
31
Problem StatementA StackOverflowError
  • class Widget implements Closeable
  • WidgetManager m
  • Widget(WidgetManager m) this.m m
  • public void close() m.removeWidget(this)
  • class WidgetManager
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount 2
  • System.arraycopy(widgets, 0, ws, 0,
  • widgets.length)
  • widgets ws
  • class Program
  • static Widget allocGreenWidget(WidgetManager
    m)
  • Widget w m.allocWidget()
  • w.setColor(Color.green)
  • return w
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • Widget w allocGreenWidget(m)
  • try
  • finally w.close()
  • catch (Throwable t)
  • showErrorMessage(t)

32
Proposed SolutionSubsystem Cleanup Routines
  • class Widget implements Closeable
  • Subsystem client Subsystem.getCaller()
  • WidgetManager m
  • Widget(WidgetManager m)
  • client.registerCleanup(this) this.m m
  • public void close() m.removeWidget(this)
  • class WidgetManager
  • Subsystem s Subsystem.getCurrent()
  • int count
  • Widget widgets new Widget10
  • Widget allocWidget()
  • reenter (s)
  • Widget w new Widget()
  • count
  • if (count widgets.length 1)
  • Widget ws new Widgetcount
    2
  • System.arraycopy(widgets, 0, ws,
    0,
  • class Program
  • static Widget allocGreenWidget(WidgetManager
    m)
  • Widget w m.allocWidget()
  • w.setColor(Color.green)
  • return w
  • public static void main(String args)
  • WidgetManager m new WidgetManager()
  • while (true)
  • String cmd getUserCommand()
  • try
  • Widget w allocGreenWidget(m)
  • try
  • finally w.close()
  • catch (Throwable t)
  • showErrorMessage(t)

33
Related Work(Under Construction)
  • Re-entering Similar to performing a remote
    procedure call in systems where each subsystem is
    a separate process/thread
  • Cancellation
  • Rudys, Wallach. Termination in language-based
    systems. ACM TISS 5(2), 2002.
  • Wick, Flatt. Memory accounting without
    partitions. ISMM 2004.
  • Flatt, Findler. Kill-safe synchronization
    abstractions. PLDI 2004.
  • Flatt, Findler, Krishnamurthi, Felleisen.
    Programming languages as operating systems. ICFP
    1999.
  • Subsystem cleanup stacks
  • Similar to compensation stacks in Weimer. Finding
    and preventing run-time error handling mistakes.
    OOPSLA 2004.

34
Conclusion
  • Its hard in Java to catch unchecked exceptions
    safely
  • Many (most?) existing try-catch blocks for
    unchecked exceptions are probably unsafe
  • Many synchronized blocks are probably unsafe
  • There is no easy and safe way to cancel a
    computation
  • Subsystems make it easy to fix these problems for
    the example programs
  • Future work Assess the severity of the problem
    and the effectiveness of subsystems in large
    programs
Write a Comment
User Comments (0)
About PowerShow.com