Advanced Java - Dr Fritz Solms

lightnewsSoftware and s/w Development

Nov 18, 2013 (3 years and 8 months ago)

253 views

Advanced Java
i
Advanced Java
In-depth theoretical and practical coverage for the
experienced developer
Advanced Java
ii
COLLABORATORS
TITLE:
Advanced Java
ACTION
NAME
DATE
SIGNATURE
WRITTEN BY
Fritz Solms and
Dawid Loubser
October 19,2010
REVISION HISTORY
NUMBER
DATE
DESCRIPTION
NAME
Advanced Java
iii
Contents
1 Introduction 1
1.1 Introduction......................................................1
1.2 Overview of Java...................................................1
1.2.1 Industry buy-in................................................1
1.2.1.1 Open source projects.......................................1
1.2.1.2 Job surveys............................................2
1.2.1.3 Java investment..........................................2
1.2.2 Key Features of the Java Programming Language..............................2
1.2.2.1 Java as an object-oriented programming language........................2
1.2.2.2 Java is relatively easy and intuitive................................3
1.2.2.3 Platformindependence via the Java Virtual Machine (JVM)...................3
1.2.2.4 Java as a"safe"programming language..............................3
1.2.2.5 Java’s Security Support......................................3
1.2.2.6 Multi-Threading..........................................4
1.2.2.7 Java as an extensible programming language...........................4
1.2.3 Java support technologies..........................................4
I Advanced Object-oriented software development with Java SE 5
2 Design By Contract with Java 6
2.1 Design By Contract..................................................6
2.1.1 Applicability of Design by Contract.....................................6
2.1.2 Quality and productivity...........................................6
2.1.3 Pre-conditions,post-conditions and invariants................................7
2.1.4 Example:Account..............................................7
2.1.5 Exceptions versus errors...........................................7
2.1.6 Design by contract and specialisation....................................8
2.1.7 Design by contract and implementing interfaces...............................8
2.1.8 Contracts...................................................9
2.1.8.1 Quality requirements.......................................9
Advanced Java
iv
2.1.8.2 Services without pre- and/or post conditions...........................9
2.1.8.3 An SLA for a caterer.......................................10
2.1.8.4 Always specify the contract fromthe perspective of the client..................10
2.2 Benefits of Design By Contract based software development............................11
2.3 Implementing preconditions in Java.........................................11
2.4 Implementing postconditions in Java.........................................12
2.4.1 RuntimeExceptions..............................................12
2.4.2 Assertions...................................................13
2.4.3 Ensuring that the postconditions of a superclass are met when the service is requested froma subclass..13
2.5 Implementing invariance constraints in Java.....................................13
2.5.1 Method for checking object integrity.....................................13
2.5.2 Enforcing invariance constraints on services.................................13
2.6 Exercises.......................................................13
2.6.1 A design by contract implementation for accounts..............................13
2.6.2 A design by contract implementation for credit card accounts........................14
3 UML Relationships and Java 15
3.1 Summary of UML relationships...........................................15
3.1.1 Dependency..................................................15
3.1.2 Association..................................................16
3.1.3 Aggregation..................................................16
3.1.4 Composition.................................................16
3.1.5 Realisation..................................................16
3.1.6 Specialisation.................................................16
3.1.7 Containment.................................................17
3.1.8 Shopping for relationships..........................................17
3.2 Mapping the Object-Oriented relationships onto Java...............................18
3.2.1 Standard Object Services...........................................18
3.2.1.1 Obtaining a simple String representation.............................18
3.2.1.2 Performing a logical equality test.................................18
3.2.1.2.1 Comparing attributes..................................19
3.2.1.3 Obtaining the hash code......................................20
3.2.1.4 Creating a copy (clone) of an object................................21
3.2.1.4.1 Cloning attributes....................................21
3.2.1.4.1.1 Aggregation...................................21
3.2.1.4.1.2 Composition...................................21
3.2.2 Mapping UML association relationships onto Java.............................22
3.2.3 Mapping UML association relationships onto Java.............................22
3.2.4 Mapping UML aggregation relationships onto Java.............................23
Advanced Java
v
3.2.5 Mapping UML composition relationships onto Java.............................24
3.2.6 Mapping specialization relationships onto Java...............................27
3.2.6.1 Substitutability in Java.......................................27
3.2.6.2 Polymorphismin Java.......................................28
3.2.6.3 Abstract classes in Java......................................29
3.2.6.4 Multiple inheritance in Java....................................29
3.2.6.5 Avoid overusing sub-classing...................................30
3.2.7 Mapping UML containment relationships onto Java.............................32
3.2.7.1 Containment relationship between packages...........................32
3.2.7.2 Static nested classes........................................33
3.2.7.3 Inner classes............................................34
3.2.7.3.1 Classes local to a method and anonymous inner classes................35
3.2.7.4 Nesting interfaces.........................................36
3.2.7.5 Nesting a class in an interface...................................37
3.2.8 Mapping UML interfaces onto Java.....................................38
3.2.9 Mapping UML interfaces onto Java.....................................39
3.2.10 Exposing the same object through different interfaces............................41
3.2.10.1 Mutable and Immutable views for an object...........................41
3.2.10.1.1 Example:A client with an account...........................41
3.2.10.1.2 Example:Randomone-dimensional variable......................46
II Developer tools and utilities 50
4 Apache Ant:A platform-independent automation tool 51
4.1 Introduction......................................................51
4.1.1 What is Ant?.................................................51
4.1.2 The Ant open-source project.........................................51
4.2 Installing Ant.....................................................51
4.3 The Ant vocabulary..................................................52
4.3.1 Ant projects..................................................52
4.3.2 Ant Targets..................................................52
4.3.3 Properties...................................................53
4.3.3.1 Ant Built-In Properties......................................54
4.3.4 Paths and classpaths.............................................54
4.3.4.1 Referencing paths and class paths.................................54
4.3.5 Pattern matching...............................................54
4.3.6 File sets....................................................55
4.3.7 Tasks.....................................................55
4.3.7.1 Compiling Java classes......................................56
Advanced Java
vi
4.3.7.2 Executing Java classes.......................................56
4.3.7.3 Archiving.............................................56
4.3.7.3.1 Manifest.........................................57
4.3.7.4 Creating Directories........................................57
4.3.7.5 Copying Files and Directories...................................57
4.3.7.6 Deleting Files Directories.....................................58
4.3.7.7 Checking whether a file exists...................................58
4.3.7.8 Writing to a stream(console,file,...)...............................58
4.3.7.9 Launching local executables....................................58
4.3.7.10 Conditional execution of targets..................................58
4.4 A very simple,complete example...........................................59
4.5 Writing your own Ant task..............................................60
4.5.1 Steps to extend Ant..............................................60
4.5.2 Defining a task which inserts the jar file size into the jad file........................60
4.5.3 Using a customAnt task...........................................62
4.6 Exercises.......................................................63
5 Maven 64
5.1 Introduction......................................................64
5.1.1 Guiding principles of Maven.........................................64
5.1.2 What does Maven provide?..........................................65
5.1.3 Maven versus Ant..............................................65
5.1.4 What is Maven really?............................................65
5.2 Maven’s Project Object Model (POM)........................................66
5.2.1 Introduction..................................................66
5.2.2 POMstructure................................................66
5.2.3 Project Identifiers...............................................68
5.2.3.1 Group ID..............................................68
5.2.3.2 ArtifactId.............................................68
5.2.3.3 Version...............................................68
5.2.3.4 Packaging.............................................68
5.2.4 POMinheritance...............................................69
5.2.4.1 Declaring the parent POM.....................................69
5.2.4.2 The Super POM..........................................69
5.2.4.3 The effective POM........................................70
5.2.5 Project dependencies.............................................70
5.2.5.1 Specifying project dependencies.................................70
5.2.5.1.1 Specifying version ranges................................71
5.2.5.1.2 Specifying the scope of a dependency.........................71
Advanced Java
vii
5.2.5.2 Transitive dependencies......................................72
5.2.5.3 Dependency management.....................................72
5.2.5.4 Exclusions.............................................73
5.2.6 Project modules................................................74
5.2.7 Build customization.............................................74
5.2.7.1 Customizing/configuring plugin behaviour............................75
5.2.7.2 Adding a goal to a life cycle phase................................75
5.2.8 Distribution Information...........................................77
5.2.8.1 Specifying distribution Info....................................77
5.2.8.2 Specifying login credentials....................................77
5.3 Maven’s life cycles..................................................78
5.3.1 Introduction..................................................78
5.3.2 Maven’s default build life cycle.......................................79
5.3.3 Maven’s clean life cycle...........................................80
5.3.4 Maven’s site life cycle............................................80
5.3.4.1 Default goal bindings for the site life cycle............................80
5.3.5 Package-based goal bindings.........................................81
5.3.6 Project based life cycle goals.........................................81
5.4 Executing Maven...................................................82
5.4.1 Executing a plugin goal...........................................82
5.4.2 Executing a life cycle phase.........................................82
5.5 Maven repositories..................................................82
5.5.1 Introduction..................................................82
5.5.2 Repository structure.............................................83
5.5.3 Repository locations.............................................83
5.5.3.1 Remote repositories........................................83
5.5.3.1.1 Accessing remote repositories.............................83
5.5.3.1.2 Specifying the location of remote repositories.....................83
5.5.3.2 The local repository........................................84
5.5.4 How Maven uses Respositories.......................................84
5.5.5 Repository tools...............................................84
5.6 Hello World via Maven................................................85
5.6.1 Introduction..................................................85
5.6.2 Creating a project via the Archetype plugin.................................85
5.6.3 Executing default life cycle phases......................................86
5.6.3.1 Deploying onto a server......................................86
5.6.3.1.1 Specifying distribution info...............................87
5.6.3.1.2 SSH key for login without password..........................87
5.6.3.1.3 Specifying authentication settings...........................88
Advanced Java
viii
5.6.4 Executing specific plugin goals.......................................88
5.6.4.1 Executing a programfromMaven.................................89
5.6.5 Generating documentation..........................................89
5.6.6 Cleaning the project.............................................90
5.7 Maven JAXB Sample.................................................90
5.7.1 Introduction..................................................90
5.7.2 The schema..................................................90
5.7.3 The Test Application.............................................91
5.7.4 Java-5 POM..................................................93
5.7.5 Java-6 POM..................................................94
5.7.6 Executing goals................................................96
5.8 Maven JAXWS Sample................................................96
5.8.1 Introduction..................................................96
5.8.2 Java-6 POM..................................................97
5.8.3 The Test Application.............................................98
5.8.4 Executing the web service test........................................99
6 JUnit 101
6.1 Introduction......................................................101
6.2 Writing JUnit Tests..................................................101
6.2.1 A fist JUnit example.............................................102
6.2.1.1 Writing the unit test class.....................................102
6.2.1.2 Writing test cases.........................................103
6.2.1.3 Making assertions.........................................103
6.2.1.4 Earlier versions of JUnit......................................103
6.2.2 Unit test classes................................................103
6.2.2.1 The scope of a unit test......................................103
6.2.2.2 Lifecycle annotations.......................................104
6.2.3 Test cases...................................................105
6.2.3.1 The scope of a test case......................................105
6.2.3.2 Raising exceptions.........................................105
6.2.3.2.1 Expecting exceptions..................................105
6.2.3.3 Asserting performance requirements...............................106
6.2.4 Assertions...................................................106
6.3 Running JUnit Tests..................................................107
6.3.1 Invoking JUnit through Ant.........................................108
6.3.1.1 Enabling JUnit support......................................108
6.3.1.2 Automated batch testing......................................108
6.3.1.2.1 Example implementation................................108
Advanced Java
ix
7 Using the JavaCompiler 110
7.1 Overview.......................................................110
7.2 Simple compilation..................................................110
7.3 Submitting compilation tasks.............................................111
7.3.1 Typical usage.................................................111
8 Monitoring and Managing Tools 112
8.1 Introduction......................................................112
8.2 Use cases for monitoring tools............................................112
8.2.1 Heap Memory issues.............................................112
8.2.1.1 Heap issues............................................112
8.2.1.1.1 What is the heap?....................................113
8.2.1.1.2 What is stored on the heap?...............................113
8.2.1.1.3 Causes of excessive heap usage.............................113
8.2.1.1.4 Measures which can be used to diagnose heap issues.................113
8.2.1.1.5 Potential solutions to heap problems..........................113
8.2.1.2 Thread Stack issues........................................114
8.2.1.2.1 What is the a thread stack?...............................114
8.2.1.2.2 What is stored on the stack?...............................114
8.2.1.2.3 Causes of stack issues..................................114
8.2.1.2.4 Measures used to identify stack issues.........................114
8.2.1.2.5 Possible solution for thread stack issues........................114
8.2.1.3 Thread-Local heap issues.....................................114
8.2.1.3.1 What is the Thread-Local heap.............................114
8.2.1.3.2 What is stored on the thread-local heap?........................115
8.2.1.3.3 Causes of TLH issues..................................115
8.2.1.3.4 Measures used to diagnoze TLH issues.........................115
8.2.1.3.5 Possible solution to TLH issues.............................115
8.2.2 Threading issues...............................................115
8.2.2.1 What is a thread..........................................115
8.2.2.2 Causes of thread issues......................................115
8.2.2.3 Measures used to diagnose threading issues...........................116
8.2.2.4 Possible solutions to threading issues...............................116
8.2.3 Performance issues..............................................116
8.2.3.1 Possible causes of performance problems.............................116
8.3 Java Monitoring and Management Tools.......................................117
8.3.1 The Java Project Status Tool.........................................117
8.3.2 The Java stack trace tool...........................................117
8.3.3 The Java Memory Map Tool.........................................117
8.3.4 The Java heap Analysis Tool.........................................117
8.3.5 JConsole...................................................118
Advanced Java
x
III Core Language and Platformfeatures 119
9 Basic OOwith Java:A revision 120
9.1 java.lang.Object:The root of the class hierarchy...................................120
9.1.1 The core services provided by all objects..................................120
9.1.1.1 Simple String representation via toString()............................121
9.1.1.2 Runtime type identification via getClass()............................122
9.1.1.2.1 A prelude to reflection.................................123
9.1.1.3 Logical equality test via equals().................................123
9.1.1.3.1 Overriding the equals service..............................124
9.1.1.3.2 Why is equals() important?...............................126
9.1.1.3.3 Why has equals() not been automated?.........................126
9.1.1.4 hashCode().............................................126
9.1.1.4.1 How to implement hashCode().............................127
9.1.1.5 Cloning objects..........................................128
9.1.1.5.1 Making a class cloneable................................128
9.1.1.5.2 Why not copy constructors?...............................130
9.2 Abstraction and Consistency with Interfaces.....................................131
9.2.1 Using a UML interface to specify a services contract............................131
9.2.1.1 Example:a services contract for a caterer.............................131
9.2.1.2 Example:a message sender....................................132
9.2.2 Defining an interface.............................................133
9.2.3 Implementing interfaces...........................................133
9.2.4 Using interfaces...............................................134
9.2.5 Implementing Multiple Interfaces......................................134
9.2.6 Interface Specialisation...........................................134
10 Typesafe enumerations 136
10.1 Introduction......................................................136
10.2 Defining enumerations................................................137
10.2.1 Attributes...................................................138
10.3 Using enumerations..................................................139
10.3.1 Iterating over values.............................................139
10.3.2 Comparing values..............................................139
10.4 When to use enumerated types?...........................................139
10.5 Exercises.......................................................140
11 Variable-length arguments 141
11.1 Using variable-length arguments...........................................141
11.1.1 Multiple parameters.............................................142
11.2 When to use variable-length arguments?.......................................143
11.3 VarArgs and Java reflection..............................................143
Advanced Java
xi
12 Static imports 144
12.1 Using static imports..................................................144
12.2 The Benefits of static imports.............................................145
12.3 The Drawback of static imports............................................145
12.3.1 Undermining OO...............................................145
12.3.2 Maintainability................................................145
13 Assertions 146
13.1 What is an Assertion?.................................................146
13.2 Defining Assertions..................................................146
13.2.1 Supplying information to an assertion error.................................147
13.3 Enabling and Disabling assertions..........................................147
13.3.1 Selective enabling/disabling of assertions..................................147
13.3.2 Switching assertions on/off for systemclasses................................147
13.4 An Example......................................................148
13.5 Guidelines for Using Assertions...........................................150
13.5.1 Use assertions liberally............................................150
13.5.2 Systems should not recover froman assertion failure............................150
13.5.3 Don’t be concerned if the assertion test is expensive............................151
13.5.4 Do not use assertions to check method arguments..............................151
13.5.5 Assertions should be transparent to the programstate............................151
14 Java Beans 152
14.1 Implementing basic JavaBeans............................................152
14.1.1 Referring to properties............................................153
14.2 Implementing observable JavaBeans.........................................153
14.2.1 The observer pattern.............................................153
14.2.2 The JavaBeans observer framework.....................................154
14.2.3 How to create observable JavaBeans.....................................155
14.2.4 Example of an observable JavaBean.....................................155
14.2.5 Shortcomings in the JavaBeans framework.................................160
14.2.6 Exercises...................................................160
15 Generic types 161
15.1 Introduction......................................................161
15.1.1 Generics versus interfaces..........................................161
15.2 Defining generic classes...............................................162
15.3 Using generic classes.................................................163
15.4 Defining generic interfaces..............................................164
15.4.1 A generic class implementing a generic interface..............................165
Advanced Java
xii
15.4.2 A concrete class implementing a generic interface..............................165
15.5 Generics in the Java Collections framework.....................................165
15.6 Multiple type parameters...............................................165
15.7 Bounded type parameters...............................................166
15.8 Generic methods...................................................166
15.8.1 Generic constructors.............................................167
15.9 Wild card parameter types..............................................168
15.9.1 Bounded wild card parameters........................................168
15.10Erasure........................................................169
15.10.1 How does the compiler handle type parameters?...............................169
15.10.2 Consequences of erasure...........................................169
15.10.2.1 Cannot instantiate template type.................................169
15.10.2.2 Cast to and use as raw type....................................170
15.10.2.3 Ambiguity errors.........................................170
15.10.2.4 Unable to reflect upon.......................................172
15.11Limitations on the use of type parameters......................................172
15.11.1 Cannot use constructors to instantiate parameterised types.........................172
15.11.2 Cannot instantiate an array of parameterised type elements.........................172
15.11.3 No generic throwables............................................172
15.11.4 Static members of a class may not use type parameters...........................173
15.12Example:A generic resource pool..........................................173
15.12.1 The prototype interface............................................173
15.12.2 The resource pool contract..........................................174
15.12.3 An implementation for a basic resource pool................................174
15.12.4 Using the basic resource pool........................................176
15.13Exercises.......................................................178
16 Metadata via annotations 179
16.1 Introduction......................................................179
16.1.1 Why would one want to use annotations?..................................179
16.1.2 Example uses of annotations.........................................179
16.2 Defining annotations.................................................180
16.2.1 Specifying annotation parameters......................................180
16.2.2 Annotating annotations............................................181
16.2.2.1 Restricting annotation targets...................................181
16.2.2.1.1 Legal restriction targets.................................182
16.2.2.2 Specifying the life span of an annotation.............................182
16.2.2.3 Specifying that the annotation should be inherited........................183
16.2.2.4 Publishing annotations in generated documentation.......................183
Advanced Java
xiii
16.3 Reflecting on annotations...............................................183
16.4 Example:A ToDo annotation.............................................184
16.4.1 ToDo.java...................................................184
16.4.2 Person.java..................................................184
16.4.3 Reflecting on the annotation.........................................185
17 Annotation processors 188
17.1 Overview.......................................................188
17.1.1 Processing annotations at class or instance level...............................188
17.1.2 What are annotation processors used for?..................................188
17.2 Example........................................................189
17.2.1 The Annotation processor..........................................189
17.2.2 The unit test for the annotation processor..................................190
17.3 Standard annotations.................................................192
17.4 Exercises.......................................................192
18 Using Regular Expressions within Java 194
18.1 Introduction......................................................194
18.2 Regular expressions..................................................194
18.2.1 Matching on characters by defining a character class............................194
18.2.1.1 Matching on a range of characters.................................195
18.2.1.2 Excluding certain characters....................................195
18.2.1.3 Matching on any character....................................195
18.2.1.4 Escaped characters.........................................196
18.2.1.5 Pre-defined character classes...................................196
18.2.2 Multiplicity constraints............................................196
18.2.3 Positional characters.............................................197
18.2.4 Optional matches and groupings.......................................197
18.2.5 Greedy versus non-greedy matching.....................................197
18.3 Regular expressions support built-in to java.lang.String...............................198
18.3.1 Testing whether a String matches a pattern.................................198
18.3.2 Replacing patterns..............................................198
18.3.3 Splitting a String around a regular expression................................199
18.4 Regular expressions support through patterns and matchers.............................199
18.4.1 Patterns....................................................200
18.4.1.1 Creating case-insensitive patterns.................................200
18.4.2 Matchers...................................................200
18.4.2.1 Testing whether the whole input string matches the pattern...................200
18.4.2.2 Finding matching occurrences in an input string.........................201
Advanced Java
xiv
18.4.2.2.1 Using capturing groups.................................201
18.4.2.3 Iteratively replacing matches...................................202
18.5 Using regular expressions with files.........................................203
18.6 Exercises.......................................................204
18.6.1 E-Mail address filter.............................................204
18.6.2 Find TODO tags...............................................204
19 Multithreading with Java 206
19.1 Introduction......................................................206
19.2 SystemIssues.....................................................206
19.2.1 Concurrency versus Parallelism.......................................206
19.2.2 Processes versus Threads...........................................207
19.2.3 Cooperative versus Preemptive Systems...................................207
19.2.4 Priority Mappings..............................................207
19.2.5 Atomicity...................................................207
19.2.6 Lessons fromSystemIssues.........................................207
19.3 Creating and Starting Threads............................................208
19.3.1 Introducing Java Threads...........................................208
19.3.2 Supporting Cooperative Thread Schedulers.................................209
19.3.3 Thread Objects are not Threads.......................................211
19.3.4 Using the java.lang.Runnable interface...................................211
19.3.5 Daemon Threads...............................................212
19.4 Thread Priorities...................................................213
19.5 Forcing your Threads to cooperate..........................................213
19.6 Monitors and Mutexes................................................214
19.6.1 Java’s Monitors................................................214
19.6.2 A Thread Requesting an Object’s Monitor for a Block of Code.......................216
19.7 Inter-Thread Communication.............................................216
19.7.1 Communicating via wait() and notify()...................................216
19.7.2 Communication via Piped Streams......................................219
19.8 Common Problems and some Solutions.......................................220
19.8.1 Killing and Suspending Threads Gracefully.................................220
19.8.2 Be Responsible when you go to Sleep....................................222
19.8.3 Race Conditions...............................................222
19.8.4 Deadlocks...................................................224
19.8.4.1 When Can Dead Locks Occur?..................................226
19.8.4.2 Avoiding Deadlocks through acquiring only one monitor at a time................226
19.8.4.3 Avoiding Deadlocks through Resource Ordering.........................226
19.9 Java’s Concurrency Utilities framework.......................................228
Advanced Java
xv
19.9.1 Executors...................................................228
19.9.1.1 The executor interface.......................................228
19.9.1.2 Using executors..........................................229
19.9.1.3 Basic executors..........................................229
19.9.1.3.1 An executor which executes tasks sequentially.....................229
19.9.1.3.2 An executor which executes each task in a separate thread...............229
19.9.1.4 Executor service..........................................229
19.9.1.4.1 Task termination.....................................230
19.9.1.4.2 Deferred synchronous requests.............................230
19.9.1.4.2.1 Callable.....................................231
19.9.1.4.2.2 Future......................................231
19.9.1.4.2.3 Invoking deferred synchronous requests....................232
19.9.1.5 Thread pooling...........................................233
19.9.1.5.1 ThreadPoolExecutor..................................233
19.9.1.5.1.1 Thread pool parameters.............................233
19.9.1.5.1.2 Thread pool services..............................233
19.9.1.5.1.3 On demand verus up-front construction....................234
19.9.1.5.1.4 Interception...................................234
19.9.1.6 Scheduling.............................................234
19.9.1.6.1 Fixed rate versus fixed delay scheduling........................234
19.9.1.6.2 The ScheduledExecutorService.............................234
19.9.2 Lock classes.................................................235
19.9.2.1 Benefits of using lock classes over synchronization.......................235
19.9.2.2 Locks...............................................236
19.9.2.3 Using locks............................................237
19.9.2.4 Reentrant locks..........................................237
19.9.2.5 Read and write locks.......................................237
19.9.2.6 Conditions.............................................238
19.9.2.6.1 Using conditions....................................238
19.9.2.6.1.1 Spin locks....................................238
19.9.3 Concurrent collections............................................238
19.9.3.1 Concurrent maps..........................................238
19.9.3.2 Copy-on-write collections.....................................239
19.9.3.3 Blocking queues..........................................239
Advanced Java
xvi
IV Frameworks 240
20 Streaming Input/Output with Java 241
20.1 Overview of Java’s I/O Libraries...........................................241
20.2 Basic Byte I/O.....................................................242
20.2.1 InputStream..................................................242
20.2.2 OutputStream.................................................242
20.2.3 Copying a file byte-for-byte.........................................243
20.2.4 Buffering for Performance..........................................244
20.2.4.1 What is Buffering?.........................................244
20.2.4.2 Applying (and measuring the effects of) Buffering........................244
20.3 Working with Files in Java..............................................248
20.3.1 File Streams.................................................248
20.3.1.1 Writing data to a file........................................249
20.3.2 The java.io.File class.............................................249
20.3.2.1 Printing a Directory Tree.....................................249
20.4 Data streams for I/O with Java Primitive Types...................................251
20.4.1 Reading Primitive Types (java.io.DataInputStream).............................251
20.4.2 Writing Primitive Types (java.io.DataOutputStream)............................252
20.4.3 Reading/Writing Strings with Data Streams................................252
20.4.4 Example usage of Data streams:Product Inventory.............................252
20.5 Object Serialization..................................................261
20.5.1 Non-serializable attributes..........................................263
20.6 I/O Exercises.....................................................263
21 NIO(New IO) 264
21.1 Introduction to NIO..................................................264
21.2 Comparison to Stream-based IO...........................................264
21.2.1 Disadvantages................................................264
21.2.2 Advantages..................................................265
21.3 NIO Buffers......................................................265
21.3.1 Introduction..................................................265
21.3.2 Using Buffers.................................................266
21.3.2.1 Creating Buffers..........................................266
21.3.2.2 Reading and Writing Buffers...................................266
21.3.2.3 Accessing the bytes in a buffer..................................268
21.4 NIO Channels.....................................................268
21.4.1 Introduction..................................................268
21.4.2 Types of Channels..............................................269
Advanced Java
xvii
21.4.3 The Lifecycle of a Channel..........................................269
21.4.4 Scattering reads and gathering writes....................................270
21.4.5 File Channels.................................................271
21.4.5.1 Why file channels?........................................271
21.4.5.2 When are File Channels useful?..................................273
21.4.5.3 Creating File Channels......................................274
21.4.5.3.1 Read-only mode.....................................274
21.4.5.3.2 Write-only mode....................................274
21.4.5.3.3 Read/Write mode....................................274
21.4.5.4 Direct Channel Data Transfer...................................274
21.4.5.5 Memory-Mapping Files......................................275
21.4.5.6 Basic FileChannel Exercises...................................276
21.4.5.6.1 Buffer Re-use......................................276
21.4.5.6.2 File Doubler.......................................276
21.4.5.6.3 Sound file amplification.................................277
21.5 Character Sets.....................................................277
21.5.1 Introduction..................................................277
21.5.2 Why the need for Character Sets?......................................277
22 Java Scripting Support 279
22.1 Overview of Java Scripting..............................................279
22.1.1 Typical uses of Java Scripting........................................279
22.1.1.1 Using task specific languages for specific tasks..........................279
22.1.1.2 Making your applications user extensible and customizable...................280
22.1.1.3 Use Java Scripting to provie a command interface to an application...............280
22.1.2 The scripting framework...........................................280
22.1.2.1 Scripting interfaces........................................280
22.1.2.2 Scripting framework classes....................................281
22.2 Scripting engines...................................................281
22.2.1 The Java Scripting project..........................................281
22.2.2 Installing support for a scripting language..................................281
22.2.3 Listing the available scripting engines....................................282
22.2.4 Using scripting engines............................................283
22.2.4.1 Example usages of scripting engines...............................283
22.2.4.1.1 JavaScript HelloWorld.................................283
22.2.4.1.2 Apache Velocity HelloWorld..............................283
22.2.4.1.3 Basic JEP example...................................284
22.2.4.1.4 Basic Jaskell example..................................285
Advanced Java
xviii
V Persistence via the Java Persistence API (JPA) 287
23 JPA overview 288
23.1 What is JPA?.....................................................288
23.2 What does JPA provide?...............................................288
23.3 JPA providers.....................................................288
24 Persistence contexts 289
24.1 Overview persistence contexts............................................289
24.1.1 What is a persistence context?........................................289
24.1.2 What is an entity manager?..........................................289
24.1.3 Optimistic concurrency control........................................289
24.1.4 The life span of an entity manager......................................290
24.1.4.1 Transaction-scoped persistence contexts.............................290
24.1.4.2 Extended persistence contexts...................................290
24.1.5 The transaction management for a persistence context...........................290
24.1.6 The scope of a persistence context......................................290
24.1.7 How are entity managers obtained?.....................................291
24.1.7.1 Obtaining an entity manager in a container managed environment................291
24.1.7.2 Manual creation of an entity manager in a JavaSE application..................291
24.1.8 Detaching objects froma persistence context................................292
24.2 Persistence context configuration...........................................292
24.2.1 Typical persistence context for non-managed Java applications.......................292
24.2.2 Typical persistence context for managed applications............................292
25 Entities 294
25.1 Overview.......................................................294
25.2 Simple entities....................................................294
25.2.1 Declaring an entity..............................................294
25.2.2 Requirements for entities...........................................294
25.2.3 What is persisted?..............................................295
25.2.3.1 Valid persistent field types.....................................296
25.2.3.2 Collection variables........................................297
25.2.3.3 Transient fields..........................................297
25.2.3.4 Field validation..........................................297
25.2.4 Embedded classes..............................................297
25.2.4.1 Defining an embeddable class...................................298
25.2.4.1.1 Specifying the access type...............................298
25.2.4.2 Embedding and embeddable class within an entity........................298
25.2.5 Primary keys.................................................298
Advanced Java
xix
25.2.5.1 Simple primary keys........................................298
25.2.5.1.1 Valid types for simple primary keys..........................299
25.2.5.1.2 Specifying the primary key field............................299
25.2.5.1.3 Automatically generating primary keys.........................299
25.2.5.2 Primary key classes (composite keys)...............................300
25.2.5.2.1 Interface for the primary key class...........................300
25.2.5.2.2 Implementation of a primary key class.........................300
25.2.5.2.3 Entity bean using the primary key class........................301
25.2.6 Specifying column mappings.........................................301
25.2.7 Column constraints..............................................302
25.2.8 Primitive collections and maps........................................302
25.3 Relationships.....................................................302
25.3.1 Summary of UML relationships.......................................303
25.3.1.1 Dependency............................................303
25.3.1.2 Association............................................303
25.3.1.3 Aggregation............................................304
25.3.1.4 Composition............................................304
25.3.1.5 Realisation.............................................304
25.3.1.6 Specialisation...........................................304
25.3.1.7 Containment............................................304
25.3.1.8 Shopping for relationships.....................................305
25.3.2 Composition between entity beans......................................305
25.3.3 Relationship types..............................................305
25.3.3.1 Relationship owner........................................306
25.3.3.2 Unidirectional single-valued relationships............................306
25.3.3.3 Bidirectional one-to-one relationships..............................306
25.3.3.4 Bidirectional many-to-one relationships.............................307
25.3.3.5 Cascading Operations.......................................308
25.3.4 Fetching strategies..............................................309
25.3.4.1 Eager fetching...........................................309
25.3.4.2 Defaults fetching strategies....................................309
25.3.5 Specialization relationships.........................................309
25.3.5.1 Mapping onto relational databases................................310
25.3.5.2 Joined subclass..........................................310
25.3.5.3 Single table per class hierarchy..................................310
25.3.5.4 Single table per class.......................................310
Advanced Java
xx
26 The Java Persistence Query Language (JPQL) 312
26.1 Introduction......................................................312
26.2 JPQL versus SQL...................................................312
26.2.1 Result Collections in JPQL..........................................312
26.2.2 Selecting entity Attributes..........................................313
26.3 JPQL statement types.................................................313
26.3.1 Elements of query statements........................................313
26.3.2 Elements of Update and delete statements..................................313
26.4 Polymorphism.....................................................314
26.5 Navigating object graphs...............................................314
26.5.1 Simple paths.................................................314
26.5.2 Single-Valued versus Multi-Valued Paths..................................315
26.6 Specifying the source of a query...........................................316
26.6.1 Selecing frommultiple domains.......................................316
26.6.2 Joins.....................................................316
26.6.2.1 Inner joins.............................................316
26.6.2.1.1 Implicit inner joins...................................316
26.6.2.1.2 Explicit inner joins...................................316
26.6.2.2 Left outer joins..........................................317
26.7 Collapsing Multi-Valued Paths into Single-Valued Paths via Collection Variables.................317
26.8 Constraining a result set via a WHERE clause....................................317
26.8.1 Comparison operators which can be used in WHERE clauses........................317
26.8.2 Calculation and string operators.......................................318
26.8.3 Using collection variables in WHERE clauses................................318
26.9 Constructing result objects..............................................318
26.10Nested queries.....................................................318
26.11Ordering........................................................319
26.12Grouping.......................................................319
26.13The Java Persistence Query Language (JPQL)....................................319
26.13.1 Positional parameters.............................................319
26.13.2 Named parameters..............................................319
27 Constructing and executing queries 320
27.1 Named queries....................................................320
28 Index 321
Advanced Java
xxi
List of Figures
2.1 Pre- and post-conditions and invariance constraints for an account..........................7
2.2 Applying design by contract rules for specialisation..................................8
2.3............................................................9
2.4 The Service Level Agreement (SLA) for a caterer..................................10
3.1 Summary of UML relationships...........................................15
3.2 A client has accounts via aggregation.........................................23
3.3 An account has a balance via composition......................................25
3.4 A simple example of a UML specialization relationship...............................27
3.5 An abstract graphics object class...........................................29
3.6 Mapping multiple inheritance relationships onto Java................................30
3.7 A class hierarchy for persons.............................................31
3.8 Using aggregation and interfaces for person roles and employee responsibilities..................31
3.9 A class hierarchy for accounts............................................32
3.10 Using a delegation based model for accounts.....................................32
3.11 The accounts package is contained within the finance package...........................33
3.12 Concrete single and double precision implementation classes nested in an abstract superclass...........33
3.13 A linked list using inner classes for nodes and its iterator implementation.....................34
3.14 Read-only and read-write interface for cheque class.................................36
3.15 Nesting classes within an interface..........................................37
3.16............................................................38
3.17............................................................39
5.1 The structure of Maven’s POM............................................67
9.1 The basic object services (java.lang.Object).....................................121
9.2 Making java objects cloneable............................................128
9.3 Shallow vs Deep copy when cloning objects.....................................129
9.4 A simple services contract for a caterer........................................132
9.5 A services contract for a message sender.......................................133
10.1 A simple enumeration (months)...........................................136
Advanced Java
xxii
14.1 Simple JavaBeans representation...........................................153
14.2 Structure of the observer design pattern.......................................154
14.3 The JavaBeans observability framework.......................................155
14.4 Example of observable Java Bean..........................................160
19.1 Resource ordering...................................................226
20.1 Conceptual Example of StreamChaining.......................................241
20.2 Basic Byte I/O.....................................................242
20.3 Output for Printing a Directory Tree.........................................251
20.4 The static model for our Inventory application....................................252
20.5 Serialization test programoutput...........................................263
21.1 Java NIO Buffer Types................................................266
21.2 A newly created Buffer................................................267
21.3 Data written to a Buffer................................................267
21.4 Flipped Buffer.....................................................268
21.5 Java NIO Channels..................................................269
25.1 Summary of UML relationships...........................................303
25.2 A unidirectional one-to-one relationship.......................................306
25.3 A bidirectional one-to-one relationship........................................307
25.4 A bidirectional many-to-one relationship.......................................308
26.1 UML class diagramfor a bond............................................314
26.2 UML class diagramfor presentations of courses for a course schedule.......................315
Advanced Java
xxiii
List of Tables
18.1 Regular expressions pre-defined character classes..................................196
18.2 Multiplicity constraints supported by regular expressions..............................196
Advanced Java
1/321
Chapter 1
Introduction
1.1 Introduction
These notes are for the Java Developer who is comfortable with the basic aspects of object-orientation (specialisation,contracts
/interfaces,polymorphism) and their implementation in the Java programming language.It also assumes comfortable knowl-
edge of some of the basic Java SE frameworks,such as Streaming I/O,the Collections framework,and Swing (graphical user
interfaces).
Without targeting any specific Java platform(such as Java EE or Java ME) this course attempts to enrich the developer’s knowl-
edge by covering further standard frameworks and technologies (such as Java Annotations,Generic types,Multi-threading with
the Java 5 Concurrency framework,high-performance I/O with the NIO framework,etc).
Also covered are distributed computing technologies such as RMI and CORBA,as well as JNDI,and basic networking.
The developer’s conceptual knowledge is enriched by gaining a solid understanding of design-by-contract (and its Java imple-
mentation) as well as advanced object-oriented implementations in Java,such as mapping UML relations to Java code.
We cover the concepts in a manner which does not try to hide their complexity or implementation behind all-encompassing
developer tools,with the realisation that - in practice - developers need to use all the tools that they can in order to maintain
productivity.We emphasise conceptual completeness - these notes do not serve as an exhaustive API reference,and consequently
the standard documentation should always be at hand when writing Java software.
1.2 Overview of Java
1.2.1 Industry buy-in
Java has become the most widely used programming language in for many application areas ranging from
• card development to
• mobile devices applications to
• desktop applications to
• enterprise applications.
1.2.1.1 Open source projects
Even though C and C++ have a long history of open source projects,as of 2006,http://sourceforge.net hosts more
open source projects in Java than in any other programming language.
Advanced Java
2/321
1.2.1.2 Job surveys
When considering job-listing publications,one typically finds that there are more positions available requiring knowledge of
Java,than for any other language.The latest statistics frommonstor.com show that there are about
• 30%more jobs requesting Java skills than what there are for C/C++ skills,
• About 2.5 times more Java positions than Visual Basic positions,
• About 3 times more Java positions than C#positions.
(The above are rough averages for jobs available globally.)
1.2.1.3 Java investment
The Financial Express did a study in April 2005 which quoted the following investment statistics in the Java technologies:
• Java is currently driving more than $100 billion of business annually.
• Java mobile game market is estimated to be around $3 billion.
• Seven out of 10 wireless applications currently under constructions will use Java technology.
• On the enterprise side,$2.2 billion in Java application server and $110 billion in related IT spendings are happening.
• Java has a global development community of over 4.5 million software developers.
• Along with that,100 carrier deployments and 579 million phones are on this platform.
• Around 750 million Java cards have been deployed globally.
1.2.2 Key Features of the Java Programming Language
The Java programming language has a range of features which make it suitable as a powerful and general object-oriented pro-
gramming language.Unlike most other languages,these features form an integral part of the standard Java platform (and not
as optional or third-party additions).This means that,using Java,you are immediately ready to tackle most computing tasks
conceivable.
1.2.2.1 Java as an object-oriented programming language
Java is a clean,robust object-oriented language with good support for most object-oriented concepts (with the notable exception
of multiple inheritance - omitted for reasons of complexity).
The following is directly supported:
• Dependency and Association relationships
• Specialisation
• Interfaces (the cornerstone of contract-driven design)
• Polymorphism (substitutability)
• Exceptions (a consistent error-handling mechanism,and also an important part of contract-driven design)
• Generics (parameterised classes)
Java has support for specialisation and association relationships,as well as interfaces,polymorphism,exception handling,inner
and static nested classes and generics or parametrized classes.
Though no known object-oriented language natively supports the behaviour of the other two key UML relationships,Aggregation
and Composition,Java language is flexible enough (in no small part because of the metadata capabilities provided by Annotations)
to make this behaviour possible,either by manual implementation,or through automatic code-generation frameworks).
Advanced Java
3/321
1.2.2.2 Java is relatively easy and intuitive
The core Java programming language is easy to learn.Once the basic object-oriented concepts have been acquired,Java is very
intuitive and consistent.This is unlike a language such as C++,which requires a much higher level of technical skill.
Apart from the core language,the typical standard frameworks (such as Java EE,used for enterprise development) have been
designed with consistency and simplicity in mind.They generally leave all the hard work to the runtime environment,and not to
the developer.
1.2.2.3 Platformindependence via the Java Virtual Machine (JVM)
One of Java’s greatest strengths is it’s platformindependence.Compiled Java software can be moved and deployed across various
different operating environments (Linux,Mac OS X,Microsoft Windows,BSD) as well as typically across different computing
devices (Desktop,Server,Mainframe,Cellular Telephone,Internet-enabled Fridge,and so forth.
This is made possible by the Java Virtual Machine,which is responsible for loading and running the compiled,platform inde-
pendent code.This is typically done either by interpreting the code in real-time (mapping the platform-independent code onto
native,machine-specific code) or,more commonly,by using a Just-In-Time compiler to compile Java code to native code as it is
loaded (with immense performance benefits).
The Java Virtual Machine not only provides the support for processes like Garbage collection (automatic memory management)
and security,but also contains all the standard class libraries.These class libraries form the standard operating environment for
any Java-based application,and provide an unprecedented degree of functionality.
1.2.2.4 Java as a"safe"programming language
In languages such as C and C++,the developer is fully responsible for allocating and freeing computer memory for every object
he creates,a delicate and error-prone task (with so-called ‘memory leaks’ having the capability to bring down entire applications
or event the operating system).In Java,the process knowns as Garbage Collection completely and automatically manages
memory.This significantly contributus to the fact that languages such as C are almost never used for business applications,as the
complexity would be overwhelming.
In this spirit,Java does not have pointers (which can access arbitrarily access memory),but rather references.They are guaranteed
to access only memory which they should access (i.e.which contains valid Java objects).All the traditional ‘unsafe’ structures,
such as Arrays and character strings,are implemented in Java as first-class objects,with bounds checking to prevent any type of
out-of-range memory access.It is thus impossible for applications to interfere with each other at a memory-access level.
1.2.2.5 Java’s Security Support
Java has sophisticated,fine-grained support for security on nearly all conceivable fronts.It provides the means to ensure
• Confidentiality of transferred information via encryption.
• Integrity of transferred information via message digestion.
• Authentication via digitally signed certificates generated using private keys and decoded via public keys.
• Fine grained Access Control to any protected resources via permissions.
• Non-repudiation with digital signatures.
These security features are applied accordingly throughout all the (especially networked) Java frameworks,such as Java WebStart,
Java Applets,Java EE,etc.They,together with the containment provided by the Java Runtime Environment,means that to date
no general-purpose virii,‘worms’,or malicious software has ever been successfully written and distributed through Java.Though
claims of a virus implemented in Java do appear from time to time,upon closer inspection,they inevitably function only when
the user explicitly runs them,and in an environment where the user explicitly allows these programs access to the areas which
they attempt to compromise.(i.e.not in a typical Java Sandbox environment).
Advanced Java
4/321
1.2.2.6 Multi-Threading
Multi-threading is the ability of a system to give the illusion that it is performing more than one task simultaneously in multiple
threads of execution.This,for example,enables your e-mail application to retrieve new mail in the background,as you are busy
writing an e-mail to your mother.As soon as the picture (which is busy being downloaded from your digital camera,for editing
in the already-running GIMP application) is ready and attached to the e-mail,you will send the e-mail,and crank up the volume
in iTunes as you switch back to your Eclipse IDE to write some more Java code.
Java is unique among programming languages for the excellent threading support contained in the core language.Most non-
trivial applications should be multi-threaded,and it is a big advantage that well-written,multi-threaded Java applications can
also be fully portable across operating environments.
Though the core language contained extensive threading capabilities since its inception,Java 5 added a whole new class of safe,
friendly,and efficient threading utilities,known as the concurrency framework.This framework is very developer-oriented,and
simplifies most multi-threading tasks.
1.2.2.7 Java as an extensible programming language
Java contains several features to make it easy to extend and augment the typical manner in which it is uses,such as fully pluggable
compiler and classloading APIs,and annotations.Annotations are a sophisticated meta-data facility,and through them you can
‘extend’ the language itself,by making use of (or writing your own) frameworks that exhibit behaviour based on the annotations
in the objects it works with.These extensions are typically examined at run-time (using Java Reflection),or processed at either
the pre-compiler stage,or at byte code level via a specific class loader.The possibilities are,quite literally,endless.
1.2.3 Java support technologies
Even more so than the core language,the reason for Java’s dominance lies mostly in the vast range of support technologies
available.These include
• dedicated support across a very wide range of platforms,ranging from cards to mobile devices to desktops up to enterprise
systems,
• Java EE,which addresses the quality requirements like scalability,reliability,security,and transaction support required for
most enterprise systems,together with separation of the presentation,application logic,domain objects and infrastructure
layers,
• support for services oriented architectures (SOA) and enterprise services bus (ESB) through a wide range of Java based vendor
solutions together with an open community standard (JBI) for services oriented architectures,
• excellent standards based integration support including
– CORBA as a public standard for object oriented integration,
– web services for services-oriented integration,
– XML bindings for XML based integration,
– connectors for managed integration via proprietary protocols supporting transaction and security context propagation,and
– good support for messaging.
• support for persistence ranging from Java SQL wrappers (JDBC) to object-relational mappers (e.g.Hibernate) to managed
entity objects (e.g.entity beans in EJB) and object data bases,
• support for graphics,media and gaming ranging from the Java Media framework (JMF),to extensive 2D and 3D graphics
libraries,gaming engines,and low-level OpenGL graphics support.
• standard tools and frameworks for developer productivity,such as a range of excellent open-source IDEs (Integrated Develop-
ment Environments),automatic build tools such as Ant,and standard logging and testing frameworks.
Advanced Java
5/321
Part I
Advanced Object-oriented software
development with Java SE
Advanced Java
6/321
Chapter 2
Design By Contract with Java
Contract-based software development facilitates testability and safe plug-ability.Most good design processes (such as URDAD)
produce contracts as the first deliverable for each level of granularity of your system.
If there were no contracts for your components and service providers,what would you testing?Would you be willing to plug in
a service provider which does not guarantee that a service contract is fulfilled?Though Java does not directly support all design-
by-contract features (as language keywords),the approach can still strictly be followed.This results in modularised,testable
code that is easy to maintain with confidence.
2.1 Design By Contract
Design by Contract is a design technique introduced in 1986 by Bertrand Meyer for developing quality software based on formal
contractual requirements which are testable and validated in code.Bertrand Meyer went on to make design by contract an integral
part of the Eiffel programming language.
2.1.1 Applicability of Design by Contract
Even though Design by Contract was originally a concept developed for software design,it is now commonly applied across
various design fields covering software,hardware and business process design.
2.1.2 Quality and productivity
K.Fujino’s quote,
when quality is pursued,productivity follows
has become a widely accepted mantra.
In other words,it is been proven unwise to believe that
• your deadlines are too pressing to follow a quality-driven approach like design-by-contract,
but rather that
• you cannot afford not to follow a quality driven approach with pressing deadlines.
Most enterprise reference architectures,be it a component infrastructure like Enterprise JavaBeans,or an integration infrastruc-
ture like Services-Oriented Architecture,in fact enforce a design-by-contract approach.
Advanced Java
7/321
2.1.3 Pre-conditions,post-conditions and invariants
Design by contract is based on the premise that the functional requirements for a service provider can be specified by defining
the interface for the service provider together with pre-and post conditions for each service,and optionally invariance constraints
for the service provider as a whole.
1.Preconditions The preconditions are those conditions under which a service provider may refuse the service without
breaking the contract.
Note
Service providers would typically raise a signal (throw an exception) to notify the client that a requested service is not
being provided because some pre-condition is not met.
2.Post-conditions The post conditions are those conditions which must hold after successful realization of the service.
3.Invariance constraints The invariance constraints are rules that must always hold for the object (providing the service)
to be in a valid state -- it must be satisfied before the service is requested as well as after the service has been rendered or
refused.
2.1.4 Example:Account
As an example,consider an account.The invariance constraints which must apply for the account to be in a valid state are that
the sum of the credits minus the sum of the debits must always yield the account’s balance.A precondition for the debit service
is that there are sufficient funds -- if there are insufficient funds the account may refuse the service without breaking the contract.
Post conditions for the debit service may be that the amount is subtracted from the balance and that the transaction has been
inserted into the transaction history.The credit service,on the other hand,needs to be provided unconditionally while the post
conditions of the credit service are similar to those of the debit service,just that the amount must be added to the balance.
Figure 2.1:Pre- and post-conditions and invariance constraints for an account.
2.1.5 Exceptions versus errors
An exception is raised when a service provider refuses a service due to a precondition not being met.This is a scenario where
the service provider may refuse the service without breaking the contract.It does thus not present an error - the system is not in
an inconsistent state,and it may continue operating normally.
If,on the other hand,all preconditions are met and the service provider is still unable to realise the service such that all post-
conditions will be met and that no invariance constraints will be violated,then the server may want to acknowledge to the client
that the contractual obligations cannot be met by raising an error.
Advanced Java
8/321
2.1.6 Design by contract and specialisation
When,for example,defining an Account sub-class such as CreditCardAccount (which defines a different business process for
the debit service) one needs to take into account the following:
• Instances of sub-class must provide the service under no more preconditions than the super-class,i.e.the service may not be
refused for any other reasons than that there are insufficient funds,though insufficient funds itself may arise under different
conditions (the credit card could allow for a negative balance while normal accounts could potentially not allow this).
• The post-conditions for account’s debit service must still apply to that of credit card accounts,though credit card accounts
could add additional post-conditions like that an associated voyager mile account must be credited with a certain amount of
voyager miles.
• The invariance constraints for accounts must still hold for credit card accounts,though credit card accounts could add further
invariance constraints around the additional state maintained for credit card accounts.
Caution
Not adhering to any of these design by contract rules would directly violate substitutability,i.e.one would no longer be
able to substitute an instance of the sub-class for an instance of the more generic class.
Figure 2.2:Applying design by contract rules for specialisation.
2.1.7 Design by contract and implementing interfaces
We can assign pre- and post-conditions to a service specified in an interface,and invariance constraints to the interface as a whole.
This would require that any implementation of that interface would have to
• provide each service,subject to no more pre-conditions than what is specified in the interface,
• realise each service such that all the post-conditions are met once the service has been provided,and
Advanced Java
9/321
• ensure that the published state of the implementing object never violates the invariance constraints.
Figure 2.3:
Very often one uses an interface with pre- and post-conditions on the services to specify the service requirements for service
providers without constraining the state of the service provider.In such cases there would be no invariance constraints.The
previous figure shows an interface with pre- and post-conditions specified for the required service.Any particular implementation
of a venue agent must be assigned a business process which refuses the service under no more conditions than what is allowed
via the pre-conditions and which realizes the service in such a way that the post conditions are met for any success scenario (i.e.
any scenario where the service was not refused due to some pre-condition not having been met).
2.1.8 Contracts
An interface together with the pre- and post-conditions on the services and potentially some invariance constraints around the
published state goes a long way towards defining a complete contract facilitating full pluggability of service providers.To
complete the contract and allow for full pluggability of any service provider realizing the contract we still need to add
• the class diagrams for the value objects exchanged,and
• the quality requirements for the service provider.
2.1.8.1 Quality requirements
Having specified that a venue agent needs to be able to process booking requests and having associated the pre- and post-
conditions for the required bookVenue service will not yet guarantee us that any service provider realizing the interface subject
to these design-by-contract constraints will indeed be pluggable.We may still have certain quality requirements for the services.
For example,our business processes may require that we receive the booking information within an hour of placing the booking
request.Some venue agents which implement the above interface may not be able to adhere to this performance requirement and
may thus not be pluggable.
Another quality requirements may specify a certain scalability,the ability to process a certain number of booking requests per
unit time (e.g.per day).
2.1.8.2 Services without pre- and/or post conditions
Some services may need to be provided unconditionally.For such services one would not specify any preconditions.Similarly,
some services would return some result,but would have no further remnants after the service has been provided.Such services
would have no post-conditions.
Advanced Java
10/321
Consider the getTime of a Clock.This service should always be provided,i.e.if,under any conditions,the clock does not provide
the service,then there would be an error with the clock.Furthermore,the clock will return the current time,but there would be
no further persistent remnants of the service request.There would thus be no pre- and no post-conditions for the getTime service
of a clock.
2.1.8.3 An SLA for a caterer
We can package together the contract elements into a contract package.The package may be seen as a UML representation of a
Services Level Agreement (SLA).It will contain the following elements:
• an interface specifying the services required fromthe service provider,
• potentially pre- and/or post-conditions on services,
• potentially quality requirements for the individual services or for the service provider as a whole (such quality requirements
would apply across all services specified in the interface),and
• class diagrams for each of the objects exchanged between the client and the service provider.
A UML representation for a Service Level Agreement (SLA) for a caterer.
Figure 2.4:The Service Level Agreement (SLA) for a caterer
2.1.8.4 Always specify the contract fromthe perspective of the client
The purpose of the SLAis to encapsulate the client’s requirements for a service provider,decoupling the client’s business process
from any particular service provider.The pre- and post-conditions and quality requirements should thus be specified from the
perspective of the client’s needs and not fromthe perspective of how a particular service provider is able to render a service.
Advanced Java
11/321
2.2 Benefits of Design By Contract based software development
There are numerous benefits to a design by contract based approach to software development including the following:
• Design by contract provides a natural approach to object-oriented software development.
• Design by contract provides a systematic approach to bug-free software development.
• Contracts facilitate testability.Consequently design by contract provides a framework for deriving generating tests for con-
tracts.The generation of these tests can be largely automated.
• Design by contract also provides a natural way to document contracts and service providers realising these contracts,directly
exposing the preconditions,deliverables and business rules around a contract.
• Design by contract tells you directly what exceptions a service of your class should be throwing and makes a clear distinction
between exceptions and errors.
• Design by contract provides firmguidelines on how inheritance should be implemented.
• Having service providers realise a contract improves their plug-ability,hence reducing the risk of lock-in for the client.
2.3 Implementing preconditions in Java
the preconditions are those conditions under which a service provider may refuse a service without breaking the contract.
Note
The contract is written from the client’s perspective.It does not mean that eery service provider realising the contract must
refuse the service - only that the service provider has the right to refuse the service.
The notification mechanism used by objects to notify a client that a requested service is not going to be provided for some or
other reason is notifiable exceptions,i.e.any exception which is not a java.lang.RuntimeException.Hence,for every
pre-condition one introduces a notifiable exception class.
Note
Java essentially has three types of throwable objects
1.java.lang.Error Errors are thrown by the Java Runtime Environment.They signal problems with the runtime environment
itself and should not be thrown,or caught,by application code.
2.java.lang.RuntimeException Runtime exceptions are thrown if an application error occurs,i.e.if the server is unable to
meet the contractual obligations.This is usually attributable to a coding mistake or insufficient testing.
3.Notifiable (Checked) exceptions These are the pre-condition exceptions used to notify a client that a service request is
refused because a particular precondition has not been met.Since the contract allows for service request refusal under
such conditions,no application error has occured - at least not at the level of the service provider class in question.
For example,if an account may refuse the debit service if either
• there are insufficient funds,or
• if the daily withdrawal limit has been exceeded,
then one should introduce two exception classes,e.g.InsufficientFundsException and DailyLimitExceededE-
xception.Both these exceptions would be notifiable exceptions (i.e.extend java.lang.Exception).
Thus the service implementation would check whether all contractual preconditions the service provider realisation would like
to enforce are met,and if any of these is not met,the service would throw a corresponding exception:
Advanced Java
12/321
public class AccountImpl implements Account
{
...
public TransactionConfirmation debit(double amount)
throws InsufficientFundsException,DailyLimitExceededException
{
//Test preconditions
if (balance - amount < minimumBalance)
throw new InsufficientFundsException();
if (getTotalDebits(today) + amount > dailyLimit)
throw new DailyLimitExceededException();
//Now perform the debit
...
//Now we can check that business rules still hold.
//If they fail now,then there was an application error.
assert balance >= minimumBalance:
"minimum balance invariance violated";
assert getTotalDebits(today) <= dailyLimit:
"daily debit limit violated";
...
}
...
}
2.4 Implementing postconditions in Java
The postconditions are the conditions which must hold after successful completion of the service They may include conditions
on the final state of
• the object providing the service,
• any object accessed by that object during the realisation of the service request,
• the return value of the service.
These postconditions must be satisfied by the service logic in order that the service provider meets its contractual obligations.
Hence,if any of these postconditions are not met upon service completion,the contractual obligations have been violated and we
have an error.Clients may be notified of such errors either via
• a RuntimeException,or
• an AssertionError.
2.4.1 RuntimeExceptions
A service provider will throw a RuntimeException if the service provider encounters a problemnot covered by the precon-
ditions,which prevents it fromfulfilling its contractual obligation.
Advanced Java
13/321
2.4.2 Assertions
Assertions may be used at the end of the service to check whether all the postconditions have been met.Assertions are a more
sophisticated mechanismwhich may be switched on or off at will.
2.4.3 Ensuring that the postconditions of a superclass are met when the service is requested from
a subclass
An approach which may often be used to ensure that the design-by-contract constraints for overriding a method are not violated
is to delegate the first part of the service realization to the superclass itself by calling the corresponding superclass method as
first statement in the overriding method.Once the superclass has addressed its responsibilities,the service implementation in the
subclass can add its additional responsibilities.
class SomeSubClass extends SomeSuperclass
{
...
public void f(...)//Overridden service
{
super.f(...);
//add additional responsibilities here.
}
...
}
2.5 Implementing invariance constraints in Java
Invariance constraints are constraints or symmetry rules which must be always met (or at least on transactional boundaries).
Hence,if they are met prior to a service having been requested,then they must still hold after the service has been provided.
2.5.1 Method for checking object integrity
A common approach is to define a method which is used to check that an object’s integrity has not been violated,i.e.that all
invariance constraints for that object hold.This may,for example,be a validate service which throws an error (typically an
assertion error) if any of the invariance constraints are currently not met.
The validate service would have,for each invariance constraint,an assertion which checks that that invariance constraint is
currently met.
2.5.2 Enforcing invariance constraints on services
In order to build invariance constraint validation into the service logic one would call the validate service at the beginning of
the service and at the end.
2.6 Exercises
2.6.1 A design by contract implementation for accounts
Write an Account class (such as a bank account) which maintains
• the account balance,
Advanced Java
14/321
• a transaction history,each transaction being either a credit or a debit transaction with a transaction amount and date,
• a daily withdrawal limit and the minimumbalance can be set for the account.
By default,the minimumbalance is zero and the daily withdrawal limit is R5000.00.
The preconditions for the debit service are
1.that there are sufficient funds,and
2.that the daily withdrawal limit is not exceeded.
and the postconditions are that
• the withdrawal amount has been subtracted fromthe balance,
• the transaction has been added to the transaction history,and that
• the debit service returns a transaction confirmation with the transaction type and date and the withdrawal amount.
The credit service,on the other hand,is offered unconditionally.The postconditions for the debit service are the same as those
for the debit service except that the withdrawal amount is now added to the balance.
There is one invariance constraint applying to the account which states that the sumof all credits in the transaction history minus
the sumof all debits must always add up to the current balance.
Provide a design by contract based implementation for the above.
2.6.2 A design by contract implementation for credit card accounts
Assume credit card accounts are specialised accounts which
• earn one voyager mile per R500 withdrawn fromthe account,
• and which apply credit interest on credit balances and debit interest on debit balances.The interest calculations are done every
time the account is credited or debited.
Provide a design by contract implementation for this subclass of account.
Advanced Java
15/321
Chapter 3
UML Relationships and Java
3.1 Summary of UML relationships
Figure??summarizes the UML relationships.It shows that these are conceptually specializations of each other and that we have
weak and strong variants of ‘ is a ’,‘ has a ’ and ‘ uses ’.
Figure 3.1:Summary of UML relationships
3.1.1 Dependency
Instances of the one class,the user,make,at times,use of instances of the other class,the service provider.The latter is often
modelled as an interface in order to decouple the user from any particular implementation of a service provider.For example,
Advanced Java
16/321
clients of the bank,upon spotting an ATM,may decide to use it in order to withdraw some cash from their account,but they do
not maintain a message path to any particular ATM.
A dependency is called a ‘ weak uses ’ because the user does not maintain a message path an is not in a position to,at any stage,
send further service requests to the service provider.
3.1.2 Association
Association is used for two purposes.On the one side it is used purely for navigability.In the second case it is used for a
client server relationship (or peer-to-peer in the case of binary associations).In either case,the object which has the association