You are viewing a plain text version of this content. The canonical link for it is here.
Posted to graffito-dev@incubator.apache.org by Alexandru Popescu <th...@gmail.com> on 2006/05/19 19:59:28 UTC

Re: Classloader problem

This was exactly my initial attempt when externalizing all reflection
code to the ReflectionUtils class. Unfortunately, at that time I
couldn't make the change everywhere.

If you can submit the patch than me or Christophe will take a look at
it and commit it.

./alex
--
.w( the_mindstorm )p.

InfoQ.com Architect

On 4/19/06, Daniel Mora <mo...@gmail.com> wrote:
> I found a solution and maybe can be a contribution to Graffito mapper. I
> modified a little some graffito mapping files (ReflectionUtils,
> FieldDescriptor, ManegeableCollectionUtil, ObjectConverterImpl) that use
> Class.forName. Now only ReflectionUtils calls Class.forName, the others use
> ReflectionUtils.forName. I added to ReflectionUtils a private static
> attribute called classLoader and its setter and getter. I also modified the
> Mapper interface and added
> public abstract void setClassLoader(ClassLoader classLoader);
> public abstract ClassLoader getClassLoader();
>
> Now I can do things like:
> Mapper mapper = new DigesterMapperImpl(this.files);
> mapper.setClassLoader(myClassLoader);
> mapper.buildMapper();
>
> And this is the ReflectionUtils file:
>
> package org.apache.portals.graffito.jcr.reflection;
>
> import java.lang.reflect.InvocationTargetException;
> import net.sf.cglib.proxy.Enhancer;
> import org.apache.commons.beanutils.ConstructorUtils;
> import org.apache.commons.beanutils.PropertyUtils;
> import org.apache.portals.graffito.jcr.exception.JcrMappingException;
> import
> org.apache.portals.graffito.jcr.persistence.collectionconverter.CollectionConverter
> ;
>
>
> /**
>  * Utility class for handling reflection using BeanUtils.
>  *
>  * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru
> Popescu</a>
>  */
> abstract public class ReflectionUtils {
>
>     private static ClassLoader classLoader = null;
>
>     public static Object getNestedProperty(Object object, String fieldName)
> {
>         if (null == object) {
>             return null;
>         }
>
>         try {
>             return PropertyUtils.getNestedProperty(object, fieldName);
>         }
>         catch(IllegalAccessException e) {
>             throw new JcrMappingException("Cannot access property "
>                     + fieldName,
>                     e);
>         }
>         catch(InvocationTargetException e) {
>             throw new JcrMappingException("Cannot access property "
>                     + fieldName,
>                     e);
>         }
>         catch(NoSuchMethodException e) {
>             throw new JcrMappingException("Cannot access property "
>                     + fieldName,
>                     e);
>         }
>     }
>
>     public static Class getPropertyType(Object object, String fieldName) {
>         try {
>             return PropertyUtils.getPropertyType(object, fieldName);
>         }
>         catch(Exception ex) {
>             throw new JcrMappingException("Cannot access property "
>                     + fieldName,
>                     ex);
>         }
>     }
>
>     public static Object newInstance(Class clazz) {
>         try {
>             return clazz.newInstance();
>         }
>         catch(Exception ex) {
>             throw new JcrMappingException("Cannot create instance for class
> "
>                     + clazz,
>                     ex);
>         }
>     }
>
>     /**
>      * @param className
>      * @param objects
>      * @return
>      */
>     public static CollectionConverter invokeConstructor(String className,
>                                                         Object[] params) {
>         try {
>
>             Class converterClass = ReflectionUtils.forName(className);
>             return (CollectionConverter)
> ConstructorUtils.invokeConstructor(converterClass,
> params);
>         }
>         catch(Exception ex) {
>             throw new JcrMappingException("Cannot create instance for class
> "
>                     + className,
>                     ex);
>         }
>     }
>
>     /**
>      * @param object
>      * @param fieldName
>      * @param path
>      */
>     public static void setNestedProperty(Object object, String fieldName,
> Object value) {
>         try {
>             PropertyUtils.setNestedProperty(object, fieldName, value);
>         }
>         catch(Exception ex) {
>             throw new JcrMappingException("Cannot set the field " +
> fieldName + " in the class : " + object.getClass().toString(),
>                     ex);
>         }
>     }
>
>     /**
>      * @param string
>      * @return
>      */
>     public static Object newInstance(String clazz) {
>         try {
>             return ReflectionUtils.forName(clazz).newInstance();
>         }
>         catch(Exception ex) {
>             throw new JcrMappingException("Cannot create instance for class
> "
>                     + clazz,
>                     ex);
>         }
>     }
>
>     /**
>      * @param elementClassName
>      * @return
>      */
>     public static Class forName(String clazz) throws JcrMappingException{
>         try {
>             Class aClass = null;
>             if(ReflectionUtils.classLoader!=null){
>                 aClass =  Class.forName(clazz,false,
> ReflectionUtils.classLoader);
>             }
>             if(aClass!=null){
>                 return aClass;
>             }
>
>             return Class.forName(clazz);
>         }
>         catch(Exception ex) {
>             throw new JcrMappingException("Cannot load class " + clazz, ex);
>         }
>     }
>
>     public static boolean isProxy(Class beanClass)
>     {
>          return Enhancer.isEnhanced(beanClass);
>     }
>
>     public static Class getBeanClass(Object bean)
>     {
>              Class beanClass = bean.getClass();
>          if (isProxy(beanClass))
>          {
>                  //CGLIB specific
>                  return beanClass.getSuperclass();
>          }
>          return beanClass;
>     }
>
>     public static ClassLoader getClassLoader() {
>         return ReflectionUtils.classLoader;
>     }
>
>     public static void setClassLoader(ClassLoader classLoader) {
>         ReflectionUtils.classLoader = classLoader;
>     }
>
> }
>
>
> On 4/19/06, Daniel Mora <mo...@gmail.com> wrote:
> >
> > Yes, I am using Tomcat. The problem is that I have a custom classloader
> > called LocalClassLoader and is conflicting with WebAppClassloader, and both
> > are loading DefaultTipology.class from WEB-INF\classes.
> > I had the same problem using XStream, but XStream has the posibility to
> > set the classloader.
> >         ClassLoader classLoader = DefaultTipology.class.getClassLoader();
> >         xstream.setClassLoader(classLoader);
> > The solution I am thinking is to modify some graffito files, for example
> > ReflectionUtils.java , and change Class.forName(className) into
> > Class.forName(className, classloader).
> > Maybe I can contribute with Graffito with this extra feature, what do you
> > think?
> >
> >
> >
> > On 4/19/06, Christophe Lombart <ch...@gmail.com> wrote:
> > >
> > > Graffito is a classic java application. So, classloader is working as
> > > usual.
> > > Can you give me more information on your deployement. How your jars are
> > > deployed ? Are you using Jetspeed ?
> > > Where is deployed DefaultTipology ? Are you using Tomcat ? I'm not sure
> > > it
> > > is necessary to set the classloader.
> > >
> > >
> > > On 4/19/06, Daniel Mora <mo...@gmail.com> wrote:
> > > >
> > > > Hi all,
> > > > I am successfully integrating Graffito mapping tools into my J2EE CMS
> > > > environment. But now Im facing a classloader problem. The following
> > > code
> > > > is
> > > > throwing a ClassCastException in (DefaultTipology) resultIter.next()
> > > > because
> > > > DefaultTipology.class.getClassLoader () != resultIter.next
> > > > ().getClass().getClassLoader()
> > > > One is LocalClassLoader and the other is WebAppClassLoader.
> > > >
> > > >           Filter filter = this.queryManager.createFilter(
> > > > DefaultTipology.class );
> > > >           Query query = this.queryManager.createQuery(filter);
> > > >           Collection result = this.persistenceManager.getObjects
> > > (query);
> > > >           Iterator resultIter = result.iterator();
> > > >           while( resultIter.hasNext()){
> > > >               DefaultTipology defTipo = (DefaultTipology)
> > > resultIter.next
> > > > ();
> > > >               this.tipologyIds.put(defTipo.getIdName(),defTipo);
> > > >           }
> > > >
> > > > Is there a way to set the classloader in graffito, in order to have
> > > only
> > > > one
> > > > instance of a class?
> > > >
> > > >
> > >
> > >
> > > --
> > > Best regards,
> > >
> > > Christophe
> > >
> > >
> >
>
>