code: public static JvmType createFromJavaHome(final String javaHome, boolean forLaunch) {
          if (javaHome == null || javaHome.trim().equals("")) {
              throw HostControllerLogger.ROOT_LOGGER.invalidJavaHome(javaHome);
          }
          final File javaHomeDir = new File(javaHome);
          if (forLaunch && !javaHomeDir.exists()) {
              throw HostControllerLogger.ROOT_LOGGER.invalidJavaHome(javaHomeDir.getAbsolutePath());
          }
          final File javaBinDir = new File(javaHomeDir, BIN_DIR);
          if (forLaunch && !javaBinDir.exists()) {
              throw HostControllerLogger.ROOT_LOGGER.invalidJavaHomeBin(javaBinDir.getAbsolutePath(), javaHomeDir.getAbsolutePath());
          }
          final File javaExecutable = new File(javaBinDir, JAVA_EXECUTABLE);
          if (forLaunch && !javaExecutable.exists()) {
              throw HostControllerLogger.ROOT_LOGGER.cannotFindJavaExe(javaBinDir.getAbsolutePath());
          }
          return new JvmType(forLaunch, isModularJvm(javaExecutable.getAbsolutePath(), forLaunch), javaExecutable.getAbsolutePath());
      }
docs: Create a {@code JvmType} based on the location of the root dir of the JRE/JDK installation.
  @param javaHome the root dir of the JRE/JDK installation. Cannot be {@code null} or empty
  @param forLaunch {@code true} if the created object will be used for launching servers; {@code false}
  if it is simply a data holder. A value of {@code true} will disable
  some validity checks and may disable determining if the JVM is modular
  @return the {@code JvmType}. Will not return {@code null}
  
  @throws IllegalStateException if the {@code JvmType} cannot be determined.