/** * Copyright (C) 2009-2013 Barchart, Inc. <http://www.barchart.com/> * * All rights reserved. Licensed under the OSI BSD License. * * http://www.opensource.org/licenses/bsd-license.php */ package bench.libs; import java.lang.reflect.Field; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Vector; public class ClassScope { private static final String[] EMPTY_LIBRARY_ARRAY = new String[] {}; private static final Throwable CVF_FAILURE; // set in <clinit> static { Throwable failure = null; Field field = null; try { // this can fail if this is not a Sun-compatible JVM // or if the security is too tight: field = ClassLoader.class.getDeclaredField("loadedLibraryNames"); if (field.getType() != Vector.class) { throw new RuntimeException("not of type java.util.Vector: " + field.getType().getName()); } field.setAccessible(true); } catch (Throwable t) { failure = t; } LIBRARIES_VECTOR_FIELD = field; CVF_FAILURE = failure; failure = null; } /** * Given a class loader instance, returns all native libraries currently * loaded by that class loader. * * @param defining * class loader to inspect [may not be null] * @return Libraries loaded in this class loader [never null, may be empty] * * @throws RuntimeException * if the "loadedLibraryNames" field hack is not possible in * this JRE */ @SuppressWarnings("unchecked") public static String[] getLoadedLibraries(final ClassLoader loader) { if (loader == null) { throw new IllegalArgumentException("null input: loader"); } if (LIBRARIES_VECTOR_FIELD == null) { throw new RuntimeException( "ClassScope::getLoadedLibraries() cannot be used in this JRE", CVF_FAILURE); } try { final Vector<String> libraries = (Vector<String>) LIBRARIES_VECTOR_FIELD .get(loader); if (libraries == null) { return EMPTY_LIBRARY_ARRAY; } final String[] result; // note: Vector is synchronized in Java 2, which helps us make // the following into a safe critical section: synchronized (libraries) { result = libraries.toArray(new String[] {}); } return result; } // this should not happen if <clinit> was successful: catch (IllegalAccessException e) { e.printStackTrace(System.out); return EMPTY_LIBRARY_ARRAY; } } /** * A convenience multi-loader version of * {@link #getLoadedLibraries(ClassLoader)}. * * @param an * array of defining class loaders to inspect [may not be null] * @return String array [never null, may be empty] * * @throws RuntimeException * if the "loadedLibrayNames" field hack is not possible in this * JRE */ public static String[] getLoadedLibraries(final ClassLoader[] loaders) { if (loaders == null) { throw new IllegalArgumentException("null input: loaders"); } final List<String> resultList = new LinkedList<String>(); for (int l = 0; l < loaders.length; ++l) { final ClassLoader loader = loaders[l]; if (loader != null) { final String[] libraries = getLoadedLibraries(loaders[l]); resultList.addAll(Arrays.asList(libraries)); } } final String[] result = new String[resultList.size()]; resultList.toArray(result); return result; } // this class is not extendible private ClassScope() { } // set in <clinit> [can be null] private static final Field LIBRARIES_VECTOR_FIELD; }