Allow invoking methods on an instance which is loaded by a different class loader #814
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently an IllegalArgumentException is thrown when an implementation of the ObjectFactory interface (from cucumber-java) creates an instance of a class that is loaded by another class loader:
java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at cucumber.runtime.Utils$1.call(Utils.java:34)
... 52 more
This happens in my case where I implemented an ObjectFactory that creates an instance in an OSGi context. The OSGi framework requires the class to be loaded by a bundle's class loader and as such the class loaded is different from the class loaded by the JavaBackend (which loads the class with the system classloader).
This issue can be solved by checking if the class loader of the target instance differs from the class loader of the method's declaring class. If so the method can be retrieved from the target instance's class instead and invoked in the same way. I also added 2 tests to validate the current behavior and new behavior.