public static void main()

in gradle-runner-agent/src/main/java/jetbrains/buildServer/gradle/runtime/TeamCityGradleLauncher.java [32:178]


  public static void main(String[] args) {
    final Map<String, String> gradleEnv = new HashMap<>(System.getenv());

    String gradleParamsFilePath = getSystemEnvValue(gradleEnv, GradleRunnerConstants.GRADLE_PARAMS_FILE_ENV_KEY);
    if (gradleParamsFilePath == null) {
      return;
    }
    final List<String> gradleParams = readParams(gradleParamsFilePath);
    if (gradleParams == null) {
      return;
    }

    String jvmArgsFilePath = getSystemEnvValue(gradleEnv, GradleRunnerConstants.GRADLE_JVM_PARAMS_FILE_ENV_KEY);
    if (jvmArgsFilePath == null) {
      return;
    }
    final List<String> tcJvmArgs = readParams(jvmArgsFilePath);
    if (tcJvmArgs == null) {
      return;
    }

    String gradleTasksPath = getSystemEnvValue(gradleEnv, GradleRunnerConstants.GRADLE_TASKS_FILE_ENV_KEY);
    if (gradleTasksPath == null) {
      return;
    }
    final List<String> gradleTasks = readParams(gradleTasksPath);
    if (gradleTasks == null) {
      return;
    }

    final String workingDir = gradleEnv.get(GradleRunnerConstants.WORKING_DIRECTORY_ENV_KEY);
    if (workingDir == null) {
      System.err.println("Parameter " + GradleRunnerConstants.WORKING_DIRECTORY_ENV_KEY
                         + " must be present in environment variables.");
      return;
    }

    File tcBuildParametersFile = getTcBuildParametersFile(gradleEnv);
    Properties teamCityBuildParameters = getTeamCityBuildParameters(tcBuildParametersFile);
    if (teamCityBuildParameters == null) {
      return;
    }
    String buildTempDir = teamCityBuildParameters.getProperty("teamcity.build.tempDir", "");
    if (buildTempDir.isEmpty()) {
      System.err.println("Parameter teamcity.build.tempDir must be set in teamcity.build.parameters.");
      return;
    }
    String buildNumber = teamCityBuildParameters.getProperty("build.number", "");

    final Boolean useWrapper = Boolean.valueOf(gradleEnv.get(GradleRunnerConstants.USE_WRAPPER_ENV_KEY));
    final String gradleHome = gradleEnv.get(GradleRunnerConstants.GRADLE_HOME_ENV_KEY);
    final String gradleWrapperProperties = gradleEnv.get(GradleRunnerConstants.GRADLE_WRAPPED_DISTRIBUTION_ENV_KEY);

    boolean isDebugModeEnabled = gradleParams.stream().anyMatch(task -> task.equals("-d"));
    GradleToolingLogger logger = new GradleToolingLoggerImpl(isDebugModeEnabled);
    GradleJvmArgsMerger jvmArgsMerger = new GradleJvmArgsMerger(logger);
    String taskOutputDir = buildTempDir + File.separator + BUILD_TEMP_DIR_TASK_OUTPUT_SUBDIR;
    BuildContext buildContext = new BuildContext(tcBuildParametersFile.getAbsolutePath(), taskOutputDir, gradleParamsFilePath, jvmArgsFilePath, gradleTasksPath);
    List<BuildEventListener> eventListeners = new ArrayList<>();
    eventListeners.add(new GradleBuildOutputProcessor(logger, buildContext));
    BuildLifecycleListener buildLifecycleListener = new GradleBuildLifecycleListener(logger, eventListeners, buildContext);
    GradleBuildConfigurator buildConfigurator = new GradleBuildConfigurator(logger);

    try {
      gradleEnv.put(TEAMCITY_BUILD_INIT_PATH, GradleBuildConfigurator.getInitScriptClasspath());
    } catch (IOException e) {
      // use existing TEAMCITY_BUILD_INIT_PATH from GradleToolingApiCommandLineComposer.composeCommandLine
      if (gradleEnv.get(TEAMCITY_BUILD_INIT_PATH) == null) {
        System.err.println("Couldn't launch Gradle via Tooling API: error while trying to build init script classpath");
        return;
      }
    }

    final GradleConnector connector;
    try {
      connector = buildConfigurator.prepareConnector(workingDir, useWrapper, gradleWrapperProperties, gradleHome);
    } catch (Exception e) {
      System.err.println(e.getMessage());
      return;
    }

    try (ProjectConnection connection = connector.connect()) {
      Optional<BuildEnvironment> buildEnvironment = getBuildEnvironment(connection, logger);
      List<String> gradleProjectJvmArgs = buildEnvironment.map(env -> env.getJava().getJvmArguments()).orElseGet(Collections::emptyList);
      boolean allowJvmArgsOverriding = Boolean.parseBoolean(System.getProperty(GRADLE_RUNNER_ALLOW_JVM_ARGS_OVERRIDING_CONFIG_PARAM));

      Collection<String> jvmArgsForOverriding = !allowJvmArgsOverriding || tcJvmArgs.isEmpty()
        ? Collections.emptyList()
        : jvmArgsMerger.mergeJvmArguments(gradleProjectJvmArgs, tcJvmArgs);

      Collection<String> tasksAndParams = Stream.concat(gradleTasks.stream(), gradleParams.stream()).collect(Collectors.toList());

      BuildLauncher launcher = buildConfigurator.prepareBuildExecutor(gradleEnv, tasksAndParams, jvmArgsForOverriding, buildLifecycleListener, buildNumber, connection);

      String buildStartedMessage = composeBuildStartedMessage(buildNumber, tasksAndParams, jvmArgsForOverriding, buildEnvironment.orElse(null), gradleEnv);
      buildLifecycleListener.onStart(new BuildStartedEventImpl(System.currentTimeMillis(), buildStartedMessage));

      // workaround for https://github.com/gradle/gradle/issues/34491, delete when issue fixed
      // shuts down JVM when Gradle build is finished after some timeout
      Optional
        .ofNullable(System.getenv().get(GradleRunnerConstants.GRADLE_TOOLING_API_LAUNCHER_SHUTDOWN_TIMEOUT_SEC_ENV_KEY))
        .map(Integer::parseInt)
        .ifPresent(timeoutSec -> {
          Thread watchdog = new Thread(() -> {
            try {
              GRADLE_CONNECTOR_DISCONNECTED.await();

              // sleep to let the problematic Tooling API thread finish
              // if it happens this daemon thread will be terminated before reaching System.exit(0)
              Thread.sleep(timeoutSec * 1000);
              System.out.printf(
                "##teamcity[message text='Tooling API hang detected: JVM still running %s seconds after Gradle build completed; shutting down' status='WARNING']\n",
                timeoutSec
              );
              System.exit(0);
            } catch (InterruptedException ignored) {
            }
          });
          watchdog.setName("Tooling API shutdown watchdog");
          watchdog.setDaemon(true);
          watchdog.start();
        });

      launcher.run(new ResultHandler<Void>() {
        @Override
        public void onComplete(Void unused) {
          try {
            buildLifecycleListener.onSuccess();
          } finally {
            connector.disconnect();
            GRADLE_CONNECTOR_DISCONNECTED.countDown();
          }
        }

        @Override
        public void onFailure(GradleConnectionException e) {
          try {
            buildLifecycleListener.onFail();
          } finally {
            connector.disconnect();
            GRADLE_CONNECTOR_DISCONNECTED.countDown();
          }
          throw e;
        }
      });
    }
  }