  Java reflection has been increasingly used in a wide range of software. It
allows a software system to inspect and/or modify the behaviour of its classes,
interfaces, methods and fields at runtime, enabling the software to adapt to
dynamically changing runtime environments. However, this dynamic language
feature imposes significant challenges to static analysis, because the
behaviour of reflection-rich software is logically complex and statically hard
to predict, especially when manipulated frequently by statically unknown string
values. As a result, existing static analysis tools either ignore reflection or
handle it partially, resulting in missed, important behaviours, i.e., unsound
results. Therefore, improving or even achieving soundness in (static)
reflection analysis -- an analysis that infers statically the behaviour of
reflective code -- will provide significant benefits to many analysis clients,
such as bug detectors, security analyzers and program verifiers. This paper
makes two contributions: we provide a comprehensive understanding of Java
reflection through examining its underlying concept, API and real-world usage,
and, building on this, we introduce a new static approach to resolving Java
reflection effectively in practice. We have implemented our reflection analysis
in an open-source tool, called SOLAR, and evaluated its effectiveness
extensively with large Java programs and libraries. Our experimental results
demonstrate that SOLAR is able to (1) resolve reflection more soundly than the
state-of-the-art reflection analysis; (2) automatically and accurately identify
the parts of the program where reflection is resolved unsoundly or imprecisely;
and (3) guide users to iteratively refine the analysis results by using
lightweight annotations until their specific requirements are satisfied.
