I have the following classes:
public class Population {
private int population;
public Population()
{
population = 0;
}
public void newYear()
{
population += 10;
}
public int getPopulation() {
return population;
}
}
and the following aspect
public aspect StatisticsAspect {
private static int year = 0;
pointcut operation(Population caller) : call(* Population.newYear());
after(Population caller) : operation(caller)
{
System.out.println("New Year: " + year);
year++;
System.out.println("Population: " + caller.getPopulation());
}
}
Now I want that everytime when newYear()
is called, that the "statistics" are printed to the console.
Unfortunately I get the ajc: formal unbound in pointcut
error.
What do I need to change to make it work?
I refactored your code a bit because
getPopulation()
is a bad name and against conventions. Not the population object s returned as the name implies but the population's size.As for your aspect, the naming
caller
is also bad because the object is not the caller but the callee or the target of the call. I simply renamed the parameter topopulation
because this time it really contains a population object. Then I bound it to atarget()
parameter in order to make your error message go away.I also switched from
call()
toexecution()
pointcut because it is more efficient to weave the code into the executed method instead of into every single place where the method is called.I also made sure that the count starts at 1, not 0, after the first new year is over and the population has grown. I did this by using
++size
rather thansize++
, i.e. pre- instead of post-increment.Now the code looks like this:
Now look at the console log:
Can you spot the problem? You have one overall year counter, but multiple populations. Actually, you should have one year counter per population in order to get your statistics right. This can be done by using one aspect instance per target (i.e. per population) instead of a singleton aspect and of course by no longer making the year counter static:
Here,
pertarget(execution(Population.new(..)))
means: Create one aspect instance perPopulation
constructor execution, i.e. per created object.Now the statistics are correct (I also changed the log message a bit in order to print the object ID so we can see which message belongs to which population):