code: public synchronized void start() throws Exception {
          if (!isRunning()) {
              ConnectionManager.getInstance().addLifecycleListener(lifecycleListener);
              ConnectionManager.getInstance().start();
              DeviceFinder.getInstance().start();
              DeviceFinder.getInstance().addDeviceAnnouncementListener(announcementListener);
              VirtualCdj.getInstance().addLifecycleListener(lifecycleListener);
              VirtualCdj.getInstance().start();
              VirtualCdj.getInstance().addUpdateListener(updateListener);
              queueHandler = new Thread(new Runnable() {
                  @Override
                  public void run() {
                      while (isRunning()) {
                          try {
                              handleUpdate(pendingUpdates.take());
                          } catch (InterruptedException e) {
                              logger.debug("Interrupted, presumably due to MetadataFinder shutdown.", e);
                          } catch (Exception e) {
                              logger.error("Problem handling CDJ status update.", e);
                          }
                      }
                  }
              });
              running.set(true);
              queueHandler.start();
              deliverLifecycleAnnouncement(logger, true);
  
              // If there are already any rekordbox instances on the network, "mount" their collections.
              for (DeviceAnnouncement existingDevice : DeviceFinder.getInstance().getCurrentDevices()) {
                  announcementListener.deviceFound(existingDevice);
              }
          }
      }
docs: Start finding track metadata for all active players. Starts the {@link VirtualCdj} if it is not already
  running, because we need it to send us device status updates to notice when new tracks are loaded; this
  starts the {@link DeviceFinder} (which is also needed by the {@code VirtualCdj}) so we can keep track of
  the comings and goings of players themselves. We start the {@link ConnectionManager} in order to make queries
  to obtain metadata.
  
  @throws Exception if there is a problem starting the required components