You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "Dave Newton (JIRA)" <ji...@apache.org> on 2009/06/07 21:43:43 UTC
[jira] Issue Comment Edited: (WW-3153) xwork
com.opensymphony.xwork2.config.ConfigurationManager needs better error
handling for missing plugin config,class
[ 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.