All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.quartzdesk.api.ApiDebug Maven / Gradle / Ivy

Go to download

QuartzDesk Public API library required for QuartzDesk Standard and Enterprise edition installations. This library must be placed on the classpath of the Quartz scheduler based application that is managed by QuartzDesk. It is important that this library is loaded by the same classloader that loads the Quartz scheduler API used by the application.

There is a newer version: 5.0.3
Show newest version
/*
 * Copyright (c) 2013-2019 QuartzDesk.com. All Rights Reserved.
 * QuartzDesk.com PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.quartzdesk.api;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;

/**
 * Various debugging utility methods.
 *
 * @author [email protected] - the author of the original class info related methods.
 */
public final class ApiDebug
{
  /**
   * Private constructor of a utility class.
   */
  private ApiDebug()
  {
  }


  /**
   * Returns detailed info about the given class such as its name, interfaces, code source, and class loader.
   *
   * @param clazz the class.
   * @return the class info as a string.
   */
  public static String getClassInfo( Class clazz )
  {
    StringBuilder sb = new StringBuilder();

    ClassLoader cl = clazz.getClassLoader();
    sb.append( clazz.getName() );

    CodeSource clazzCS = clazz.getProtectionDomain().getCodeSource();
    sb.append( ", code source: " ).append( clazzCS );

    sb.append( ApiConst.NL ).append( "class loader:" ).append( ApiConst.NL );
    sb.append( getClassLoaderInfo( cl ) );

    sb.append( ApiConst.NL ).append( "interfaces:" );
    Class[] ifaces = clazz.getInterfaces();
    for ( Class iface : ifaces )
    {
      sb.append( ApiConst.NL ).append( "  " ).append( iface );
      ClassLoader loader = iface.getClassLoader();
      sb.append( ApiConst.NL ).append( "    class loader: " ).append( loader );
      ProtectionDomain pd = iface.getProtectionDomain();
      CodeSource cs = pd.getCodeSource();
      sb.append( ApiConst.NL ).append( "    code source: " ).append( cs );
    }

    sb.append( ApiConst.NL ).append( "ctx class loader:" ).append( ApiConst.NL );
    sb.append( getClassLoaderInfo( Thread.currentThread().getContextClassLoader() ) );

    return sb.toString();
  }


  /**
   * Dumps out info on the specified class loader. The dump describes the entire class loader hierarchy starting at the
   * specified class loader.
   *
   * @param cl a class loader.
   * @return the class loader info in a string.
   */
  public static String getClassLoaderInfo( ClassLoader cl )
  {
    StringBuilder sb = new StringBuilder();

    ClassLoader parent = cl;

    while ( parent != null )
    {
      sb.append( parent );
      URL[] urls = getClassLoaderURLs( parent );

      if ( urls != null )
      {
        if ( urls.length == 0 )
          sb.append( ApiConst.NL ).append( "  empty URLs" );

        for ( URL url : urls )
          sb.append( ApiConst.NL ).append( "  " ).append( url );
      }
      else
      {
        sb.append( ApiConst.NL ).append( "  no URLs" );
      }

      parent = parent.getParent();

      if ( parent != null )
        sb.append( ApiConst.NL );
    }

    return sb.toString();
  }


  /**
   * Use reflection to access a URL[] getURLs or ULR[] getAllURLs method so that non-URLClassLoader class loaders, or
   * class loaders that override getURLs to return null or empty, can provide the true classpath info.
   *
   * @param cl a class loader.
   * @return the classloader URLs.
   */
  public static URL[] getClassLoaderURLs( ClassLoader cl )
  {
    URL[] urls = {};
    try
    {
      Class returnType = urls.getClass();
      Class[] parameterTypes = {};
      Method getURLs = cl.getClass().getMethod( "getURLs", parameterTypes );
      if ( returnType.isAssignableFrom( getURLs.getReturnType() ) )
      {
        Object[] args = {};
        urls = (URL[]) getURLs.invoke( cl, args );
      }
    }
    catch ( NoSuchMethodException ignore )
    {
      // can happen for class loaders not derived from java.net.URLClassLoader
    }
    catch ( IllegalAccessException ignore )
    {
      // should not happen
    }
    catch ( InvocationTargetException ignore )
    {
      // should not happen
    }
    return urls;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy