Introduction to AOP Exercises for Tuesday, 2003/09/23 Exercise 3. Experient with tracing in AspectJ. To test your aspect on it, write a small Java program that creates an object with some fields in it and then calls a method on that object. The method should in turn call some other methods. Write an aspect that outputs one line of information each time a method is called and each time a call is completed. Make sure the message says whether the method completes normally or through an exception. Add tracing for changes in the fields values. Does this work for private fields of your test class? Now, add indentation: You want output like Entering call(TestClass.m()) Entering call(TestClass.f()) Entering call(TestClass.g()) Exiting call(TestClass.g()) Exiting call(TestClass.f()) Entering call(TestClass.m()) Can you do this without changing your original tracing aspect, by adding a new indentation aspect? (Hint: you can add advice to the print statement in the original tracing aspect.) Exercise 4. Write some aspects for fine-grained access restriction. Add one or two toy classes to your test program, all in the same package. • Write an aspect that ensures at runtime that objects of class A can only be created within methods of class B. • Write an aspect that ensures that there is no write access to non-private fields. • Write an aspect to make a field object-private, i.e. it may only be accessed from within the same object, not from other objects of the same class. • Add a field int group to one of your classes, which can be initialized using the constructor. Objects of that class are now considered to belong to different groups, depending on the value of that field. Make sure that some method can only be called from other objects in the same group. For each of these, figure out whether it would be possible to ensure these restrictions statically, i.e. at compile time. Exercise 5. Write a class containing a method that computes binomial coefficients using the plain recursive algorithm. bc(n, 0) = 1 bc(n, n) = n bc(n, m) = bc(n − 1, m − 1) + bc(n − 1, m) Write an aspect that counts the number of recursive calls and outputs the result when the top-most call returns. Write a caching aspect that stores all calculated values of bc and uses the cached values, instead of re-evaluating them in the recursion. Use both aspects to see how much you saved.