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

org.rhq.bindings.util.ClassPoolFactory Maven / Gradle / Ivy

Go to download

Abstraction of different facilities and default configurations for script bindings

The newest version!
/*
 * RHQ Management Platform
 * Copyright (C) 2013 Red Hat, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation, and/or the GNU Lesser
 * General Public License, version 2.1, also as published by the Free
 * Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License and the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License
 * and the GNU Lesser General Public License along with this program;
 * if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

package org.rhq.bindings.util;

import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.LoaderClassPath;

/**
 * This class is used to create Javassist's classpools usable in RHQ on both client and server side. This only exists to
 * centralize the initialization code for the pools.
 *
 * 

This is to ensure that Javassist can locate the classes in various classloading "schemes" - the traditional * application classloader used in the CLI client and the JBoss Modules classloading used on the server. * * @author Lukas Krejci */ public class ClassPoolFactory { /** * A simple extension of a standard Javassist's class pool that makes sure that the classes are defined using a * specified classloader. * *

The default implementation always defines a class in the current context classloader, which theoretically * might not be the same as the classloader that we requested the class pool for in the {@link * #getClassPoolForCurrentContextClassLoader()} method. * *

This class pool searches for classes using the provided class loader by default. */ private static class ClassLoaderBoundClassPool extends ClassPool { private WeakReference classLoader; public ClassLoaderBoundClassPool(ClassLoader classLoader) { this.classLoader = new WeakReference(classLoader); this.insertClassPath(new LoaderClassPath(classLoader)); } @Override public ClassLoader getClassLoader() { ClassLoader cl = classLoader.get(); if (cl == null) { throw new IllegalStateException("The bound classloader has been garbage collected."); } return cl; } } /** * A cache of ClassPools, each for a classloader */ private static final WeakHashMap CLASS_POOL_PER_CLASS_LOADER = new WeakHashMap(); private ClassPoolFactory() { } /** * Returns a class pool that uses the provided class loader as its source for the "class path". Each class loader * will have exactly one class pool and the class pool will use the class loader to define the classes. This is to * ensure that there exists a consistent correspondence between the classes cached by the class pool with the ones * defined by the class loader and no linkage error can occur due to the possible attempts to define a single class * multiple times using a single class loader. * *

If the provided class loader is null, a default instance is used. * * @param classLoader the class loader to return the class pool for * @return */ public static ClassPool getClassPool(ClassLoader classLoader) { synchronized (CLASS_POOL_PER_CLASS_LOADER) { ClassPool ret = CLASS_POOL_PER_CLASS_LOADER.get(classLoader); if (ret == null) { ret = classLoader == null ? new ClassPool() : new ClassLoaderBoundClassPool(classLoader); initClassPool(ret); CLASS_POOL_PER_CLASS_LOADER.put(classLoader, ret); } return ret; } } /** * Unlike the ClassPool.getDefault() method that only ever returns a single instance of the pool, this * factory may return different instances depending on the context classloader of the current thread. The returned * class pool is using the current thread context class loader to locate the classes but also is using the default * resource lookup of the Class class, in addition to just the system class path as detected by * Javassist (which is the only one used in the class pool returned by ClassPool.getDefault()). * * @return the class pool instance for the current context classloader * @see #getClassPool(ClassLoader) */ public static ClassPool getClassPoolForCurrentContextClassLoader() { return getClassPool(Thread.currentThread().getContextClassLoader()); } private static void initClassPool(ClassPool classPool) { classPool.appendClassPath(new ClassClassPath(ClassPoolFactory.class)); classPool.appendSystemPath(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy