Renaming /doc to /docs for use with GitHub Pages
[jpf-core.git] / docs / jpf-core / ExceptionInjector.md
1 # ExceptionInjector #
2
3 The ExceptionInjector is a listener that can throw user configured exceptions at arbitrary program locations. The main purpose is to ease the testing of exception handler code that would otherwise hard to reach, e.g. because it is not clear if/how an exception could be thrown in 3rd party code.
4
5 ## Properties ##
6
7 ~~~~~~~~ {.bash}
8 **ei.exception** = <exception-spec>;... \
9
10   <exception-spec> := <type>'@'<location> \
11
12   <type> := <exception-classname>[[string-literal]('(') ')'] \
13
14   <location> := <classname>':'line | <classname>'.'<method-spec>[ [[BR](':'line])]
15 ~~~~~~~~
16
17 Relative line numbers count from the first executable statement in the method body. They are mostly used to have tests that are more robust against changes in the target source file.
18
19 If a method is given without a line offset, the exception is thrown before executing INVOKE instructions that call the specified method.
20
21 If a line is specified (either absolute or method-body relative), the exception is thrown before executing the associated bytecode at this line.
22
23 If more than one exception specification is given, these need to be separated by semicolons ';' (commas cannot be used because they can appear within argument type lists of the target method).
24
25 Method argument types have to be specified the same way as they are reported by 'javap', i.e. with fully qualified type names in dot notation (e.g. "`foo(java.lang.String,int[])`"). Return types can be omitted.  
26
27 `ei.throw_first` [`boolean`] - if true, throw exception on first bytecode instruction associated with the given (absolute or relative) source line. If false, throw on last associated bytecode instruction
28  
29
30 ## Examples ##
31
32 ### (1) throw exception on absolute line 42 in xyz.MyClass: ###
33
34 The application property file
35
36 ~~~~~~~~ {.bash}
37 target = yxz.MyClass
38 ei.exception = ArithmeticException@xyz.MyClass:42
39 ~~~~~~~~
40 on file
41 ~~~~~~~~ {.java}
42 1:  package x.y.z;
43     ..
44     public class MyClass {
45       ..
46       try {
47         ..
48 42:     int z = x / y;
49         ..
50       } catch (ArithmeticException ax){
51         // the handler code to test
52       }
53      ..
54 ~~~~~~~~
55
56 will throw an ArithmeticException on line 42 regardless of the 'x' and 'y' values. 
57
58 ### (2) throw a `Zapp("gotcha")` exception on (relative) line 2 in method body `xyz.MyClass.foo()` ###
59
60 The application property file
61
62 ~~~~~~~~ {.bash}
63 target = yxz.MyClass
64 ei.exception = Zapp("gotcha")@xyz.MyClass.foo(int[]):2
65 ~~~~~~~~
66 on file
67 ~~~~~~~~ {.java}
68     package x.y.z;
69     ..
70     public class MyClass {
71       ..
72       void foo (int[] whatever) {
73         // some comment (doesn't count for line offsets)
74 +0:     int n = ..       // first statement line in foo()
75 +1:     // some more comment (does count for line offsets)
76 +2:     doSomething(n);  // can throw a Zapp exception 
77      ..
78 ~~~~~~~~
79 will throw a Zapp("gotcha") exception on relative line 2 of method body xyz.MyClass.foo(). Note that the line offset counts from the first executable statement line within foo().
80
81
82 ### (3) throw an `IOException` when calling `File.createTempFile()` ###
83 The application property file
84
85 ~~~~~~~~ {.bash}
86 target = yxz.MyClass
87 ei.exception = java.io.IOException@java.io.File.createTempFile(java.lang.String,java.lang.String)
88 ~~~~~~~~
89
90 will throw an exception on the first call of File.createTempFile(), regardless of where this occurs and what the parameters to the call are
91
92 ~~~~~~~~ {.java}
93 1:  package x.y.z;
94     ..
95     public class MyClass {
96       ..
97       try {
98         ..
99         File tmp = File.createTempFile(prefix,suffix);
100         ..
101       } catch (IOException iox) {
102         // the handler code to test
103       }
104      ..
105 ~~~~~~~~