def monolithic_jar(self, binary, path, manifest_classpath=None):
    """Creates a jar containing all the dependencies for a jvm_binary target.

    Yields a handle to the open jarfile, so the caller can add to the jar if needed.
    The yielded jar file either has all the class files for the jvm_binary target as
    a fat jar, or includes those dependencies in the `Class-Path` field of its
    Manifest.

    :param binary: The jvm_binary target to operate on.
    :param path: Write the output jar here, overwriting an existing file, if any.
    :param iterable manifest_classpath: If set output jar will set as its manifest's
      classpath, otherwise output jar will simply include class files.
    """
    # TODO(benjy): There's actually nothing here that requires 'binary' to be a jvm_binary.
    # It could be any target. And that might actually be useful.
    with self.context.new_workunit(name='create-monolithic-jar'):
      with self.open_jar(path,
                         jar_rules=binary.deploy_jar_rules,
                         overwrite=True,
                         compressed=True) as monolithic_jar:
        if manifest_classpath:
          monolithic_jar.append_classpath(manifest_classpath)
        else:
          with self.context.new_workunit(name='add-internal-classes'):
            with self.create_jar_builder(monolithic_jar) as jar_builder:
              jar_builder.add_target(binary, recursive=True)

          # NB(gmalmquist): Shading each jar dependency with its own prefix would be a nice feature,
          # but is not currently possible with how things are set up. It may not be possible to do
          # in general, at least efficiently.
          with self.context.new_workunit(name='add-dependency-jars'):
            dependencies = self.list_external_jar_dependencies(binary)
            for jar, coordinate in dependencies:
              self.context.log.debug('  dumping {} from {}'.format(coordinate, jar))
              monolithic_jar.writejar(jar)

        yield monolithic_jar

      if binary.shading_rules:
        with self.context.new_workunit('shade-monolithic-jar'):
          self.shade_jar(binary.shading_rules, jar_path=path)
Creates a jar containing all the dependencies for a jvm_binary target.

    Yields a handle to the open jarfile, so the caller can add to the jar if needed.
    The yielded jar file either has all the class files for the jvm_binary target as
    a fat jar, or includes those dependencies in the `Class-Path` field of its
    Manifest.

    :param binary: The jvm_binary target to operate on.
    :param path: Write the output jar here, overwriting an existing file, if any.
    :param iterable manifest_classpath: If set output jar will set as its manifest's
      classpath, otherwise output jar will simply include class files.