001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.util;
006
007import java.io.IOException;
008
009/** Loads a native library at runtime. */
010public final class RuntimeLoader {
011  /**
012   * Returns a load error message given the information in the provided UnsatisfiedLinkError.
013   *
014   * @param libraryName the name of the library that failed to load.
015   * @param ule UnsatisfiedLinkError object.
016   * @return A load error message.
017   */
018  private static String getLoadErrorMessage(String libraryName, UnsatisfiedLinkError ule) {
019    String jvmLocation = ProcessHandle.current().info().command().orElse("Unknown");
020    StringBuilder msg = new StringBuilder(512);
021    msg.append(libraryName)
022        .append(" could not be loaded from path.\n" + "\tattempted to load for platform ")
023        .append(CombinedRuntimeLoader.getPlatformPath())
024        .append("\nLast Load Error: \n")
025        .append(ule.getMessage())
026        .append('\n')
027        .append(String.format("JVM Location: %s\n", jvmLocation));
028    if (System.getProperty("os.name").startsWith("Windows")) {
029      msg.append(
030          "A common cause of this error is using a JVM with an incorrect MSVC runtime.\n"
031              + "Ensure you are using the WPILib JVM (The current running JVM is listed above)\n"
032              + "See https://wpilib.org/jvmruntime for more information\n");
033    }
034    return msg.toString();
035  }
036
037  /**
038   * Loads a native library.
039   *
040   * @param libraryName the name of the library to load.
041   * @throws IOException if the library fails to load
042   */
043  public static void loadLibrary(String libraryName) throws IOException {
044    try {
045      System.loadLibrary(libraryName);
046    } catch (UnsatisfiedLinkError ule) {
047      throw new IOException(getLoadErrorMessage(libraryName, ule));
048    }
049  }
050
051  private RuntimeLoader() {
052    throw new IllegalStateException("This class shouldn't be instantiated");
053  }
054}