You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hivemind.apache.org by ah...@apache.org on 2007/03/05 23:09:47 UTC
svn commit: r514886 - in /hivemind/hivemind2/trunk:
annotations/src/java/org/apache/hivemind/annotations/
annotations/src/java/org/apache/hivemind/annotations/internal/
annotations/src/test/org/apache/hivemind/annotations/
framework/src/java/org/apache...
Author: ahuegen
Date: Mon Mar 5 14:09:46 2007
New Revision: 514886
URL: http://svn.apache.org/viewvc?view=rev&rev=514886
Log:
Load annotation processors extensions defined in manifest
Added:
hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ManifestReader.java
Modified:
hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java
hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties
hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java
hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java
hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplMessages.java
hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplStrings.properties
hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java
Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java?view=diff&rev=514886&r1=514885&r2=514886
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java Mon Mar 5 14:09:46 2007
@@ -60,5 +60,15 @@
MethodSignature methodSig = new MethodSignature(method);
return _formatter.format("annotated-method-protected-not-accessible", methodSig.toString());
}
+
+ public static String unableToCreateAnnotationProcessor(String processorClassName, Exception cause)
+ {
+ return _formatter.format("unable-to-create-annotation-processor", processorClassName, cause);
+ }
+
+ public static String annotationProcessorWrongType(String processorClassName, Class requiredInterface)
+ {
+ return _formatter.format("annotation-processor-wrong-type", processorClassName, requiredInterface.getName());
+ }
}
Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties?view=diff&rev=514886&r1=514885&r2=514886
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties Mon Mar 5 14:09:46 2007
@@ -18,3 +18,5 @@
annotated-method-has-invalid-modifiers=Method ''{0}'' used as {1} has invalid modifiers: {2}
annotated-method-protected-not-accessible=Method ''{0}'' is protected but not accessible by HiveMind. If a SecurityManager is used then HiveMind must be allowed to call Method#setAccessible.
+unable-to-create-annotation-processor=Unable to create AnnotationProcessor of type {0}: {1}
+annotation-processor-wrong-type=AnnotationProcessor class {0} must implement interface {1}
Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java?view=diff&rev=514886&r1=514885&r2=514886
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java Mon Mar 5 14:09:46 2007
@@ -14,24 +14,18 @@
package org.apache.hivemind.annotations.internal;
-import java.io.IOException;
-import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.annotations.AnnotationsMessages;
import org.apache.hivemind.annotations.definition.processors.AnnotationProcessor;
-import org.apache.hivemind.util.IOUtils;
-import org.apache.hivemind.util.URLResource;
+import org.apache.hivemind.impl.ManifestReader;
/**
* @author Achim Huegen
@@ -40,119 +34,56 @@
{
private static final Log LOG = LogFactory.getLog(AnnotationExtensionLoader.class);
public static final String MANIFEST = "META-INF/MANIFEST.MF";
- public static final String HIVEMIND_SECTION_NAME = "hivemind";
public static final String PROCESSOR_ATTRIBUTE_NAME = "annotation-definition-processors";
-
- private List _providers = new ArrayList();
+
+ private List _processors = new ArrayList();
public AnnotationExtensionLoader(ClassResolver resolver)
{
- processManifestFiles(resolver);
- }
-
- public List getProviders()
- {
- return _providers;
- }
-
- /**
- * Process all manifest files found in the classpath
- * @param resolver the ClassResolver to use for the search
- */
- private void processManifestFiles(ClassResolver resolver)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Processing manifest files visible to " + resolver);
-
- ClassLoader loader = resolver.getClassLoader();
- Enumeration e = null;
-
- try
+ String[] processorValues = ManifestReader.getAttributeValues(resolver, PROCESSOR_ATTRIBUTE_NAME);
+ for (int i = 0; i < processorValues.length; i++)
{
- e = loader.getResources(MANIFEST);
+ String processorValue = processorValues[i];
+ handleProcessorValue(resolver, processorValue);
}
- catch (IOException ex)
- {
- throw new ApplicationRuntimeException(ImplMessages.unableToFindProviders(resolver, ex),
- ex);
- }
-
- while (e.hasMoreElements())
- {
- URL descriptorURL = (URL) e.nextElement();
-
- processManifestFile(resolver, new URLResource(descriptorURL));
- }
-
}
-
-
+
/**
- * Process a single manifest file.
- *
- * @param resolver
- * @param resource pointer to the manifest file
+ * @return List with instances of {@link AnnotationProcessor}
*/
- private void processManifestFile(ClassResolver resolver, URLResource resource)
+ public List getProcessors()
{
- URL url = resource.getResourceURL();
- InputStream manifestStream = null;
- Manifest manifest;
- try
- {
- manifestStream = IOUtils.openStreamWithoutCaching(url);
- manifest = new Manifest(manifestStream);
- }
- catch (IOException e)
- {
- throw new ApplicationRuntimeException(ImplMessages.unableToReadManifest(url, e),
- e);
- }
- finally
- {
- IOUtils.close(manifestStream);
- }
- // Search for an entry that defines a provider class
- Attributes attributes = manifest.getMainAttributes();
- if (attributes != null) {
- String providers = attributes.getValue(PROCESSOR_ATTRIBUTE_NAME);
- if (providers != null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Found providers '" + providers + "' defined in manifest file '" + url.toString() + "'");
- }
- handleProviderAttribute(resolver, providers);
- }
- }
+ return _processors;
}
/**
- * Parse the provider list in an attribute and load all classes.
+ * Parse the processor list in an attribute and load all classes.
*/
- private void handleProviderAttribute(ClassResolver resolver, String providers)
+ private void handleProcessorValue(ClassResolver resolver, String processors)
{
- StringTokenizer tokenizer = new StringTokenizer(providers, ",");
+ StringTokenizer tokenizer = new StringTokenizer(processors, ",");
while (tokenizer.hasMoreTokens())
{
- String providerClassName = tokenizer.nextToken();
- loadProvider(resolver, providerClassName);
+ String processorClassName = tokenizer.nextToken();
+ loadProcessor(resolver, processorClassName);
}
}
/**
- * Load a provider class and create an instance.
+ * Load a processor class and create an instance.
*
* @param resolver
- * @param providerClassName
+ * @param processorClassName
*/
- private void loadProvider(ClassResolver resolver, String providerClassName)
+ private void loadProcessor(ClassResolver resolver, String processorClassName)
{
if (LOG.isDebugEnabled())
- LOG.debug("Loading provider " + providerClassName);
- Object provider = null;
+ LOG.debug("Loading processor " + processorClassName);
+ Object processor = null;
try
{
- Class providerClass = resolver.findClass(providerClassName);
- provider = providerClass.newInstance();
+ Class processorClass = resolver.findClass(processorClassName);
+ processor = processorClass.newInstance();
}
catch (Exception e)
{
@@ -161,15 +92,15 @@
{
cause = (InvocationTargetException) e;
}
- throw new ApplicationRuntimeException(ImplMessages.unableToCreateProvider(providerClassName, e),
+ throw new ApplicationRuntimeException(AnnotationsMessages.unableToCreateAnnotationProcessor(processorClassName, e),
cause);
}
- // Check type of provider
- if (!(provider instanceof AnnotationProcessor)) {
- throw new ApplicationRuntimeException(ImplMessages.providerWrongType(providerClassName, RegistryProvider.class));
+ // Check type of processor
+ if (!(processor instanceof AnnotationProcessor)) {
+ throw new ApplicationRuntimeException(AnnotationsMessages.annotationProcessorWrongType(processorClassName, AnnotationProcessor.class));
}
- _providers.add(provider);
+ _processors.add(processor);
}
-}
+}
\ No newline at end of file
Modified: hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java?view=diff&rev=514886&r1=514885&r2=514886
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java Mon Mar 5 14:09:46 2007
@@ -16,6 +16,7 @@
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.annotations.internal.AnnotatedModuleProcessor;
+import org.apache.hivemind.annotations.internal.AnnotationProcessorRegistryFactory;
import org.apache.hivemind.definition.ModuleDefinition;
import org.apache.hivemind.definition.RegistryDefinition;
import org.apache.hivemind.definition.ServicePointDefinition;
@@ -56,7 +57,7 @@
public void testModuleClassNotFinal()
{
AnnotatedModuleProcessor processor = new AnnotatedModuleProcessor(new RegistryDefinitionImpl(),
- new DefaultClassResolver());
+ new DefaultClassResolver(), AnnotationProcessorRegistryFactory.createDefaultRegistry());
try
{
processor.processModule(FinalModule.class);
@@ -70,7 +71,7 @@
public void testModuleClassNotAbstract()
{
AnnotatedModuleProcessor processor = new AnnotatedModuleProcessor(new RegistryDefinitionImpl(),
- new DefaultClassResolver());
+ new DefaultClassResolver(), AnnotationProcessorRegistryFactory.createDefaultRegistry());
try
{
processor.processModule(AbstractModule.class);
@@ -84,7 +85,7 @@
public void testModuleClassPublic()
{
AnnotatedModuleProcessor processor = new AnnotatedModuleProcessor(new RegistryDefinitionImpl(),
- new DefaultClassResolver());
+ new DefaultClassResolver(), AnnotationProcessorRegistryFactory.createDefaultRegistry());
try
{
processor.processModule(NotPublicModule.class);
Modified: hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplMessages.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplMessages.java?view=diff&rev=514886&r1=514885&r2=514886
==============================================================================
--- hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplMessages.java (original)
+++ hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplMessages.java Mon Mar 5 14:09:46 2007
@@ -100,6 +100,11 @@
return _formatter.format("unable-to-parse", resource, cause);
}
+ static String unableToFindManifests(ClassResolver resolver, Throwable cause)
+ {
+ return _formatter.format("unable-to-find-manifests", resolver, cause);
+ }
+
static String unableToFindProviders(ClassResolver resolver, Throwable cause)
{
return _formatter.format("unable-to-find-providers", resolver, cause);
Modified: hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplStrings.properties
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplStrings.properties?view=diff&rev=514886&r1=514885&r2=514886
==============================================================================
--- hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplStrings.properties (original)
+++ hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ImplStrings.properties Mon Mar 5 14:09:46 2007
@@ -52,6 +52,7 @@
unable-to-map-configuration=Unable to map the contributions to configuration point {0}. All top-level schema elements must define a key attribute.
unable-to-convert-type=Unable to convert type ''{0}'' to a Java class, either as is, or in package {1}.
+unable-to-find-manifests=Unable to locate manifest files in {0}: {1}
unable-to-find-providers=Unable to locate manifest files in {0}: {1}
unable-to-read-manifest=Unable to read manifest file {0}: {1}
unable-to-create-provider=Unable to create provider of type {0}: {1}
Added: hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ManifestReader.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ManifestReader.java?view=auto&rev=514886
==============================================================================
--- hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ManifestReader.java (added)
+++ hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/ManifestReader.java Mon Mar 5 14:09:46 2007
@@ -0,0 +1,152 @@
+package org.apache.hivemind.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.util.IOUtils;
+import org.apache.hivemind.util.URLResource;
+
+/**
+ * Reads Manifest-Files (META-INF/MANIFEST.MF) and searches them for certain attributes.
+ * The {@link Manifest} instances are cached between two calls for better performance.
+ *
+ * @author Achim Huegen
+ */
+public class ManifestReader
+{
+ private static final Log LOG = LogFactory.getLog(ManifestReader.class);
+ private static final String MANIFEST = "META-INF/MANIFEST.MF";
+ public static final String HIVEMIND_SECTION_NAME = "hivemind";
+
+ /**
+ * Caches loaded manifests keyed by the ClassLoader
+ */
+ private static Map MANIFEST_CACHE = new HashMap();
+
+ /**
+ * Searches all manifest files found in the classpath by a ClassResolver
+ * for a attribute whose name is specified by <code>attributeName</code>.
+ * @param resolver
+ * @param attributeName
+ * @return all found attribute values
+ */
+ public static String[] getAttributeValues(ClassResolver resolver, String attributeName)
+ {
+ Manifest[] manifests = getManifests(resolver);
+ List results = new ArrayList();
+ for (int i = 0; i < manifests.length; i++)
+ {
+ Manifest manifest = manifests[i];
+ String value = getAttributeValue(manifest, attributeName);
+ results.add(value);
+ }
+ return (String[]) results.toArray(new String[results.size()]);
+ }
+
+ /**
+ * Searches a manifest for a attribute of the given name.
+ * @return the attribute value
+ */
+ private static String getAttributeValue(Manifest manifest, String attributeName)
+ {
+ String value = null;
+ // Search for an entry
+ Attributes attributes = manifest.getMainAttributes();
+ if (attributes != null) {
+ value = attributes.getValue(attributeName);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found attribute '" + attributeName + "' with value '" + value
+ + "' defined in manifest file'");
+ }
+ }
+ return value;
+ }
+
+ private static Manifest[] getManifests(ClassResolver resolver)
+ {
+ // Try to load manifests from static cache
+ Manifest[] manifests = (Manifest[]) MANIFEST_CACHE.get(resolver.getClassLoader());
+ if (manifests == null) {
+ manifests = loadManifestFiles(resolver);
+ MANIFEST_CACHE.put(resolver.getClassLoader(), manifests);
+ }
+ return manifests;
+ }
+
+
+ /**
+ * Loads all manifest files found in the classpath
+ * @param resolver the ClassResolver to use for the search
+ * @return an empty array if none have been found.
+ */
+ private static Manifest[] loadManifestFiles(ClassResolver resolver)
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Processing manifest files visible to " + resolver);
+
+ ClassLoader loader = resolver.getClassLoader();
+ Enumeration e = null;
+
+ try
+ {
+ e = loader.getResources(MANIFEST);
+ }
+ catch (IOException ex)
+ {
+ throw new ApplicationRuntimeException(ImplMessages.unableToFindManifests(resolver, ex),
+ ex);
+ }
+
+ List result = new ArrayList();
+ while (e.hasMoreElements())
+ {
+ URL descriptorURL = (URL) e.nextElement();
+
+ Manifest manifest = loadManifestFile(resolver, new URLResource(descriptorURL));
+ result.add(manifest);
+ }
+ return (Manifest[]) result.toArray(new Manifest[result.size()]);
+ }
+
+ /**
+ * Loads a single manifest file.
+ *
+ * @param resolver
+ * @param resource pointer to the manifest file
+ */
+ private static Manifest loadManifestFile(ClassResolver resolver, URLResource resource)
+ {
+ URL url = resource.getResourceURL();
+ InputStream manifestStream = null;
+ Manifest manifest;
+ try
+ {
+ manifestStream = IOUtils.openStreamWithoutCaching(url);
+ manifest = new Manifest(manifestStream);
+ }
+ catch (IOException e)
+ {
+ throw new ApplicationRuntimeException(ImplMessages.unableToReadManifest(url, e),
+ e);
+ }
+ finally
+ {
+ IOUtils.close(manifestStream);
+ }
+ return manifest;
+ }
+
+
+}
Modified: hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java?view=diff&rev=514886&r1=514885&r2=514886
==============================================================================
--- hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java (original)
+++ hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java Mon Mar 5 14:09:46 2007
@@ -14,23 +14,15 @@
package org.apache.hivemind.impl;
-import java.io.IOException;
-import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;
-import java.util.jar.Attributes;
-import java.util.jar.Manifest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.ClassResolver;
-import org.apache.hivemind.util.IOUtils;
-import org.apache.hivemind.util.URLResource;
/**
* Searches for {@link org.apache.hivemind.impl.RegistryProvider} implementations
@@ -45,96 +37,32 @@
public class RegistryProviderAutoDetector
{
private static final Log LOG = LogFactory.getLog(RegistryProviderAutoDetector.class);
- public static final String MANIFEST = "META-INF/MANIFEST.MF";
- public static final String HIVEMIND_SECTION_NAME = "hivemind";
public static final String PROVIDER_ATTRIBUTE_NAME = "hivemind-providers";
private List _providers = new ArrayList();
public RegistryProviderAutoDetector(ClassResolver resolver)
{
- processManifestFiles(resolver);
- }
-
- public List getProviders()
- {
- return _providers;
- }
-
- /**
- * Process all manifest files found in the classpath
- * @param resolver the ClassResolver to use for the search
- */
- private void processManifestFiles(ClassResolver resolver)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Processing manifest files visible to " + resolver);
-
- ClassLoader loader = resolver.getClassLoader();
- Enumeration e = null;
-
- try
+ String[] providerValues = ManifestReader.getAttributeValues(resolver, PROVIDER_ATTRIBUTE_NAME);
+ for (int i = 0; i < providerValues.length; i++)
{
- e = loader.getResources(MANIFEST);
+ String providerValue = providerValues[i];
+ handleProviderValue(resolver, providerValue);
}
- catch (IOException ex)
- {
- throw new ApplicationRuntimeException(ImplMessages.unableToFindProviders(resolver, ex),
- ex);
- }
-
- while (e.hasMoreElements())
- {
- URL descriptorURL = (URL) e.nextElement();
-
- processManifestFile(resolver, new URLResource(descriptorURL));
- }
-
}
-
-
+
/**
- * Process a single manifest file.
- *
- * @param resolver
- * @param resource pointer to the manifest file
+ * @return list with instances of {@link RegistryProvider}
*/
- private void processManifestFile(ClassResolver resolver, URLResource resource)
+ public List getProviders()
{
- URL url = resource.getResourceURL();
- InputStream manifestStream = null;
- Manifest manifest;
- try
- {
- manifestStream = IOUtils.openStreamWithoutCaching(url);
- manifest = new Manifest(manifestStream);
- }
- catch (IOException e)
- {
- throw new ApplicationRuntimeException(ImplMessages.unableToReadManifest(url, e),
- e);
- }
- finally
- {
- IOUtils.close(manifestStream);
- }
- // Search for an entry that defines a provider class
- Attributes attributes = manifest.getMainAttributes();
- if (attributes != null) {
- String providers = attributes.getValue(PROVIDER_ATTRIBUTE_NAME);
- if (providers != null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Found providers '" + providers + "' defined in manifest file '" + url.toString() + "'");
- }
- handleProviderAttribute(resolver, providers);
- }
- }
+ return _providers;
}
/**
* Parse the provider list in an attribute and load all classes.
*/
- private void handleProviderAttribute(ClassResolver resolver, String providers)
+ private void handleProviderValue(ClassResolver resolver, String providers)
{
StringTokenizer tokenizer = new StringTokenizer(providers, ",");
while (tokenizer.hasMoreTokens())