/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.mx.loading;
import java.net.URL;
import javax.management.ObjectName;
import javax.management.loading.MLet;
import org.jboss.logging.Logger;
/**
* A RepositoryClassLoader that wraps an MLet.
*
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision: 81022 $
*/
class MLetRepositoryClassLoader extends RepositoryClassLoader
{
// Constants -----------------------------------------------------
/** The log */
private static final Logger log = Logger.getLogger(MLetRepositoryClassLoader.class);
// Attributes -----------------------------------------------------
/** The MLet */
private MLet mlet;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
/**
* Create a new LoaderRepositoryClassLoader
*
* @param urls the urls
* @param parent the parent classloader
*/
protected MLetRepositoryClassLoader(MLet mlet)
{
super(mlet.getURLs(), mlet);
this.mlet = mlet;
}
// Public --------------------------------------------------------
/**
* Get the ObjectName
*
* @return the object name
*/
public ObjectName getObjectName()
{
throw new UnsupportedOperationException("Not relevent");
}
/**
* This method simply invokes the super.getURLs() method to access the
* list of URLs that make up the RepositoryClassLoader classpath.
*
* @return the urls that make up the classpath
*/
public URL[] getClasspath()
{
return mlet.getURLs();
}
/**
* Return all library URLs associated with this RepositoryClassLoader
*
* <p>Do not remove this method without running the WebIntegrationTestSuite
*/
public URL[] getAllURLs()
{
return repository.getURLs();
}
public synchronized Class loadClassImpl(String name, boolean resolve, int stopAt)
throws ClassNotFoundException
{
loadClassDepth ++;
boolean trace = log.isTraceEnabled();
if( trace )
log.trace("loadClassImpl, name="+name+", resolve="+resolve);
if( repository == null )
{
String msg = "Invalid use of destroyed classloader, UCL destroyed at:";
throw new ClassNotFoundException(msg, this.unregisterTrace);
}
/* Since loadClass can be called from loadClassInternal with the monitor
already held, we need to determine if there is a ClassLoadingTask
which requires this UCL. If there is, we release the UCL monitor
so that the ClassLoadingTask can use the UCL.
*/
boolean acquired = attempt(1);
while( acquired == false )
{
/* Another thread needs this UCL to load a class so release the
monitor acquired by the synchronized method. We loop until
we can acquire the class loading lock.
*/
try
{
if( trace )
log.trace("Waiting for loadClass lock");
this.wait();
}
catch(InterruptedException ignore)
{
}
acquired = attempt(1);
}
ClassLoadingTask task = null;
try
{
Thread t = Thread.currentThread();
// Register this thread as owning this UCL
if( loadLock.holds() == 1 )
LoadMgr3.registerLoaderThread(this, t);
// Create a class loading task and submit it to the repository
task = new ClassLoadingTask(name, this, t, stopAt);
/* Process class loading tasks needing this UCL until our task has
been completed by the thread owning the required UCL(s).
*/
UnifiedLoaderRepository3 ulr3 = (UnifiedLoaderRepository3) repository;
if( LoadMgr3.beginLoadTask(task, ulr3) == false )
{
while( task.threadTaskCount != 0 )
{
try
{
LoadMgr3.nextTask(t, task, ulr3);
}
catch(InterruptedException e)
{
// Abort the load or retry?
break;
}
}
}
}
finally
{
// Unregister as the UCL owner to reschedule any remaining load tasks
if( loadLock.holds() == 1 )
LoadMgr3.endLoadTask(task);
// Notify any threads waiting to use this UCL
this.release();
this.notifyAll();
loadClassDepth --;
}
if( task.loadedClass == null )
{
if( task.loadException instanceof ClassNotFoundException )
throw (ClassNotFoundException) task.loadException;
else if( task.loadException != null )
{
if( log.isTraceEnabled() )
log.trace("Unexpected error during load of:"+name, task.loadException);
String msg = "Unexpected error during load of: "+name
+ ", msg="+task.loadException.getMessage();
throw new ClassNotFoundException(msg);
}
// Assert that loadedClass is not null
else
throw new IllegalStateException("ClassLoadingTask.loadedTask is null, name: "+name);
}
return task.loadedClass;
}
// URLClassLoader overrides --------------------------------------
public Class loadClassLocally(String name, boolean resolve)
throws ClassNotFoundException
{
boolean trace = log.isTraceEnabled();
if( trace )
log.trace("loadClassLocally, " + this + " name=" + name);
Class result = null;
try
{
result = mlet.loadClass(name, null);
return result;
}
finally
{
if (trace)
{
if (result != null)
log.trace("loadClassLocally, " + this + " name=" + name + " class=" + result + " cl=" + result.getClassLoader());
else
log.trace("loadClassLocally, " + this + " name=" + name + " not found");
}
}
}
// Object overrides ----------------------------------------------
// Protected -----------------------------------------------------
// Package Private -----------------------------------------------
// Private -------------------------------------------------------
// Inner classes -------------------------------------------------
}