-
1. Re: How rule injection to abstract classes works
adinn Feb 6, 2018 11:19 AM (in response to ochaloup)Oooh, that's an interesting outcome. I'll take a look as soon as I get a chance!
regards,
Andrew Dinn
-
2. Re: How rule injection to abstract classes works
adinn Feb 8, 2018 11:28 AM (in response to ochaloup)Hi Ondra,
I looked at your tests and I don't think Byteman is doing anything wrong or unexpected either for the abstractmethod test or the callSuper tests.
Firstly, lets look at the abstract method question. As you say, for test abstractmethod the rule does not trigger because there is no method for it to be injected into. If you switch on verbose trace you can see this
retransforming org.jboss.btm.abstractmethod.AbstractGreetingsProcessorAbstractMethod
However, you don't see any messages about triggers because there is no method to inject into.
What you also don't see is a TypeWarning saying that the rule failed to be injected. That is perhaps an issue as it ought to be flagged when a retransform is scheduled for a class mentioned in some rule but injection of that rule never happens. I am not quite sure why and will investigate that further.
As for the super call test that is doing what I would expect and I don't understand why you think it should do anything different. I changed your rules slightly to make it clearer what is happening and to show which rules are being executed. The problem is that your rule produces the same side effect in the parent and child implementation. I modified the action to this
targetLocation = "AT ENTRY",
action = "$1 = $1 + \" \" + $CLASS")
n.b. $CLASS is a special var that names the class into which the rule has been injected. When I run this the test fails (of course) but the errors are as follows
Failed tests: abstractmethod(org.jboss.btm.test.AbstractTest): expected:<"[goodbye]"> but was:<"[hello]">
callsuper(org.jboss.btm.test.AbstractTest): expected:<"[goodbye]"> but was:<"[hello org.jboss.btm.callsuper.AbstractGreetingsProcessorCallSuper]">
callsuperInheritInheritanceRule(org.jboss.btm.test.AbstractTest): expected:<"[goodbye]"> but was:<"[hello org.jboss.btm.callsuper.GreetingsProcessorCallSuper org.jboss.btm.callsuper.AbstractGreetingsProcessorCallSuper]">
As you can see in the first test -- where you inject only into the parent class -- the argument is modified by appending the parent class name. By contrast, in the second test the argument is modified in the child class by appending the child class name and then again in the parent class by appending the parent class name· This is what is expected.
One other thing. Your rules specify overriding injection using
targetClass = "^AbstractGreetingsProcessorAbstractMethod"
That happens to work but it is an anti-pattern and may be rejected in future. What you are supposed to specify is
targetClass = "^AbstractGreetingsProcessorAbstractMethod",
isOverriding = true
regards,
Andrew Dinn
-
3. Re: How rule injection to abstract classes works
ochaloup Feb 9, 2018 2:34 AM (in response to adinn)HI adinn
many thanks for the clarification and sorry for my ignorance if you consider so I can see the point now just I was kind of blind when playing with it. And thank you for pointing to $CLASS variable. I haven't recognized the existence. I can see it's pretty handy for rule debugging.
Have a nice day
Ondra
-
4. Re: How rule injection to abstract classes works
adinn Feb 9, 2018 4:59 AM (in response to ochaloup)Hi Ondra,
ochaloup wrote:
many thanks for the clarification and sorry for my ignorance if you consider so I can see the point now just I was kind of blind when playing with it. And thank you for pointing to $CLASS variable. I haven't recognized the existence. I can see it's pretty handy for rule debugging.
There is nothing wrong or ignorant about asking questions :-)
The special vars $CLASS and $METHOD were added as part of the SystemTap integration. I think they are mentioned somewhere in the Programmer's Guide but if not they ought to be.
While we are here I'll just note that $CLASS is really useful when using overriding rules. I initially wrote the action as
action = "$1 = $1 + \" \" + $0.getClass().getName()")
but of course that appends the same string in both super- and subclass. $CLASS refers to the name of the class that owns the method into which the rule has been injected. So, when the rule is triggered when executing the subclass method it identifies the name of the subclass and when it is triggered from the superclass method it identifies the name of the superclass.
That's quite a useful feature. For example, this condition will ensure that a rule injected using overriding only fires at the outermost injection point
condition = "$0.getClass().getName() == $CLASS"
regards,
Andrew Dinn
-
5. Re: How rule injection to abstract classes works
ochaloup Feb 9, 2018 5:13 AM (in response to adinn)I see, sure ;)
ah, ok, that's nice trick (
condition = "$0.getClass().getName() == $CLASS"
). Thanks!