[master branch] EJBCLIENT-81 Fix potential class initialization deadlock #45
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.
https://issues.jboss.org/browse/EJBCLIENT-81 exposes a bug where the static initializer of EJBClientContext would trigger operations like EJB receiver creation and registration against EJBClientContext(s) from within the static initializer. Some of these operations involve acquiring locks for synchronized blocks. What's causing this issue is:
It so happens that T1 waits for a lock L2 on "instanceVariableFoo" on line 5. The lock L2 is held by the other thread T2 between lines 2 through 4. So T1 waits. Now T2 reaches the logger statement on line 4. The logger requires the class instance of EJBClientContext which hasn't yet fully initialized (remember all this is triggered via static initializer in that class). Since the class isn't fully initialized the thread T2 tries to get the initialization lock L1 but that's held by T1 and won't release it until the class initialization completes and that won't happen until T2 releases the lock L2, for T1 to finish. This effectively leads to a deadlock which is what is happening in EJBCLIENT-81.
The commit here fixes the issue by _not_ using the static initializer block of EJBClientContext to trigger receiver registration(s) and effectively spawing other threads to register the cluster nodes. Instead it just "constructs" the ConfigBasedEJBClientContextSelector. The receiver registration is done lazily, later on, by the ConfigBasedEJBClientContextSelector