The issue you are encountering is a bug in Java 7 (even in 7.0_45), documented here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7166598
A simple workaround to avoid the "Invalid cursor position" SQLException that worked for me is to add this logic to the start of your implementation of Predicate.evaluate(RowSet rs) to detect the end-of-rowset condition:
FilteredRowSet frs = (FilteredRowSet) rs;
int rowNum = frs.getRow();
if (rowNum == 0) { // Meaning "no current row" - should never happen...
return false; // Needed only to address a bug in Java 7
}
Your workaround of calling isAfterLast() also seems fine, and the ugly workaround of simply swallowing the SQLException also works, since the exception occurs after all processing is complete.
The problem is fixed under Java 8 RTE, and recompilation is not necessary.
I have specifically tested a Predicate implementation which is failing under Java 7 using Java 8, within Intellij Idea, and also from the command line. Under Java 8 it also works fine without needing the Java 7 workaround described above.