An example is in AttributeConverterDescriptorImpl#toMember.
There are some scenarios that could lead to an exception when executing this line in AttributeConverterDescriptorImpl#toMember when first accessed in a multi-threaded environment:
memberMethod.invoke( xProperty )
1) thread-1 initializes the static field, memberMethod;
2) thread-2 finds that memberMethod != null, and attempts to invoke the method before thread-1 makes the memberMethod accessible via memberMethod.setAccessible( true ), resulting in HibernateException being thrown.
1) both thread-1 and thread-2 find memberMethod == null and enter block to initialize memberMethod;
2) thread-1 initializes memberMethod and makes it accessible;
3) thread-2 overwrites memberMethod with a different Method, because Class#getDeclaredMethod returns a copy of the requested Method;
4) thread-1, attempts to invoke the method before thread-2 makes the overwritten memberMethod accessible, resulting in HibernateException being thrown.
There are 2 ways to fix this.
1) If lazy initialization is not needed, Initialize the static memberMethod in a static block, as in https://github.com/scottmarlow/hibernate-orm/tree/IllegalAccessException_hack.
2) If lazy initialization is desirable, assign the Method to a temporary variable and make it accessible before assigning to the static memberMethod. For example:
Method tempMemberMethod = javaXMemberClass.getDeclaredMethod( "getMember" ); tempMemberMethod.setAccessible( true );
memberMethod = tempMemberMethod;
Other places that need to be fixed are still to be determined.