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
> > >
> > >
> >
>
>