code: public static JobLauncher newJobLauncher(Properties sysProps, Properties jobProps,
        String launcherTypeValue, SharedResourcesBroker<GobblinScopeTypes> instanceBroker, List<? extends Tag<?>> metadataTags) {
      Optional<JobLauncherType> launcherType = Enums.getIfPresent(JobLauncherType.class, launcherTypeValue);
  
      try {
        if (launcherType.isPresent()) {
          switch (launcherType.get()) {
            case LOCAL:
                return new LocalJobLauncher(JobConfigurationUtils.combineSysAndJobProperties(sysProps, jobProps), instanceBroker, metadataTags);
            case MAPREDUCE:
              return new MRJobLauncher(JobConfigurationUtils.combineSysAndJobProperties(sysProps, jobProps), instanceBroker, metadataTags);
            default:
              throw new RuntimeException("Unsupported job launcher type: " + launcherType.get().name());
          }
        }
  
        @SuppressWarnings("unchecked")
        Class<? extends AbstractJobLauncher> launcherClass =
            (Class<? extends AbstractJobLauncher>) Class.forName(launcherTypeValue);
        return launcherClass.getDeclaredConstructor(Properties.class)
            .newInstance(JobConfigurationUtils.combineSysAndJobProperties(sysProps, jobProps));
      } catch (Exception e) {
        throw new RuntimeException("Failed to create job launcher: " + e, e);
      }
    }
docs: Creates a new instance for a JobLauncher with a given type
  @param sysProps          the system/environment properties
  @param jobProps          the job properties
  @param launcherTypeValue the type of the launcher; either a {@link JobLauncherType} value or
  the name of the class that extends {@link AbstractJobLauncher} and has a constructor
  that has a single Properties parameter..
  @param metadataTags additional metadata to be added to timing events
  @return the JobLauncher instance
  @throws RuntimeException if the instantiation fails