-
1. Re: METHOD and generics
belaban Oct 24, 2012 10:43 AM (in response to belaban)Correction: the INVOKE method triggers an exception:
unsatisfiable local variable binding $msg checking method up(Lorg/jgroups/Event;)Ljava/lang/Object;
-
2. Re: METHOD and generics
belaban Oct 24, 2012 11:11 AM (in response to belaban)Hmm, what puzzles me is that the following rule:
RULE dummy2
CLASS NAKACK2
METHOD up(Event)
BIND msg:Message=$1.getArg();
clazz=msg.getClass();
# len=msg.getLength();
AT READ is_server ALL
IF TRUE
DO System.out.println("******** $1=" + msg + ", clazz=" + clazz);
ENDRULE
prints out clazz=org.jgroups.Message, so it *has* the correct type of msg. After all, I thought that BIND msg:*Message*=$1.getArg(), would force Byteman to recognize msg as of being of type Message, *not* Object !
However, if I uncomment the binding of len, then it seems that Byteman does still see msg as Object:
Rule.ensureTypeCheckedCompiled : error type checking rule dummy2
org.jboss.byteman.rule.exception.TypeException: MethodExpression.typeCheck : invalid method getLength for target class java.lang.Object
Thoughts ?
-
3. Re: METHOD and generics
adinn Dec 4, 2012 6:17 AM (in response to belaban)Hi Bela,
Apologies for not attending to teh details fo this earlier -- been very busy getting the ARM64 OpenJDK interpreter port tpo pass the TCK (almost there :-)
Bela Ban wrote:
Hmm, what puzzles me is that the following rule:
RULE dummy2
CLASS NAKACK2
METHOD up(Event)
BIND msg:Message=$1.getArg();
clazz=msg.getClass();
# len=msg.getLength();
AT READ is_server ALL
IF TRUE
DO System.out.println("******** $1=" + msg + ", clazz=" + clazz);
ENDRULE
prints out clazz=org.jgroups.Message, so it *has* the correct type of msg. After all, I thought that BIND msg:*Message*=$1.getArg(), would force Byteman to recognize msg as of being of type Message, *not* Object !
However, if I uncomment the binding of len, then it seems that Byteman does still see msg as Object:
Rule.ensureTypeCheckedCompiled : error type checking rule dummy2
org.jboss.byteman.rule.exception.TypeException: MethodExpression.typeCheck : invalid method getLength for target class java.lang.Object
Thoughts ?
I'm quite surprised that this works as you describe it above. The type checker should recognise that $1.getArg() has type Object and flag the initialisation of msg:Message as invalid because it involves a cast down from Object to Msg.
I would very much like to be able to support casting down and have been thinking of how to add it for quite some time now but I didn't expect it already to work :-)
Anyway, the main problem you are facing is that Byteman cannot deal with generics. Of course, it only has limited information about the type bindings employed in the original source since most such information is erased from the bytecode (not all though). So, you can sometimes know what type of datum you have at the point of use. So, in fact, you can probably identify from the bytecode that the argument passed AT INVOKE BoundedMessage.add() is indeed a Message. The real problem is that inside the generic code itself you don't know what parameter types you are delaing with.
Your initial example highlights the problem. You really want to inject the rule into BoundedList<Message>.add(). But in the JVM there is only one generic implementation method BoundedList.add(). How do you know when to trigger the rule? If the list contains any elements you could type test them and determine whether it is de facto a list of Message instances. But actually the type might have been constructed and passed around as a List<Streamable>. Does this matter? Well, using the dynamic type will allow you to avoid type errors but it may also lead to unintended triggerings. For example, any empty list will pass the dynamic test which might lead to your rule firing in many more circumstances than those you originally envisaged. I don't really see any way to deal with this issue which is why I have not yet implemented any support for using what little generic type info there is in the bytecode in your Byteman rules. I'm stil open to ideas but I don't really know what would be useful.
-
4. Re: METHOD and generics
belaban Dec 4, 2012 6:48 AM (in response to adinn)OK, I understand that type erasure makes your life harder :-)
But, what I don't understand is why
BIND msg:Message=$1.getArg();
doesn't *force* byteman to narrow Object to a Message. I thought that's the point of being able to specify the type of a variable, e.g. msg:TYPE=xxx.
I mean I know what I'm doing here and don't mind a CCE if it turns out that I specified the wrong type for msg.
Cheers,
-
5. Re: METHOD and generics
adinn Dec 4, 2012 7:03 AM (in response to belaban)Hi Bela,
Bela Ban wrote:
OK, I understand that type erasure makes your life harder :-)
But, what I don't understand is why
BIND msg:Message=$1.getArg();
doesn't *force* byteman to narrow Object to a Message. I thought that's the point of being able to specify the type of a variable, e.g. msg:TYPE=xxx.
I mean I know what I'm doing here and don't mind a CCE if it turns out that I specified the wrong type for msg.
Cheers,
Well, no . . . the point of the type declaration was to ensure you could state what type you expected rather than just get the type you got. However, I take your point that a downcast in bindings should be quite workable and would be very useful. Indeed, I am looking at implementing this right now. I think this will make it into the release I am currently preparing this week.
I think I will need to provide a backwards compatiility setting to disallow downcasts though e.g. settign a System variable like org.jboss.byteman.disallow.downcast. In part this is to allow you to ensure that downcasts are notified if you don't intend to use them. However, it also serves to retain backwards compatibility in one unlikely but possible special case. Allowing downcasting disallows use of the declared type to infer the type of the expression on the right of the equals sign. That may mean that some rules which currenltly type check because the expression type is known in advance may fail to check wit this new feature.
-
6. Re: METHOD and generics
belaban Dec 4, 2012 8:40 AM (in response to adinn)Re your point as to express the expected type: I do think this should potentially involve a downcast (if necessary). Would be very helpful for handling generic collections, which AIUI contain only Objects from a byteman perspective.
If you have to add a system property, then I'd vote for opting out: ie. if no system property is defined, downcasts are allowed ! :-)
Thanks for the very quick turnaround !
Cheers,