Repository: open-telemetry/opentelemetry-java
File: sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/AutoConfiguredOpenTelemetrySdkBuilder.java (Java)

Code before:
    if (config == null) {
      config = computeConfigProperties();
    }
    return config;
  }

  private ConfigProperties computeConfigProperties() {
    DefaultConfigProperties properties = DefaultConfigProperties.create(propertiesSupplier.get());
    for (Function<ConfigProperties, Map<String, String>> customizer : propertiesCustomizers) {
      Map<String, String> overrides = customizer.apply(properties);
      properties = properties.withOverrides(overrides);
    }
    return configPropertiesCustomizer.apply(properties);
  }

  // Visible for testing
  @SuppressWarnings("SystemOut")
  Thread shutdownHook(OpenTelemetrySdk sdk) {
    return new Thread(
        () -> {
          try {
            sdk.close();
          } catch (NoClassDefFoundError e) {
            // https://github.com/open-telemetry/opentelemetry-java/issues/6827
            // logging deps might not be on the classpath at this point
            System.out.printf("%s Flush failed during shutdown: %s%n", Level.WARNING, e);
          }
        });
  }

  private static <I, O1, O2> BiFunction<I, ConfigProperties, O2> mergeCustomizer(
      BiFunction<? super I, ConfigProperties, ? extends O1> first,
      BiFunction<? super O1, ConfigProperties, ? extends O2> second) {
    return (I configured, ConfigProperties config) -> {
      O1 firstResult = first.apply(configured, config);
      return second.apply(firstResult, config);
    };
  }

  private static Supplier<Map<String, String>> mergeProperties(
      Supplier<Map<String, String>> first, Supplier<Map<String, String>> second) {
    return () -> {
      Map<String, String> merged = new HashMap<>();
      merged.putAll(first.get());
      merged.putAll(second.get());
      return merged;
    };
  }
}


Review comment (bug):
So, although this might all be true in one very narrow case, it seems very non-obvious that a) flush is what would have failed (since `close()` was called, and it might do more than that), and are we sure that `NoClassDefFoundError` is the only thing we want to catch here? This feels like a bandaid, and if we want this band-aid, we should make it more comprehensive, and not assume the one narrow case we've run into so far.

Code after:
            Level.WARNING, "Error invoking listener " + listener.getClass().getName(), throwable);
      }
    }
  }

  @SuppressWarnings("deprecation") // Support deprecated SdkTracerProviderConfigurer
  void mergeSdkTracerProviderConfigurer() {
    for (io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer configurer :
        componentLoader.load(
            io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer.class)) {
      addTracerProviderCustomizer(
          (builder, config) -> {
            configurer.configure(builder, config);
            return builder;
          });
    }
  }

  private ConfigProperties getConfig() {
    ConfigProperties config = this.config;
    if (config == null) {
      config = computeConfigProperties();
    }
    return config;
  }

  private ConfigProperties computeConfigProperties() {
    DefaultConfigProperties properties =
        DefaultConfigProperties.create(propertiesSupplier.get(), componentLoader);
    for (Function<ConfigProperties, Map<String, String>> customizer : propertiesCustomizers) {
      Map<String, String> overrides = customizer.apply(properties);
      properties = properties.withOverrides(overrides);
    }
    return configPropertiesCustomizer.apply(properties);
  }

  // Visible for testing
  @SuppressWarnings("SystemOut")
  Thread shutdownHook(OpenTelemetrySdk sdk) {
    return new Thread(
        () -> {
          try {
            sdk.close();
          } catch (Throwable e) {
            // https://github.com/open-telemetry/opentelemetry-java/issues/6827
            // logging deps might not be on the classpath at this point
            System.out.printf("%s Flush failed during shutdown: %s%n", Level.WARNING, e);
          }
        });
  }