private static void premainImpl(String agentArgs, Instrumentation inst) {
    log("");
    log("Starting LogLoadedApplicationClassesAgent: " + agentArgs);
    log("");

    String targetFileName = System.getenv().get(TARGET_FILE);
    boolean useAppCDS = Boolean.parseBoolean(System.getenv().getOrDefault(USE_APP_CDS, "true"));

    if (targetFileName == null) {
      log("Failed to find " + TARGET_FILE + " parameter to -javaagentpath");
      return;
    }

    File targetFile = new File(targetFileName);
    //noinspection ResultOfMethodCallIgnored
    targetFile.getParentFile().mkdirs();

    final TransitiveClassesCollector myAllClasses = new TransitiveClassesCollector();

    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(r -> {
      Thread thread = new Thread(r, "LogLoadedApplicationClassesAgent-watcher");
      thread.setDaemon(true);
      return thread;
    });

    executor.scheduleWithFixedDelay(() -> myAllClasses.addClasses(inst), 0, 20, TimeUnit.MILLISECONDS);

    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      log("Shutdown is started...");
      executor.shutdown();
      try {
        executor.awaitTermination(2, TimeUnit.SECONDS);
      }
      catch (InterruptedException e) {
        log("Failed to wait for classes dump thread termination", e);
      }

      logDetectedClasses(useAppCDS, targetFile, myAllClasses.getAllClasses());
    }, "LogLoadedApplicationClassesAgent-shutdown"));

    log("LogLoadedApplicationClassesAgent was configured");
  }
private static void premainImpl(String agentArgs, Instrumentation inst)