New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Potential bug due to the non-determinicity of Class#getDeclaredConstructors #682
Labels
Comments
Oja95
pushed a commit
to Oja95/javers
that referenced
this issue
Jun 21, 2018
bartoszwalacik
added a commit
that referenced
this issue
Jul 7, 2018
@Oja95 thanks for your help in finding and fixing this bug. |
fix is on its way to the Central |
fix released in javers-3.10.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
During initializing the modules, reflection is used to instantiate various classes needed for the modules.
However, the utility responsible for instantiating these classes takes the first public constructor from the array returned by
Class#getDeclaredConstructors
method and uses it to instantiate the class. Seeorg.javers.common.reflection.ReflectionUtil#newInstance
.However, the Javadoc from
Class#getDeclaredConstructors
states the following:Thus, relying on the order of the constructors obtained might result in unexpected behaviour.
A real erroneous scenario occurred during initializing the
InMemoryRepositoryModule
, more specifically, during instantiating theInMemoryRepository
class.InMemoryRepository
has two public constructors:public InMemoryRepository()
public InMemoryRepository(CommitIdGenerator commitIdGenerator)
Should the
Class#getDeclaredConstructors
return an array in which the default public constructor is the first element, everything works well. However, should the second constructor be the first element, then it fails to resolve theCommitIdGenerator
object reference from the Pico container. The following is then logged:Steps to reproduce
There is no good way to reliably reproduce this by some simple application. To reproduce the issue, create a simple
main
method that builds a default Javers instance using the following:Then add a conditional breakpoint to line 70 in
org.javers.common.reflection.ReflectionUtil
to only break whenclazz == InMemoryRepository.class
holds. Run the application, and when the application stops on the breakpoint, check theconstructor
variable to see if it references the default constructor. If so, evaluate an expression to change the value of the constructor variable to become the other constructor obtained byClass#getDeclaredConstructors
using the following expression:After that, resume the execution and the mentioned errors should pop right up in the standard output. Please keep in mind that this difficult hack to reproduce the issue is to simulate a potential scenario that could very well happen due to the non-determinicity of the order of elements returned by
Class#getDeclaredConstructors
method.Reality and expectation
The
org.javers.common.reflection.ReflectionUtil#newInstance
instantiation method has non-determinicity in it which might cause unexpected behaviour. Expectation would be to ensure that the initialization logic wouldn't break because of the non-determinicity of the order of the elements ofClass#getDeclaredConstructors
method.The text was updated successfully, but these errors were encountered: