You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "Martin Gainty (JIRA)" <ji...@apache.org> on 2009/06/07 20:44:42 UTC
[jira] Created: (WW-3153) xwork
com.opensymphony.xwork2.config.ConfigurationManager needs better error
handling for missing plugin config,class
xwork com.opensymphony.xwork2.config.ConfigurationManager needs better error handling for missing plugin config,class
---------------------------------------------------------------------------------------------------------------------
Key: WW-3153
URL: https://issues.apache.org/struts/browse/WW-3153
Project: Struts 2
Issue Type: Bug
Environment: Struts 2.1.6
xwork 2.0-SNAPSHOT
J2SE 1.6.0.10
TC 1.6
Reporter: Martin Gainty
xwork com.opensymphony.xwork2.config.ConfigurationManager code
/*** Get the current XWork configuration object. By default an instance of
DefaultConfiguration will be returned
* @see com.opensymphony.xwork2.config.impl.DefaultConfiguration
*/
public synchronized Configuration getConfiguration() {
if (configuration == null) {
setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
try {
configuration.reload(getConfigurationProviders());
} catch (ConfigurationException e) {
setConfiguration(null);
/****** xwork getConfigurationProviders code inlined so we can see whats going on ***
* Get the current list of ConfigurationProviders. If no custom ConfigurationProviders have been added, this method
* will return a list containing only the default ConfigurationProvider, XMLConfigurationProvider. if a custom
* ConfigurationProvider has been added, then the XmlConfigurationProvider must be added by hand.
* </p>
* <p/>
* TODO: the lazy instantiation of XmlConfigurationProvider should be refactored to be elsewhere. the behavior described above seems unintuitive.
*
* @return the list of registered ConfigurationProvider objects
* @see ConfigurationProvider
*/
public List<ConfigurationProvider> getConfigurationProviders() {
providerLock.lock();
try {
if (configurationProviders.size() == 0) {
configurationProviders.add(new XmlConfigurationProvider("xwork.xml", true));
}
return configurationProviders;
} finally {
providerLock.unlock();
}
}
***********/
throw e;
}
} else {
conditionalReload();
}
return configuration;
}
//end configurationManager
//Here is com.opensymphony.xwork2.config.impl.DefaultConfigurationProvider
public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {
ContainerProperties props = new ContainerProperties();
ContainerBuilder builder = new ContainerBuilder();
for (final ContainerProvider containerProvider : providers)
{
containerProvider.init(this);
containerProvider.register(builder, props);
}
props.setConstants(builder);
//a quick recap of setConstants
/*public void setConstants(ContainerBuilder builder) {
//keySet appears to be empty so the iterator to key wont work here
for (Object keyobj : keySet()) {
String key = (String)keyobj;
builder.factory(String.class, key,
new LocatableConstantFactory<String>(getProperty(key), getPropertyLocation(key)));
}
}
*/
container = builder.create(false);
/*start code com.opensymphony.xwork2.inject.ConfigurationBuilder.create()
public Container create(boolean loadSingletons) {
ensureNotCreated();
created = true;
final ContainerImpl container = new ContainerImpl(
new HashMap<Key<?>, InternalFactory<?>>(factories));
if (loadSingletons) { //wont happen as this is always false
container.callInContext(new ContainerImpl.ContextualCallable<Void>() {
public Void call(InternalContext context) {
for (InternalFactory<?> factory : singletonFactories) {
factory.create(context);
}
return null;
}
});
}
//final List<Class<?>> staticInjections = new ArrayList<Class<?>>();
//no effect as staticInjections are null at this point
container.injectStatics(staticInjections);
return container;
}
//end com.opensymphony.xwork2.inject.ConfigurationBuilder.create()
*/
setContext(container);
/******* setContext code inlined so we can see whats going on
protected ActionContext setContext(Container cont) {
ValueStack vs = cont.getInstance(ValueStackFactory.class).createValueStack();
ActionContext context = new ActionContext(vs.getContext());
ActionContext.setContext(context);
return context; //returns the context of the VS from the supplied container
}
********/
// Set<String> getInstanceNames(Class<?> type);
objectFactory = container.getInstance(ObjectFactory.class);
//a not null objectFactory with no contained objects
// Process the configuration providers first (WARNING providers could be null!)
for (final ContainerProvider containerProvider : providers)
{
if (containerProvider instanceof PackageProvider) {
container.inject(containerProvider);
((PackageProvider)containerProvider).loadPackages();
packageProviders.add((PackageProvider)containerProvider);
}
}
// Then process any package providers from the plugins
//Container.getInstanceNames Set<String> getInstanceNames(Class<?> type);
/*com.opensymphony.xwork2.inject.ContainerImpl has getInstanceNames we can use
public Set<String> getInstanceNames(final Class<?> type) {
return factoryNamesByType.get(type);
//FYI this.factoryNamesByType = Collections.unmodifiableMap(map);
//now a simple get on the key should return the Factory for PackageProvider
}
*/
Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);
if (packageProviderNames != null) {
for (String name : packageProviderNames) {
PackageProvider provider = container.getInstance(PackageProvider.class, name);
provider.init(this);
provider.loadPackages();
packageProviders.add(provider);
}
}
rebuildRuntimeConfiguration();
} finally {
ActionContext.setContext(null);
}
return packageProviders;
//how does a factory for PackageProvider get created?
/* CAUTION members needs to contain the classnames for factory to create
<M extends Member & AnnotatedElement> void addInjectorsForMembers(
List<M> members, boolean statics, List<Injector> injectors,
InjectorFactory<M> injectorFactory) {
for (M member : members) {
if (isStatic(member) == statics) {
Inject inject = member.getAnnotation(Inject.class);
if (inject != null) {
try {
injectors.add(injectorFactory.create(this, member, inject.value()));
} catch (MissingDependencyException e) {
if (inject.required()) {
throw new DependencyException(e);
}
}
}
}
}
}
*/
//where is addInjectorsForMembers called?
/*addInjectorsForMembers is called as Injector parameter to method
void addInjectorsForMethods(Method[] methods, boolean statics,
List<Injector> injectors) {
addInjectorsForMembers(Arrays.asList(methods), statics, injectors,
new InjectorFactory<Method>() {
public Injector create(ContainerImpl container, Method method,
String name) throws MissingDependencyException {
return new MethodInjector(container, method, name);
}
});
}
*/
OR addInjectorsForMember is called as parameter to Field
void addInjectorsForFields(Field[] fields, boolean statics,
List<Injector> injectors) {
addInjectorsForMembers(Arrays.asList(fields), statics, injectors,
new InjectorFactory<Field>() {
public Injector create(ContainerImpl container, Field field,
String name) throws MissingDependencyException {
return new FieldInjector(container, field, name);
}
});
}
//where do the injectors come from
//they are called as a parameter to injectStatics here is the code:
void injectStatics(List<Class<?>> staticInjections) {
final List<Injector> injectors = new ArrayList<Injector>();
for (Class<?> clazz : staticInjections) {
addInjectorsForFields(clazz.getDeclaredFields(), true, injectors);
addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors);
}
callInContext(new ContextualCallable<Void>() {
public Void call(InternalContext context) {
for (Injector injector : injectors) {
injector.inject(context, null);
}
return null;
}
});
}
//the solution comes provided with test samples for xwork2
//com.opensymphony.xwork2.conf.XmlConfigurationProvider.java
String impl=java.util.Properties.getProperty("struts.convention.actionConfigBuilder");
Class clazz = new Class(impl);
//quick sanity check
if (clazz==null)
{ log.debug(impl+"class is not on classpath please put actionConfigBuilder class on classpath"); }
//if the instantiated class is null because of wrong name or not on classpath we should log the error!
Class cimpl = ClassLoaderUtil.loadClass(impl, clazz);
if (cimpl==null)
{ log.debug(impl+"class is not on classpath please put actionConfigBuilder class on classpath"); }
//if the instantiated class is null because of wrong name or not on classpath or CL couldnt find we should log the error!
/*the resourceName HAS TO BE PRECONFIGURED in context otherwise call to getResource on impl will fail
public static URL getResource(String resourceName, Class callingClass) {
URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
if (url == null) {
url = ClassLoaderUtil.class.getClassLoader().getResource(resourceName);
}
if (url == null) {
ClassLoader cl = callingClass.getClassLoader();
if (cl != null) {
url = cl.getResource(resourceName);
}
}
*/
// Force loading of class to detect no class def found exceptions
try
{
cimpl.getDeclaredClasses();
}
catch(ClassNotFoundException cnfe)
{
log.debug("current CL cant locate class "+cimpl+"place class on CLASSPATH or configuration for plugin class is missing please try again");
}
//now that you have the actionConfigBuilder Class built and the configuration is verified go ahead and inject
containerBuilder.injectStatics(cimpl);
HTH
Martin Gainty
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
[jira] Issue Comment Edited: (WW-3153) xwork
com.opensymphony.xwork2.config.ConfigurationManager needs better error
handling for missing plugin config,class
Posted by "Dave Newton (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/struts/browse/WW-3153?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46350#action_46350 ]
Dave Newton edited comment on WW-3153 at 6/7/09 12:42 PM:
----------------------------------------------------------
Please devise a more legible means to communicate your concerns. Perhaps simply providing pointers to source code rather than embedding Java comments in a swatch of extracted code.
Also note that S2.1.6 has a dependency on XW2.1.2, so reporting an XW2.0-SNAPSHOT environment is misleading.
was (Author: newton_dave):
Please devise a more legible means with which to communicate your concerns.
> xwork com.opensymphony.xwork2.config.ConfigurationManager needs better error handling for missing plugin config,class
> ---------------------------------------------------------------------------------------------------------------------
>
> Key: WW-3153
> URL: https://issues.apache.org/struts/browse/WW-3153
> Project: Struts 2
> Issue Type: Bug
> Environment: Struts 2.1.6
> xwork 2.0-SNAPSHOT
> J2SE 1.6.0.10
> TC 1.6
> Reporter: Martin Gainty
>
> xwork com.opensymphony.xwork2.config.ConfigurationManager code
> /*** Get the current XWork configuration object. By default an instance of
> DefaultConfiguration will be returned
> * @see com.opensymphony.xwork2.config.impl.DefaultConfiguration
> */
> public synchronized Configuration getConfiguration() {
> if (configuration == null) {
> setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
> try {
> configuration.reload(getConfigurationProviders());
> } catch (ConfigurationException e) {
> setConfiguration(null);
> /****** xwork getConfigurationProviders code inlined so we can see whats going on ***
> * Get the current list of ConfigurationProviders. If no custom ConfigurationProviders have been added, this method
> * will return a list containing only the default ConfigurationProvider, XMLConfigurationProvider. if a custom
> * ConfigurationProvider has been added, then the XmlConfigurationProvider must be added by hand.
> * </p>
> * <p/>
> * TODO: the lazy instantiation of XmlConfigurationProvider should be refactored to be elsewhere. the behavior described above seems unintuitive.
> *
> * @return the list of registered ConfigurationProvider objects
> * @see ConfigurationProvider
> */
> public List<ConfigurationProvider> getConfigurationProviders() {
> providerLock.lock();
> try {
> if (configurationProviders.size() == 0) {
> configurationProviders.add(new XmlConfigurationProvider("xwork.xml", true));
> }
> return configurationProviders;
> } finally {
> providerLock.unlock();
> }
> }
> ***********/
> throw e;
> }
> } else {
> conditionalReload();
> }
> return configuration;
> }
> //end configurationManager
> //Here is com.opensymphony.xwork2.config.impl.DefaultConfigurationProvider
> public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {
> ContainerProperties props = new ContainerProperties();
> ContainerBuilder builder = new ContainerBuilder();
> for (final ContainerProvider containerProvider : providers)
> {
> containerProvider.init(this);
> containerProvider.register(builder, props);
> }
> props.setConstants(builder);
> //a quick recap of setConstants
> /*public void setConstants(ContainerBuilder builder) {
> //keySet appears to be empty so the iterator to key wont work here
> for (Object keyobj : keySet()) {
> String key = (String)keyobj;
> builder.factory(String.class, key,
> new LocatableConstantFactory<String>(getProperty(key), getPropertyLocation(key)));
> }
> }
> */
> container = builder.create(false);
> /*start code com.opensymphony.xwork2.inject.ConfigurationBuilder.create()
> public Container create(boolean loadSingletons) {
> ensureNotCreated();
> created = true;
> final ContainerImpl container = new ContainerImpl(
> new HashMap<Key<?>, InternalFactory<?>>(factories));
> if (loadSingletons) { //wont happen as this is always false
> container.callInContext(new ContainerImpl.ContextualCallable<Void>() {
> public Void call(InternalContext context) {
> for (InternalFactory<?> factory : singletonFactories) {
> factory.create(context);
> }
> return null;
> }
> });
> }
> //final List<Class<?>> staticInjections = new ArrayList<Class<?>>();
> //no effect as staticInjections are null at this point
> container.injectStatics(staticInjections);
> return container;
> }
> //end com.opensymphony.xwork2.inject.ConfigurationBuilder.create()
> */
> setContext(container);
> /******* setContext code inlined so we can see whats going on
> protected ActionContext setContext(Container cont) {
> ValueStack vs = cont.getInstance(ValueStackFactory.class).createValueStack();
> ActionContext context = new ActionContext(vs.getContext());
> ActionContext.setContext(context);
> return context; //returns the context of the VS from the supplied container
> }
> ********/
> // Set<String> getInstanceNames(Class<?> type);
> objectFactory = container.getInstance(ObjectFactory.class);
> //a not null objectFactory with no contained objects
> // Process the configuration providers first (WARNING providers could be null!)
> for (final ContainerProvider containerProvider : providers)
> {
> if (containerProvider instanceof PackageProvider) {
> container.inject(containerProvider);
> ((PackageProvider)containerProvider).loadPackages();
> packageProviders.add((PackageProvider)containerProvider);
> }
> }
>
> // Then process any package providers from the plugins
> //Container.getInstanceNames Set<String> getInstanceNames(Class<?> type);
> /*com.opensymphony.xwork2.inject.ContainerImpl has getInstanceNames we can use
> public Set<String> getInstanceNames(final Class<?> type) {
> return factoryNamesByType.get(type);
> //FYI this.factoryNamesByType = Collections.unmodifiableMap(map);
> //now a simple get on the key should return the Factory for PackageProvider
> }
> */
> Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);
> if (packageProviderNames != null) {
> for (String name : packageProviderNames) {
> PackageProvider provider = container.getInstance(PackageProvider.class, name);
> provider.init(this);
> provider.loadPackages();
> packageProviders.add(provider);
> }
> }
>
> rebuildRuntimeConfiguration();
> } finally {
> ActionContext.setContext(null);
> }
> return packageProviders;
> //how does a factory for PackageProvider get created?
> /* CAUTION members needs to contain the classnames for factory to create
> <M extends Member & AnnotatedElement> void addInjectorsForMembers(
> List<M> members, boolean statics, List<Injector> injectors,
> InjectorFactory<M> injectorFactory) {
> for (M member : members) {
> if (isStatic(member) == statics) {
> Inject inject = member.getAnnotation(Inject.class);
> if (inject != null) {
> try {
> injectors.add(injectorFactory.create(this, member, inject.value()));
> } catch (MissingDependencyException e) {
> if (inject.required()) {
> throw new DependencyException(e);
> }
> }
> }
> }
> }
> }
> */
> //where is addInjectorsForMembers called?
> /*addInjectorsForMembers is called as Injector parameter to method
> void addInjectorsForMethods(Method[] methods, boolean statics,
> List<Injector> injectors) {
> addInjectorsForMembers(Arrays.asList(methods), statics, injectors,
> new InjectorFactory<Method>() {
> public Injector create(ContainerImpl container, Method method,
> String name) throws MissingDependencyException {
> return new MethodInjector(container, method, name);
> }
> });
> }
> */
> OR addInjectorsForMember is called as parameter to Field
> void addInjectorsForFields(Field[] fields, boolean statics,
> List<Injector> injectors) {
> addInjectorsForMembers(Arrays.asList(fields), statics, injectors,
> new InjectorFactory<Field>() {
> public Injector create(ContainerImpl container, Field field,
> String name) throws MissingDependencyException {
> return new FieldInjector(container, field, name);
> }
> });
> }
> //where do the injectors come from
> //they are called as a parameter to injectStatics here is the code:
> void injectStatics(List<Class<?>> staticInjections) {
> final List<Injector> injectors = new ArrayList<Injector>();
> for (Class<?> clazz : staticInjections) {
> addInjectorsForFields(clazz.getDeclaredFields(), true, injectors);
> addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors);
> }
> callInContext(new ContextualCallable<Void>() {
> public Void call(InternalContext context) {
> for (Injector injector : injectors) {
> injector.inject(context, null);
> }
> return null;
> }
> });
> }
> //the solution comes provided with test samples for xwork2
> //com.opensymphony.xwork2.conf.XmlConfigurationProvider.java
> String impl=java.util.Properties.getProperty("struts.convention.actionConfigBuilder");
> Class clazz = new Class(impl);
> //quick sanity check
> if (clazz==null)
> { log.debug(impl+"class is not on classpath please put actionConfigBuilder class on classpath"); }
> //if the instantiated class is null because of wrong name or not on classpath we should log the error!
> Class cimpl = ClassLoaderUtil.loadClass(impl, clazz);
> if (cimpl==null)
> { log.debug(impl+"class is not on classpath please put actionConfigBuilder class on classpath"); }
> //if the instantiated class is null because of wrong name or not on classpath or CL couldnt find we should log the error!
> /*the resourceName HAS TO BE PRECONFIGURED in context otherwise call to getResource on impl will fail
> public static URL getResource(String resourceName, Class callingClass) {
> URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
> if (url == null) {
> url = ClassLoaderUtil.class.getClassLoader().getResource(resourceName);
> }
> if (url == null) {
> ClassLoader cl = callingClass.getClassLoader();
> if (cl != null) {
> url = cl.getResource(resourceName);
> }
> }
> */
> // Force loading of class to detect no class def found exceptions
> try
> {
> cimpl.getDeclaredClasses();
> }
> catch(ClassNotFoundException cnfe)
> {
> log.debug("current CL cant locate class "+cimpl+"place class on CLASSPATH or configuration for plugin class is missing please try again");
> }
> //now that you have the actionConfigBuilder Class built and the configuration is verified go ahead and inject
> containerBuilder.injectStatics(cimpl);
> HTH
> Martin Gainty
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
[jira] Commented: (WW-3153) xwork
com.opensymphony.xwork2.config.ConfigurationManager needs better error
handling for missing plugin config,class
Posted by "Dave Newton (JIRA)" <ji...@apache.org>.
[ https://issues.apache.org/struts/browse/WW-3153?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46350#action_46350 ]
Dave Newton commented on WW-3153:
---------------------------------
Please devise a more legible means with which to communicate your concerns.
> xwork com.opensymphony.xwork2.config.ConfigurationManager needs better error handling for missing plugin config,class
> ---------------------------------------------------------------------------------------------------------------------
>
> Key: WW-3153
> URL: https://issues.apache.org/struts/browse/WW-3153
> Project: Struts 2
> Issue Type: Bug
> Environment: Struts 2.1.6
> xwork 2.0-SNAPSHOT
> J2SE 1.6.0.10
> TC 1.6
> Reporter: Martin Gainty
>
> xwork com.opensymphony.xwork2.config.ConfigurationManager code
> /*** Get the current XWork configuration object. By default an instance of
> DefaultConfiguration will be returned
> * @see com.opensymphony.xwork2.config.impl.DefaultConfiguration
> */
> public synchronized Configuration getConfiguration() {
> if (configuration == null) {
> setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
> try {
> configuration.reload(getConfigurationProviders());
> } catch (ConfigurationException e) {
> setConfiguration(null);
> /****** xwork getConfigurationProviders code inlined so we can see whats going on ***
> * Get the current list of ConfigurationProviders. If no custom ConfigurationProviders have been added, this method
> * will return a list containing only the default ConfigurationProvider, XMLConfigurationProvider. if a custom
> * ConfigurationProvider has been added, then the XmlConfigurationProvider must be added by hand.
> * </p>
> * <p/>
> * TODO: the lazy instantiation of XmlConfigurationProvider should be refactored to be elsewhere. the behavior described above seems unintuitive.
> *
> * @return the list of registered ConfigurationProvider objects
> * @see ConfigurationProvider
> */
> public List<ConfigurationProvider> getConfigurationProviders() {
> providerLock.lock();
> try {
> if (configurationProviders.size() == 0) {
> configurationProviders.add(new XmlConfigurationProvider("xwork.xml", true));
> }
> return configurationProviders;
> } finally {
> providerLock.unlock();
> }
> }
> ***********/
> throw e;
> }
> } else {
> conditionalReload();
> }
> return configuration;
> }
> //end configurationManager
> //Here is com.opensymphony.xwork2.config.impl.DefaultConfigurationProvider
> public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {
> ContainerProperties props = new ContainerProperties();
> ContainerBuilder builder = new ContainerBuilder();
> for (final ContainerProvider containerProvider : providers)
> {
> containerProvider.init(this);
> containerProvider.register(builder, props);
> }
> props.setConstants(builder);
> //a quick recap of setConstants
> /*public void setConstants(ContainerBuilder builder) {
> //keySet appears to be empty so the iterator to key wont work here
> for (Object keyobj : keySet()) {
> String key = (String)keyobj;
> builder.factory(String.class, key,
> new LocatableConstantFactory<String>(getProperty(key), getPropertyLocation(key)));
> }
> }
> */
> container = builder.create(false);
> /*start code com.opensymphony.xwork2.inject.ConfigurationBuilder.create()
> public Container create(boolean loadSingletons) {
> ensureNotCreated();
> created = true;
> final ContainerImpl container = new ContainerImpl(
> new HashMap<Key<?>, InternalFactory<?>>(factories));
> if (loadSingletons) { //wont happen as this is always false
> container.callInContext(new ContainerImpl.ContextualCallable<Void>() {
> public Void call(InternalContext context) {
> for (InternalFactory<?> factory : singletonFactories) {
> factory.create(context);
> }
> return null;
> }
> });
> }
> //final List<Class<?>> staticInjections = new ArrayList<Class<?>>();
> //no effect as staticInjections are null at this point
> container.injectStatics(staticInjections);
> return container;
> }
> //end com.opensymphony.xwork2.inject.ConfigurationBuilder.create()
> */
> setContext(container);
> /******* setContext code inlined so we can see whats going on
> protected ActionContext setContext(Container cont) {
> ValueStack vs = cont.getInstance(ValueStackFactory.class).createValueStack();
> ActionContext context = new ActionContext(vs.getContext());
> ActionContext.setContext(context);
> return context; //returns the context of the VS from the supplied container
> }
> ********/
> // Set<String> getInstanceNames(Class<?> type);
> objectFactory = container.getInstance(ObjectFactory.class);
> //a not null objectFactory with no contained objects
> // Process the configuration providers first (WARNING providers could be null!)
> for (final ContainerProvider containerProvider : providers)
> {
> if (containerProvider instanceof PackageProvider) {
> container.inject(containerProvider);
> ((PackageProvider)containerProvider).loadPackages();
> packageProviders.add((PackageProvider)containerProvider);
> }
> }
>
> // Then process any package providers from the plugins
> //Container.getInstanceNames Set<String> getInstanceNames(Class<?> type);
> /*com.opensymphony.xwork2.inject.ContainerImpl has getInstanceNames we can use
> public Set<String> getInstanceNames(final Class<?> type) {
> return factoryNamesByType.get(type);
> //FYI this.factoryNamesByType = Collections.unmodifiableMap(map);
> //now a simple get on the key should return the Factory for PackageProvider
> }
> */
> Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);
> if (packageProviderNames != null) {
> for (String name : packageProviderNames) {
> PackageProvider provider = container.getInstance(PackageProvider.class, name);
> provider.init(this);
> provider.loadPackages();
> packageProviders.add(provider);
> }
> }
>
> rebuildRuntimeConfiguration();
> } finally {
> ActionContext.setContext(null);
> }
> return packageProviders;
> //how does a factory for PackageProvider get created?
> /* CAUTION members needs to contain the classnames for factory to create
> <M extends Member & AnnotatedElement> void addInjectorsForMembers(
> List<M> members, boolean statics, List<Injector> injectors,
> InjectorFactory<M> injectorFactory) {
> for (M member : members) {
> if (isStatic(member) == statics) {
> Inject inject = member.getAnnotation(Inject.class);
> if (inject != null) {
> try {
> injectors.add(injectorFactory.create(this, member, inject.value()));
> } catch (MissingDependencyException e) {
> if (inject.required()) {
> throw new DependencyException(e);
> }
> }
> }
> }
> }
> }
> */
> //where is addInjectorsForMembers called?
> /*addInjectorsForMembers is called as Injector parameter to method
> void addInjectorsForMethods(Method[] methods, boolean statics,
> List<Injector> injectors) {
> addInjectorsForMembers(Arrays.asList(methods), statics, injectors,
> new InjectorFactory<Method>() {
> public Injector create(ContainerImpl container, Method method,
> String name) throws MissingDependencyException {
> return new MethodInjector(container, method, name);
> }
> });
> }
> */
> OR addInjectorsForMember is called as parameter to Field
> void addInjectorsForFields(Field[] fields, boolean statics,
> List<Injector> injectors) {
> addInjectorsForMembers(Arrays.asList(fields), statics, injectors,
> new InjectorFactory<Field>() {
> public Injector create(ContainerImpl container, Field field,
> String name) throws MissingDependencyException {
> return new FieldInjector(container, field, name);
> }
> });
> }
> //where do the injectors come from
> //they are called as a parameter to injectStatics here is the code:
> void injectStatics(List<Class<?>> staticInjections) {
> final List<Injector> injectors = new ArrayList<Injector>();
> for (Class<?> clazz : staticInjections) {
> addInjectorsForFields(clazz.getDeclaredFields(), true, injectors);
> addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors);
> }
> callInContext(new ContextualCallable<Void>() {
> public Void call(InternalContext context) {
> for (Injector injector : injectors) {
> injector.inject(context, null);
> }
> return null;
> }
> });
> }
> //the solution comes provided with test samples for xwork2
> //com.opensymphony.xwork2.conf.XmlConfigurationProvider.java
> String impl=java.util.Properties.getProperty("struts.convention.actionConfigBuilder");
> Class clazz = new Class(impl);
> //quick sanity check
> if (clazz==null)
> { log.debug(impl+"class is not on classpath please put actionConfigBuilder class on classpath"); }
> //if the instantiated class is null because of wrong name or not on classpath we should log the error!
> Class cimpl = ClassLoaderUtil.loadClass(impl, clazz);
> if (cimpl==null)
> { log.debug(impl+"class is not on classpath please put actionConfigBuilder class on classpath"); }
> //if the instantiated class is null because of wrong name or not on classpath or CL couldnt find we should log the error!
> /*the resourceName HAS TO BE PRECONFIGURED in context otherwise call to getResource on impl will fail
> public static URL getResource(String resourceName, Class callingClass) {
> URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
> if (url == null) {
> url = ClassLoaderUtil.class.getClassLoader().getResource(resourceName);
> }
> if (url == null) {
> ClassLoader cl = callingClass.getClassLoader();
> if (cl != null) {
> url = cl.getResource(resourceName);
> }
> }
> */
> // Force loading of class to detect no class def found exceptions
> try
> {
> cimpl.getDeclaredClasses();
> }
> catch(ClassNotFoundException cnfe)
> {
> log.debug("current CL cant locate class "+cimpl+"place class on CLASSPATH or configuration for plugin class is missing please try again");
> }
> //now that you have the actionConfigBuilder Class built and the configuration is verified go ahead and inject
> containerBuilder.injectStatics(cimpl);
> HTH
> Martin Gainty
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.