code: def bundle(self, app, results_dir):
      
      assert(isinstance(app, BundleCreate.App))
  
      bundle_dir = self.get_bundle_dir(app.id, results_dir)
      self.context.log.debug('creating {}'.format(os.path.relpath(bundle_dir, get_buildroot())))
  
      safe_mkdir(bundle_dir, clean=True)
  
      classpath = OrderedSet()
  
      # Create symlinks for both internal and external dependencies under `lib_dir`. This is
      # only needed when not creating a deployjar
      lib_dir = os.path.join(bundle_dir, self.LIBS_DIR)
      if not app.deployjar:
        os.mkdir(lib_dir)
        consolidated_classpath = self.context.products.get_data('consolidated_classpath')
        classpath.update(ClasspathProducts.create_canonical_classpath(
          consolidated_classpath,
          app.target.closure(bfs=True, **self._target_closure_kwargs),
          lib_dir,
          internal_classpath_only=False,
          excludes=app.binary.deploy_excludes,
        ))
  
      bundle_jar = os.path.join(bundle_dir, '{}.jar'.format(app.binary.basename))
      with self.monolithic_jar(app.binary, bundle_jar,
                               manifest_classpath=classpath) as jar:
        self.add_main_manifest_entry(jar, app.binary)
  
        # Make classpath complete by adding the monolithic jar.
        classpath.update([jar.path])
  
      if app.binary.shading_rules:
        for jar_path in classpath:
          # In case `jar_path` is a symlink, this is still safe, shaded jar will overwrite jar_path,
          # original file `jar_path` linked to remains untouched.
          # TODO run in parallel to speed up
          self.shade_jar(shading_rules=app.binary.shading_rules, jar_path=jar_path)
  
      self.symlink_bundles(app, bundle_dir)
  
      return bundle_dir
docs: Create a self-contained application bundle.
  
      The bundle will contain the target classes, dependencies and resources.