I'm using reflection to invoke methods on java.util.stream.Stream but because the actual implementations (ReferencePipeline etc.) have the actual code which runs, I get illegal reflective access warnings when calling method.setAccessible(true), and without that call, it doesn't work. I was wondering whether there is a way to automatically delegate this to a super method where access isn't illegal? That is, I want to call filter where it's legal on java.util.stream.Stream and not ReferencePipeline or whatever the implementation is.
EDIT Here is some code. target is a concrete instance of a Stream obtained via reflection.
assert target instanceof java.util.stream.Stream;
Method candidate = Stream.of(target.getClass().getMethods())
.filter(method -> method.getName().equals("filter"))
//.filter(myComplicatedCriteria) - omitted for brevity
.findAny().orElseThrow();
try {
candidate.setAccessible(true);
return candidate.invoke(target, candidateParameterValues);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new EolRuntimeException(ex);
}
Use the interface class
Streaminstead of the implementing classtarget.getClass(). Change the code to:Root cause of the problem is
java.util.stream.ReferencePipelineas well asjava.util.stream.ReferencePipeline.Headbeing package protected. Your class can't access these classes using reflection even if thefilter()method itself is defined aspublic.The
Stream.class.getMethods()approach will work because your class can access the publicStreamclass. Seesun.reflect.Reflection.ensureMemberAccess()check if you need details.