Skip to content

Possible thread safety bug in runtime reflection due to lack of fence in j.l.r.Method constructor #10598

@retronym

Description

@retronym

Inspection of java.lang.reflect.Method shows that its fields are not final (not even one), and hence appears to be unsafe to share between threads without a fence.

I received a report of Scala runtime reflection returning Map[Object, Object] as the return type of a Scala method returning Map[String, X].

This suggests to me that Scala a thread in reflection is witnessing an instance of Method that was initialized in another thread and shared via TwoWayCaches.toJavaMap. The stores in the constructor of Method might not all be visible to the other thread. That could mean that signature appears to be null, in which case getGenericReturnType would just return Map.class, rather than the ParameterizedType created by parsing the generic signature.

Here's jcstress test with a similar structure that fails. https://gist.github.com/d68b202042e346c2fe99fd065d152971 . I couldn't witness a failure when actually using java.lang.reflect.Method

If this theory holds true, we'd need to use Unsafe / VarHandle to manually add a fence before sharing. WIP: https://github.com/scala/scala/compare/2.11.x...retronym:topic/reflection-method-fence?expand=1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions