You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The javassist class processor which adds code to execute oval rules for builder validation does so by overriding the existing reflective validation in the base OvalBuilder class. However, there are two issues in complex builder hierarchies where some of the builder classes have been processed but others have not.
In these examples OB will denote the root OvalBuilder class, PB will be a processed builder, and UB will be an unprocessed builder. Consider:
UB -> OB => OK (reflective)
PB -> OB => OK (injected)
PB -> UB -> OB => BROKEN*
UB -> PB -> OB => BROKEN
PB1 -> UB -> PB2 -> OB => BROKEN
Rules are executed but violations are double counted for PB.
In the first broken case the top level PB uses injected validation and then not being the lowest level non-OB builder delegates to its super class which is UB. The UB class defaults to reflective validation which processes the full class hierarchy and thus double counts any validation failures in PB.
This problem can be solved by adding an isSelfValidating method to the OB which returns false and then overriding that method in PB to return true && super.isSelfValidating as long as super is not OB. Then, the OB can skip injected validation if isSelfValidating return false (e.g. any class below it is not processed).
In the second broken case the top level UB requires reflective validation but the intermediate PB intercepts the validation and performs injected validation. Thus, the reflective validation in the parent is never executed.
The solution proposed for the first problem does not address this issue and this is the far more pressing problem since full validation is not performed. The problem is that there is no code in the class which indicates that it is unprocessed. Options:
Check for and cache the presence of the @processed annotation added by the processing plugin and specifically whether it includes the validation processor.
Check for the existence of the validate method added by the validation processor.
In either case, instead of asking OB isSelfValidating via inheritance we can ask OB isSelfValidating(this.getClass()). OB can evaluate the entire class hierarchy and cache the results. Then we can skip injected validation if any part of the class hierarchy is unprocessed.
Although this is a serious issue and should be fixed it is not a blocked at the moment because our builders do not cross library boundaries and thus are either all processed or all not processed.
The text was updated successfully, but these errors were encountered:
The javassist class processor which adds code to execute oval rules for builder validation does so by overriding the existing reflective validation in the base OvalBuilder class. However, there are two issues in complex builder hierarchies where some of the builder classes have been processed but others have not.
In these examples OB will denote the root OvalBuilder class, PB will be a processed builder, and UB will be an unprocessed builder. Consider:
UB -> OB => OK (reflective)
PB -> OB => OK (injected)
PB -> UB -> OB => BROKEN*
UB -> PB -> OB => BROKEN
PB1 -> UB -> PB2 -> OB => BROKEN
In the first broken case the top level PB uses injected validation and then not being the lowest level non-OB builder delegates to its super class which is UB. The UB class defaults to reflective validation which processes the full class hierarchy and thus double counts any validation failures in PB.
This problem can be solved by adding an isSelfValidating method to the OB which returns false and then overriding that method in PB to return true && super.isSelfValidating as long as super is not OB. Then, the OB can skip injected validation if isSelfValidating return false (e.g. any class below it is not processed).
In the second broken case the top level UB requires reflective validation but the intermediate PB intercepts the validation and performs injected validation. Thus, the reflective validation in the parent is never executed.
The solution proposed for the first problem does not address this issue and this is the far more pressing problem since full validation is not performed. The problem is that there is no code in the class which indicates that it is unprocessed. Options:
Check for and cache the presence of the @processed annotation added by the processing plugin and specifically whether it includes the validation processor.
Check for the existence of the validate method added by the validation processor.
In either case, instead of asking OB isSelfValidating via inheritance we can ask OB isSelfValidating(this.getClass()). OB can evaluate the entire class hierarchy and cache the results. Then we can skip injected validation if any part of the class hierarchy is unprocessed.
Although this is a serious issue and should be fixed it is not a blocked at the moment because our builders do not cross library boundaries and thus are either all processed or all not processed.
The text was updated successfully, but these errors were encountered: