  Software bloat is code that is packaged in an application but is actually not
necessary to run the application. The presence of software bloat is an issue
for security, for performance, and for maintenance. In this paper, we introduce
a novel technique for debloating, which we call coverage-based debloating. We
implement the technique for one single language: Java bytecode. We leverage a
combination of state-of-the-art Java bytecode coverage tools to precisely
capture what parts of a project and its dependencies are used when running with
a specific workload. Then, we automatically remove the parts that are not
covered, in order to generate a debloated version of the project. We succeed to
debloat 211 library versions from a dataset of 94 unique open-source Java
libraries. The debloated versions are syntactically correct and preserve their
original behavior according to the workload. Our results indicate that 68.3% of
the libraries' bytecode and 20.3% of their total dependencies can be removed
through coverage-based debloating. For the first time in the literature on
software debloating, we assess the utility of debloated libraries with respect
to client applications that reuse them. We select 988 client projects that
either have a direct reference to the debloated library in their source code or
which test suite covers at least one class of the libraries that we debloat.
Our results show that 81.5% of the clients, with at least one test that uses
the library, successfully compile and pass their test suite when the original
library is replaced by its debloated version.
