/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.druid.cli;

import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import org.apache.druid.initialization.Initialization;
import org.apache.druid.java.util.common.lifecycle.Lifecycle;
import org.apache.druid.java.util.common.logger.Logger;
import org.apache.druid.server.log.StartupLoggingConfig;
import org.apache.druid.utils.JvmUtils;

import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 */
public abstract class GuiceRunnable implements Runnable
{
  private final Logger log;

  private Injector baseInjector;

  public GuiceRunnable(Logger log)
  {
    this.log = log;
  }

  /**
   * This method overrides {@link Runnable} just in order to be able to define it as "entry point" for
   * "Unused declarations" inspection in IntelliJ.
   */
  @Override
  public abstract void run();

  @Inject
  public void configure(Injector injector)
  {
    this.baseInjector = injector;
  }

  protected abstract List<? extends Module> getModules();

  public Injector makeInjector()
  {
    try {
      return Initialization.makeInjectorWithModules(baseInjector, getModules());
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  public Lifecycle initLifecycle(Injector injector)
  {
    try {
      final Lifecycle lifecycle = injector.getInstance(Lifecycle.class);
      final StartupLoggingConfig startupLoggingConfig = injector.getInstance(StartupLoggingConfig.class);

      log.info(
          "Starting up with processors[%,d], memory[%,d], maxMemory[%,d], directMemory[%,d].",
          JvmUtils.getRuntimeInfo().getAvailableProcessors(),
          JvmUtils.getRuntimeInfo().getTotalHeapSizeBytes(),
          JvmUtils.getRuntimeInfo().getMaxHeapSizeBytes(),
          JvmUtils.getRuntimeInfo().getDirectMemorySizeBytes()
      );

      if (startupLoggingConfig.isLogProperties()) {
        final Set<String> maskProperties = Sets.newHashSet(startupLoggingConfig.getMaskProperties());
        final Properties props = injector.getInstance(Properties.class);

        for (String propertyName : Ordering.natural().sortedCopy(props.stringPropertyNames())) {
          String property = props.getProperty(propertyName);
          for (String masked : maskProperties) {
            if (propertyName.contains(masked)) {
              property = "<masked>";
              break;
            }
          }
          log.info("* %s: %s", propertyName, property);
        }
      }

      try {
        lifecycle.start();
      }
      catch (Throwable t) {
        log.error(t, "Error when starting up.  Failing.");
        System.exit(1);
      }

      return lifecycle;
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}

@@ -1071,16 +1071,70 @@
 zation;%0A
+import org.apache.druid.java.util.common.StringUtils;%0A
 import o
@@ -2423,24 +2423,272 @@
 ig.class);%0A%0A
+      Long directSizeBytes = null;%0A      try %7B%0A        directSizeBytes = JvmUtils.getRuntimeInfo().getDirectMemorySizeBytes();%0A      %7D%0A      catch (UnsupportedOperationException ignore) %7B%0A        // querying direct memory is not supported%0A      %7D%0A%0A
       log.in
@@ -2767,27 +2767,10 @@
 %25,d%5D
-, directMemory%5B%25,d%5D
+%25s
 .%22,%0A
@@ -2965,49 +2965,82 @@
     
-JvmUtils.getRuntimeInfo().getDirectMemory
+directSizeBytes != null ? StringUtils.format(%22, directMemory%5B%25,d%5D%22, direct
 Size
@@ -3044,18 +3044,22 @@
 izeBytes
-(
 )
+ : %22%22
 %0A      )

Handle exception thrown in log while trying to call sun.misc.VM.maxDirectMemory() which is not available in Java 11 (#8352)