Author: jason.greene(a)jboss.com
Date: 2006-11-15 22:13:56 -0500 (Wed, 15 Nov 2006)
New Revision: 1443
Modified:
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/AbstractJSEDeployer.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXRPCDeployerJSE.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointPublisher.java
trunk/src/main/java/org/jboss/ws/integration/tomcat/wspublish.java
trunk/src/main/java/org/jboss/ws/jaxws/DynamicWrapperGenerator.java
trunk/src/main/java/org/jboss/ws/soap/attachment/SwapableMemoryDataSource.java
trunk/src/main/java/org/jboss/ws/utils/IOUtils.java
trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java
Log:
JBCTS-410 Rework deployers to use relativeOrder correctly
Switch to a delegate deployment classloader
Detect and handle RepositoryClassLoader blacklists when performing dynamic class creation
Modified:
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java 2006-11-16
00:37:11 UTC (rev 1442)
+++
trunk/src/main/java/org/jboss/ws/deployment/AbstractServiceEndpointPublisher.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -23,7 +23,10 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
@@ -33,8 +36,11 @@
import org.jboss.logging.Logger;
import org.jboss.ws.WSException;
+import org.jboss.ws.server.ServerConfig;
+import org.jboss.ws.server.ServerConfigFactory;
import org.jboss.ws.utils.DOMUtils;
import org.jboss.ws.utils.DOMWriter;
+import org.jboss.ws.utils.IOUtils;
import org.w3c.dom.Element;
/**
@@ -71,7 +77,7 @@
public abstract String destroyServiceEndpoint(URL warURL) throws Exception;
- public URL rewriteWebXML(URL warURL)
+ public URL rewriteWarWebXml(URL warURL)
{
File warFile = new File(warURL.getFile());
if (warFile.isDirectory() == false)
@@ -83,11 +89,6 @@
try
{
- Element root = DOMUtils.parse(new FileInputStream(webXML));
-
- String warName = warFile.getName();
- Map<String, String> sepTargetMap = modifyServletConfig(root, warName);
-
// After redeployment there might be a stale copy of the original
web.xml.org,
we delete it
File orgWebXML = new File(webXML.getCanonicalPath() + ".org");
orgWebXML.delete();
@@ -96,11 +97,8 @@
if (webXML.renameTo(orgWebXML) == false)
throw new WSException("Cannot rename web.xml: " + orgWebXML);
- FileOutputStream fos = new FileOutputStream(webXML);
- new DOMWriter(fos).setPrettyprint(true).print(root);
- fos.close();
-
- return warURL;
+ FileInputStream stream = new FileInputStream(orgWebXML);
+ return rewriteWebXml(stream, webXML).toURL();
}
catch (RuntimeException rte)
{
@@ -112,8 +110,27 @@
}
}
- private Map<String, String> modifyServletConfig(Element root, String warName)
+ public File rewriteWebXml(InputStream source, File dest) throws IOException,
FileNotFoundException
{
+ if (dest == null)
+ {
+ dest = File.createTempFile("jbossws-alt-web", "xml",
IOUtils.createTempDirectory());
+ dest.deleteOnExit();
+ }
+
+ Element root = DOMUtils.parse(source);
+ modifyServletConfig(root);
+
+ FileOutputStream fos = new FileOutputStream(dest);
+ new DOMWriter(fos).setPrettyprint(true).print(root);
+ fos.flush();
+ fos.close();
+
+ return dest;
+ }
+
+ private Map<String, String> modifyServletConfig(Element root)
+ {
Map<String, String> sepTargetMap = new HashMap<String, String>();
Iterator itServlets = DOMUtils.getChildElements(root, "servlet");
@@ -132,7 +149,7 @@
String targetBeanName = null;
- // Nothing to do if we have an <init-param>
+ // Nothing to do if we have an <init-param>
if (isAlreadyModified(servletElement) == false)
{
// Check if it is a real servlet that we can ignore
Modified: trunk/src/main/java/org/jboss/ws/integration/jboss50/AbstractJSEDeployer.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/integration/jboss50/AbstractJSEDeployer.java 2006-11-16
00:37:11 UTC (rev 1442)
+++
trunk/src/main/java/org/jboss/ws/integration/jboss50/AbstractJSEDeployer.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -22,7 +22,9 @@
package org.jboss.ws.integration.jboss50;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
@@ -39,8 +41,8 @@
import org.jboss.metadata.NameValuePair;
import org.jboss.metadata.WebMetaData;
import org.jboss.metadata.web.Servlet;
-import org.jboss.util.file.Files;
import org.jboss.virtual.VirtualFile;
+import org.jboss.ws.WSException;
import org.jboss.ws.deployment.UnifiedDeploymentInfo;
import org.jboss.ws.server.ServerConfig;
import org.jboss.ws.server.ServerConfigFactory;
@@ -55,62 +57,44 @@
* @author Thomas.Diesler(a)jboss.org
* @since 31-Oct-2006
*/
-public abstract class AbstractJSEDeployer extends AbstractDeployer
+public abstract class AbstractJSEDeployer extends AbstractDeployer
{
- // The URL the expanded webapp in the deployment unit
- public static final String JBOSSWS_EXPANDED_WAR_URL =
"jbossws.expanded.war.url";
// The servlet init param in web.xml that is the service endpoint class
public static final String INIT_PARAM_SERVICE_ENDPOINT_IMPL =
"ServiceEndpointImpl";
- /** Install an annotation class loader, if there is none already
- */
- @Override
- public void deploy(DeploymentUnit unit) throws DeploymentException
+ public AbstractJSEDeployer()
{
- Set<? extends WebMetaData> allMetaData =
unit.getAllMetaData(WebMetaData.class);
- if (allMetaData.size() > 0)
- {
- boolean removeLoader = false;
- try
- {
- unit.getClassLoader();
- }
- catch (Exception ex)
- {
- unit.getDeploymentContext().createClassLoader(new
WebAppClassLoaderFactory());
- removeLoader = true;
- }
- try
- {
- super.deploy(unit);
- }
- finally
- {
- if (removeLoader == true)
- unit.getDeploymentContext().removeClassLoader();
- }
- }
+ super();
+ super.setRelativeOrder(CLASSLOADER_DEPLOYER + 1);
}
- /** Create the unified deployment info and create and start th eservice endpoints
- * through the ServiceEndpointDeployer
+ /** Create the unified deployment info and create and start th eservice endpoints
+ * through the ServiceEndpointDeployer
*/
@Override
protected void deployWebServiceDeployment(DeploymentUnit unit) throws
DeploymentException
{
// Call the super implementation
super.deployWebServiceDeployment(unit);
-
+
// FIXME: JBAS-3812 - TomcatDeployment should use modified WebMetaData
- URL expWebAppURL = expandWebDeployment(unit);
- if (expWebAppURL != null)
+ String altDD = generateAltDD(unit);
+
+ // modify the WebMetaData
+ modifyWebMetaData(unit, altDD);
+ }
+
+ private String generateAltDD(DeploymentUnit unit)
+ {
+ try
{
- getServiceEndpointPublisher().rewriteWebXML(expWebAppURL);
- unit.addAttachment(JBOSSWS_EXPANDED_WAR_URL, expWebAppURL);
+ InputStream stream =
unit.getDeploymentContext().getRoot().findChild("WEB-INF/web.xml").openStream();
+ return getServiceEndpointPublisher().rewriteWebXml(stream, null).toString();
}
-
- // modify the WebMetaData
- modifyWebMetaData(unit);
+ catch (Exception e)
+ {
+ throw new WSException("Could not generate alternate deployment
descriptor", e);
+ }
}
@Override
@@ -118,16 +102,9 @@
{
// Call the super implementation
super.undeployWebServiceDeployment(unit, udi);
-
- // FIXME: JBAS-3812 - TomcatDeployment should use modified WebMetaData
- URL warURL = (URL)unit.getAttachment(JBOSSWS_EXPANDED_WAR_URL);
- if (warURL != null)
- {
- Files.delete(new File(warURL.getFile()));
- }
}
- private void modifyWebMetaData(DeploymentUnit unit) throws DeploymentException
+ private void modifyWebMetaData(DeploymentUnit unit, String altDD) throws
DeploymentException
{
try
{
@@ -146,7 +123,7 @@
Class<?> servletClass = anLoader.loadClass(className);
if (servletClass.isAnnotationPresent(WebService.class))
{
- // Nothing to do if we have an <init-param>
+ // Nothing to do if we have an <init-param>
if (isAlreadyModified(servlet) == false)
{
servlet.setServletClass(serviceEndpointServlet);
@@ -154,6 +131,8 @@
servlet.addInitParam(initParam);
}
}
+ // FIXME: JBAS-3812 - TomcatDeployment should use modified WebMetaData
+ webMetaData.setAltDDPath(altDD);
}
}
}
Modified: trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java 2006-11-16
00:37:11 UTC (rev 1442)
+++
trunk/src/main/java/org/jboss/ws/integration/jboss50/DeploymentInfoAdaptor.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -22,6 +22,7 @@
package org.jboss.ws.integration.jboss50;
import java.net.URL;
+import java.net.URLClassLoader;
import java.util.Set;
import org.jboss.deployers.spi.deployer.DeploymentUnit;
@@ -56,15 +57,10 @@
udi.url = getDeploymentURL(unit);
udi.metaData = buildMetaData(unit);
- // FIXME - parent deployments really don't need a classloader since the
classpath
- // is built via the VFS
- try
- {
- udi.classLoader = unit.getClassLoader();
- }
- catch (IllegalStateException e)
- {
- }
+ // Since we create temporary classes, we need to create a delegate loader
+ // This prevents CCE problems where the parent loader is available at deploy time,
+ // and a child loader is available at start time.
+ udi.classLoader = new URLClassLoader(new URL[]{}, unit.getClassLoader());
log.debug("UnifiedDeploymentInfo:\n" + udi);
Modified: trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXRPCDeployerJSE.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXRPCDeployerJSE.java 2006-11-16
00:37:11 UTC (rev 1442)
+++ trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXRPCDeployerJSE.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -39,18 +39,12 @@
*/
public class JAXRPCDeployerJSE extends AbstractJSEDeployer
{
- // The default relative order after the JBossWebAppParsingDeployer
- public int getRelativeOrder()
- {
- return PARSER_DEPLOYER + 3;
- }
-
@Override
protected DeploymentType getDeploymentType()
{
return DeploymentType.JSR109_JSE;
}
-
+
@Override
public boolean isWebServiceDeployment(DeploymentUnit unit)
{
@@ -66,7 +60,7 @@
DeploymentInfoAdaptor.buildDeploymentInfo(udi, unit);
return udi;
}
-
+
private URL getWebServicesURL(DeploymentUnit unit)
{
VirtualFile vfile = unit.getMetaDataFile("webservices.xml");
@@ -77,7 +71,7 @@
String urlStr = vfile.toURL().toExternalForm();
if (urlStr.startsWith("jar:") &&
urlStr.endsWith("!/"))
urlStr = urlStr.substring(4, urlStr.length() - 2);
-
+
return new URL(urlStr);
}
catch (Exception ex)
Modified: trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java 2006-11-16
00:37:11 UTC (rev 1442)
+++ trunk/src/main/java/org/jboss/ws/integration/jboss50/JAXWSDeployerJSE.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -45,19 +45,13 @@
public class JAXWSDeployerJSE extends AbstractJSEDeployer
{
private DeploymentType deploymentType;
-
- // The default relative order after the JBossWebAppParsingDeployer
- public int getRelativeOrder()
- {
- return PARSER_DEPLOYER + 3;
- }
@Override
protected DeploymentType getDeploymentType()
{
return deploymentType;
}
-
+
@Override
public boolean isWebServiceDeployment(DeploymentUnit unit)
{
Modified:
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointPublisher.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointPublisher.java 2006-11-16
00:37:11 UTC (rev 1442)
+++
trunk/src/main/java/org/jboss/ws/integration/jboss50/ServiceEndpointPublisher.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -65,7 +65,7 @@
{
log.debug("publishServiceEndpoint: " + warURL);
- rewriteWebXML(warURL);
+ rewriteWarWebXml(warURL);
DeploymentContext context = createDeploymentContext(warURL);
mainDeployer.addDeploymentContext(context);
Modified: trunk/src/main/java/org/jboss/ws/integration/tomcat/wspublish.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/integration/tomcat/wspublish.java 2006-11-16 00:37:11
UTC (rev 1442)
+++ trunk/src/main/java/org/jboss/ws/integration/tomcat/wspublish.java 2006-11-16 03:13:56
UTC (rev 1443)
@@ -69,7 +69,7 @@
TomcatServiceEndpointPublisher publisher = new TomcatServiceEndpointPublisher();
publisher.setServiceEndpointServlet(servletName);
- publisher.rewriteWebXML(tmpDir.toURL());
+ publisher.rewriteWarWebXml(tmpDir.toURL());
File outFile = new File(destDir.getCanonicalPath() + "/" + warName);
outFile.getParentFile().mkdirs();
Modified: trunk/src/main/java/org/jboss/ws/jaxws/DynamicWrapperGenerator.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/jaxws/DynamicWrapperGenerator.java 2006-11-16
00:37:11 UTC (rev 1442)
+++ trunk/src/main/java/org/jboss/ws/jaxws/DynamicWrapperGenerator.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -90,7 +90,7 @@
throw new WSException("Cannot generate a type when their is no wrapper
parameters");
log.debug("Generating wrapper: " + wrapperName);
-
+
QName xmlName = pmd.getXmlName();
QName xmlType = pmd.getXmlType();
@@ -105,12 +105,13 @@
addProperty(clazz, parameter.getType(), parameter.getName(),
parameter.getVariable(), parameter.getTypeArguments());
}
pool.toClass(clazz, loader);
+ JavaUtils.clearBlacklists(loader);
}
catch (Exception e)
{
throw new WSException("Could not generate wrapper type: " +
wrapperName, e);
}
-
+
// Add the generated type to the types meta data
TypesMetaData types =
opMetaData.getEndpointMetaData().getServiceMetaData().getTypesMetaData();
types.addTypeMapping(new TypeMappingMetaData(types, xmlType, wrapperName));
@@ -137,6 +138,7 @@
addProperty(clazz, properties.get(property).getName(), new QName(property),
property, null);
pool.toClass(clazz, loader);
+ JavaUtils.clearBlacklists(loader);
}
catch (Exception e)
{
Modified: trunk/src/main/java/org/jboss/ws/soap/attachment/SwapableMemoryDataSource.java
===================================================================
---
trunk/src/main/java/org/jboss/ws/soap/attachment/SwapableMemoryDataSource.java 2006-11-16
00:37:11 UTC (rev 1442)
+++
trunk/src/main/java/org/jboss/ws/soap/attachment/SwapableMemoryDataSource.java 2006-11-16
03:13:56 UTC (rev 1443)
@@ -33,44 +33,43 @@
import org.jboss.logging.Logger;
import org.jboss.ws.WSException;
-import org.jboss.ws.server.ServerConfig;
-import org.jboss.ws.server.ServerConfigFactory;
+import org.jboss.ws.utils.IOUtils;
/**
* A datasource which offloads large attachments to disk.
- *
+ *
* @author Thomas.Diesler(a)jboss.org
* @author <a href="mailto:jason@stacksmash.com">Jason T.
Greene</a>
*/
public class SwapableMemoryDataSource implements DataSource
{
private static Logger log = Logger.getLogger(SwapableMemoryDataSource.class);
-
+
private static final int BLOCK_SIZE = 32 * 1024;
-
+
private static final int DEFAULT_MAX_MEMORY_SIZE = 64 * 1024;
-
+
private static final String SWAP_PREFIX = "JBossWSsattachment";
-
+
private static final String SWAP_SUFFIX = ".dat";
-
+
private File swapFile;
-
+
private String contentType = MimeConstants.TYPE_APPLICATION_OCTET_STREAM;
-
+
private byte[] content;
-
+
private int contentLength;
-
- private int maxMemorySize = 64 * 1024;
-
-
+
+ private int maxMemorySize = 64 * 1024;
+
+
/**
* Constructs a <code>SwapableMemoryDataSource</code> from inputStream,
and contentType.
* The instance then reads from the input stream, and stores it in memory unless the
size
- * of the content is larger that 64KB, at whichpoint the stream is stored in a
temporary
+ * of the content is larger that 64KB, at whichpoint the stream is stored in a
temporary
* file on disk.
- *
+ *
* @param inputStream the stream to read from
* @param contentType the content type of this stream
*/
@@ -78,47 +77,44 @@
{
this(inputStream, contentType, DEFAULT_MAX_MEMORY_SIZE);
}
-
+
/**
* Constructs a <code>SwapableMemoryDataSource</code> from inputStream,
and
* contentType. The instance then reads from the input stream, and stores it
* in memory unless the size of the content is larger than maxMemorySize, at
* whichpoint the stream is stored in a temporary file on disk.
- *
+ *
* @param inputStream the stream to read from
* @param contentType the content type of this stream
- * @param maxMemorySize the maximum size in bytes that this data source is
+ * @param maxMemorySize the maximum size in bytes that this data source is
* allowed to allocate for stream storage
*/
public SwapableMemoryDataSource(InputStream inputStream, String contentType, int
maxMemorySize) throws IOException
{
if (contentType != null)
this.contentType = contentType;
-
- this.maxMemorySize = maxMemorySize;
-
+
+ this.maxMemorySize = maxMemorySize;
+
load(inputStream);
}
-
+
private void load(InputStream inputStream) throws IOException
{
RawByteArrayOutputStream rbaos = new RawByteArrayOutputStream();
OutputStream os = rbaos;
-
+
byte[] buffer = new byte[BLOCK_SIZE];
int count = inputStream.read(buffer);
while (count > 0) {
os.write(buffer, 0, count);
-
+
if (rbaos != null && rbaos.size() > maxMemorySize)
{
File tmpdir = null;
try
{
- ServerConfigFactory factory = ServerConfigFactory.getInstance();
- ServerConfig config = factory.getServerConfig();
- tmpdir = new File(config.getServerTempDir().getCanonicalPath() +
"/jbossws");
- tmpdir.mkdirs();
+ tmpdir = IOUtils.createTempDirectory();
}
catch (Throwable e)
{
@@ -132,13 +128,13 @@
rbaos.writeTo(os);
rbaos = null;
}
-
+
count = inputStream.read(buffer);
}
-
+
os.flush();
os.close();
-
+
if (rbaos == null)
{
log.debug("Using swap file, location = " + swapFile.toURL() + "
size = " + swapFile.length());
@@ -150,18 +146,18 @@
content = rbaos.getBytes();
}
}
-
+
protected void finalize() throws Throwable
{
super.finalize();
-
+
if (swapFile != null)
swapFile.delete();
}
-
+
/**
* Returns the content type of this data source.
- *
+ *
* @return the content type
*/
public String getContentType()
@@ -172,33 +168,33 @@
/**
* Returns a new input stream on this data source. Multiple calls
* are allowed because the data is stored.
- *
+ *
* @return a new input stream at the start of the data
*/
public InputStream getInputStream() throws IOException
{
if (content != null)
return new ByteArrayInputStream(content, 0, contentLength);
-
+
if (swapFile != null)
return new FileInputStream(swapFile);
-
+
throw new WSException("No content available");
}
/**
* This method always returns null.
- *
+ *
* @return null
*/
public String getName()
{
return null;
}
-
+
/**
* This method always returns null.
- *
+ *
* @return null
*/
public OutputStream getOutputStream() throws IOException
Modified: trunk/src/main/java/org/jboss/ws/utils/IOUtils.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/utils/IOUtils.java 2006-11-16 00:37:11 UTC (rev
1442)
+++ trunk/src/main/java/org/jboss/ws/utils/IOUtils.java 2006-11-16 03:13:56 UTC (rev
1443)
@@ -21,12 +21,15 @@
*/
package org.jboss.ws.utils;
-// $Id: $
+// $Id$
import java.io.*;
import org.jboss.logging.Logger;
import org.jboss.ws.WSException;
+import org.jboss.ws.server.ServerConfig;
+import org.jboss.ws.server.ServerConfigFactory;
+
import javax.activation.DataHandler;
/**
@@ -93,4 +96,13 @@
}
return new ByteArrayInputStream(strBuffer.toString().getBytes());
}
+
+ public static File createTempDirectory() throws IOException
+ {
+ ServerConfigFactory factory = ServerConfigFactory.getInstance();
+ ServerConfig config = factory.getServerConfig();
+ File tmpdir = new File(config.getServerTempDir().getCanonicalPath() +
"/jbossws");
+ tmpdir.mkdirs();
+ return tmpdir;
+ }
}
Modified: trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java
===================================================================
--- trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java 2006-11-16 00:37:11 UTC (rev
1442)
+++ trunk/src/main/java/org/jboss/ws/utils/JavaUtils.java 2006-11-16 03:13:56 UTC (rev
1443)
@@ -29,6 +29,7 @@
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
+import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.HashSet;
@@ -475,7 +476,7 @@
{
if (val == null)
return "null";
-
+
StringBuilder out = new StringBuilder("[");
for (int i = 0; i < val.length; i++)
{
@@ -586,4 +587,52 @@
return ret;
}
+
+ /**
+ * Tests if this class loader is a JBoss RepositoryClassLoader
+ *
+ * @param loader
+ * @return
+ */
+ public static boolean isJBossRepositoryClassLoader(ClassLoader loader)
+ {
+ Class clazz = loader.getClass();
+ while (!clazz.getName().startsWith("java"))
+ {
+ if
("org.jboss.mx.loading.RepositoryClassLoader".equals(clazz.getName()))
+ return true;
+ clazz = clazz.getSuperclass();
+ }
+
+ return false;
+ }
+
+ /**
+ * Clears black lists on a JBoss RepositoryClassLoader. This is somewhat of a hack,
and
+ * could be replaced with an integration module. This is needed when the following
order of
+ * events occur.
+ *
+ * <ol>
+ * <li>loadClass() returns not found</li>
+ * <li>Some call to defineClass()</li>
+ * <ol>
+ *
+ * The CNFE triggers a black list addition, which cause the class never again to be
found.
+ *
+ * @param loader the loader to clear black lists for
+ */
+ public static void clearBlacklists(ClassLoader loader)
+ {
+ if (isJBossRepositoryClassLoader(loader))
+ {
+ try
+ {
+ loader.getClass().getMethod("clearBlacklists").invoke(loader);
+ }
+ catch (Exception e)
+ {
+ log.debug("Could not clear blacklists on " + loader);
+ }
+ }
+ }
}
\ No newline at end of file