A THROW clause may only throw an exception which is declared by the target method declared in the rule event (ignoring runtime exceptions which may always be thrown). This restriction ensures that the THROW does not break the target method contract. However, when injecting into interfaces or into overriding classes this is not a sufficient guarantee. If the trigger method into which the rule is being injected overrides the target method mentioned in a CLASS rule or is an implementation of a method declared in an INTERFACE rule then it does not actually have to throw all or, indeed, any of the exceptions declared by the super method. So, the type checker currently validates the rule against the trigger method exception list and generates an error if this implementation method does not declare the exception.
This behaviour is invalidating perfectly valid uses of rules declared at a generic level in the class hierarchy. A correct approach would be: to continue to reject rules where the THROW type is not declared by the target method; to inject the rule into trigger methods which do declare a relevant exception; to generate a warning and inhibit injection when the trigger method does not declare a relevant exception.
Unfortunately, it is not actually possible to implement this behaviour in this way because it is not possible to check the exception type in the THROW clause against the exception types declared by a trigger method at injection time. This might require loading classes during transformation which the Java transformer architecture does not support properly. However it is possible to implement the same effect following the normal procedure of injecting the rule and then type-checking the first time it is triggered.
Currently, the type checker will throw a type error causing the injected code to be bypassed. Fixing the problem requires that the type checker throw a type warning rather than an error. The error reporting mechanism needs to either mask these type warning exceptions or, at least, not display them as an error. The injected code cannot be uninjected until the rule is unloaded but execution can still be disabled.