Class AsyncProfilerLoader

java.lang.Object
one.profiler.AsyncProfilerLoader

public final class AsyncProfilerLoader extends Object
Allows to work with the async-profiler libraries and tools stored in the resources folder.

Upon extraction the libraries and tools are stored in an application, version and user specific application folder. The resulting files are therefore cached between executions of the JVM. This folder can be manually specified by either setting the property ap_loader_extraction_dir or by using the setExtractionDirectory(Path)} method.

Running this class as an agent main class, makes it an agent that behaves the same as the libasyncProfiler.so agent. Running the main method exposed the asprof, jattach and jfrconv features.

  • Constructor Details

    • AsyncProfilerLoader

      public AsyncProfilerLoader()
  • Method Details

    • setExtractionDirectory

      public static void setExtractionDirectory(Path extractionDir)
      Returns directory used for storing the extracted libraries, binaries and JARs
    • setVersion

      public static void setVersion(String version) throws IOException
      Set the used version of async-profiler. This is required if there are multiple versions of this library in the dependencies.
      Parameters:
      version - set version of async-profiler to use
      Throws:
      IOException
    • deleteExtractionDirectory

      public static void deleteExtractionDirectory() throws IOException
      Deletes the directory used for extraction
      Throws:
      IOException
    • getExtractionDirectory

      public static Path getExtractionDirectory() throws IOException
      Returns the directory used for storing the extracted libraries, binaries and JARs
      Throws:
      IOException
    • getAvailableVersions

      public static List<String> getAvailableVersions()
      Get available versions of the library
    • getVersion

      public static String getVersion()
      Returns the version of the included async-profiler library (or the version set by setVersion(String)
      Throws:
      IllegalStateException - if the version could not be determined
    • isSupported

      public static boolean isSupported()
      Checks if an async-profiler library for the current OS, architecture and glibc is available in this JAR.
      Returns:
      true if a library is available, false otherwise
    • extractCustomLibraryFromResources

      public static Path extractCustomLibraryFromResources(ClassLoader classLoader, String fileName) throws IOException
      Extracts a custom agent from the resources

      Parameters:
      classLoader - the class loader to load the resources from
      fileName - the name of the file to copy, maps the library name if the fileName does not start with "lib", e.g. "jni" will be treated as "libjni.so" on Linux and as "libjni.dylib" on macOS
      Returns:
      the path of the library
      Throws:
      IOException - if the extraction fails
    • extractCustomLibraryFromResources

      public static Path extractCustomLibraryFromResources(ClassLoader classLoader, String fileName, Path alternativeSource) throws IOException
      Extracts a custom native library from the resources and returns the alternative source if the file is not in the resources.

      If the file is extracted, then it is copied to a new temporary folder which is deleted upon JVM exit.

      This method is mainly seen as a helper method to obtain custom native agents for jattach(Path) and jattach(Path, String). It is included in ap-loader to make it easier to write applications that need custom native libraries.

      This method works on all architectures.

      Parameters:
      classLoader - the class loader to load the resources from
      fileName - the name of the file to copy, maps the library name if the fileName does not start with "lib", e.g. "jni" will be treated as "libjni.so" on Linux and as "libjni.dylib" on macOS
      alternativeSource - the optional resource directory to use if the resource is not found in the resources, this is typically the case when running the application from an IDE, an example would be "src/main/resources" or "target/classes" for maven projects
      Returns:
      the path of the library
      Throws:
      IOException - if the extraction fails and the alternative source is not present for the current architecture
    • getJattachPath

      public static Path getJattachPath() throws IOException
      Extracts the jattach tool
      Returns:
      path to the extracted jattach tool
      Throws:
      IllegalStateException - if OS or arch are not supported
      IOException - if the extraction fails
    • getJfrconvPath

      public static Path getJfrconvPath() throws IOException
      Extracts the jfrconv tool
      Returns:
      path to the extracted jfrconv tool
      Throws:
      IllegalStateException - if OS or arch are not supported
      IOException - if the extraction fails
    • getAsyncProfilerPath

      public static Path getAsyncProfilerPath() throws IOException
      Extracts the async-profiler and returns the path to the extracted file.
      Returns:
      the path to the extracted library
      Throws:
      IOException - if the library could not be loaded
      IllegalStateException - if OS or Arch are not supported
    • executeJattach

      public static AsyncProfilerLoader.ExecutionResult executeJattach(String... args) throws IOException
      See jattach for more information.

      It runs the same as jattach with the only exception that every string that ends with "libasyncProfiler.so" and "libasyncProfiler.dylib" are mapped to the extracted async-profiler library for the load command. One can therefore start/stop the async-profiler via executeJattach(PID, "load", "libasyncProfiler.so", true, "start"/"stop").

      Use the jattach(Path) or jattach(Path, String) to load agents via jattach directly, without the need to construct the command line arguments yourself.

      Throws:
      IOException - if something went wrong (e.g. the jattach binary is not found or the execution fails)
      IllegalStateException - if OS or Arch are not supported
    • jattach

      public static boolean jattach(Path agentPath)
      See jattach for more information.

      It loads the passed agent via jattach to the current JVM, mapping "libasyncProfiler.so" and "libasyncProfiler.dylib" to the extracted async-profiler library for the load command.

      Returns:
      true if the agent was successfully attached, false otherwise
      Throws:
      IllegalStateException - if OS or Arch are not supported
    • jattach

      public static boolean jattach(Path agentPath, String arguments)
      See jattach for more information.

      It loads the passed agent via jattach to the current JVM, mapping "libasyncProfiler.so" and "libasyncProfiler.dylib" to the extracted async-profiler library for the load command.

      Returns:
      true if the agent was successfully attached, false otherwise
      Throws:
      IllegalStateException - if OS or Arch are not supported
    • executeConverter

      public static AsyncProfilerLoader.ExecutionResult executeConverter(String... args) throws IOException
      See Converter Usage for more information.

      Just pass it the arguments that you would normally pass to the JVM after jfrconv

      Throws:
      IOException - if something went wrong (e.g. the execution fails)
      IllegalStateException - if OS or Arch are not supported
    • executeProfiler

      public static AsyncProfilerLoader.ExecutionResult executeProfiler(String... args) throws IOException
      See Profiler Options for more information.

      Throws:
      IOException - if something went wrong (e.g. the execution fails)
      IllegalStateException - if OS or Arch are not supported
    • loadOrNull

      public static AsyncProfiler loadOrNull()
      Loads the included async-profiler for the current OS, architecture and glibc.
      Returns:
      the loaded async-profiler or null if anything went wrong (e.g. unsupported OS)
    • load

      public static AsyncProfiler load() throws IOException
      Loads the included async-profiler for the current OS, architecture and glibc
      Returns:
      the loaded async-profiler
      Throws:
      IOException - if the library could not be loaded
      IllegalStateException - if OS or arch are not supported
    • premain

      public static void premain(String agentArgs, Instrumentation instrumentation)
    • getProcessId

      public static int getProcessId()
      Returns the id of the current process
      Throws:
      IllegalStateException - if the id can not be obtained, this should never happen
    • attach

      public static void attach(String arguments)
      Attach the extracted async-profiler agent to the current JVM.
      Parameters:
      arguments - arguments string passed to the agent, might be null
      Throws:
      IllegalStateException - if the agent could not be attached
    • agentmain

      public static void agentmain(String agentArgs, Instrumentation instrumentation)
    • main

      public static void main(String[] args) throws IOException
      Throws:
      IOException