SourceForge.net Logo
Main Overview Wiki Issues Forum Build Fisheye
Issue Details (XML | Word | Printable)

Key: CMP-912
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Shay Banon
Reporter: Evgeny Beschastnov
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Compass

Wrong handling of annotations on fields which are collections of parametrized type

Created: 21/Dec/09 07:37 AM   Updated: 08/Jan/10 05:49 AM
Component/s: Compass::Core
Affects Version/s: 2.2.0 GA
Fix Version/s: 2.3.0 beta1


 Description  « Hide
Say, we have this class:
@Entity
@Searcheable
public class Document {
...
    @OneToMany
    @SearchableComponent
    private List<DocumentAttribute<?>> attributes;
...
}

When performing this operations:

CompassConfiguration conf = 
    new CompassConfiguration()
        .setSetting(CompassEnvironment.CONNECTION, "my/index/dir")
        .addScan("my.general.package");

I have this exception:

Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class
	at org.compass.annotations.config.binding.AnnotationsBindingUtils.getCollectionParameterClass(AnnotationsBindingUtils.java:55)
	at org.compass.annotations.config.binding.AnnotationsMappingBinding.getConverter(AnnotationsMappingBinding.java:998)
	at org.compass.annotations.config.binding.AnnotationsMappingBinding.bindConverter(AnnotationsMappingBinding.java:994)
	at org.compass.annotations.config.binding.AnnotationsMappingBinding.bindComponent(AnnotationsMappingBinding.java:622)
	at org.compass.annotations.config.binding.AnnotationsMappingBinding.processsAnnotatedElement(AnnotationsMappingBinding.java:529)
	at org.compass.annotations.config.binding.AnnotationsMappingBinding.processAnnotatedClass(AnnotationsMappingBinding.java:478)
	at org.compass.annotations.config.binding.AnnotationsMappingBinding.processAnnotatedClass(AnnotationsMappingBinding.java:403)
	at org.compass.annotations.config.binding.AnnotationsMappingBinding.addClass(AnnotationsMappingBinding.java:243)
	at org.compass.core.config.binding.AbstractClassMetaDataMappingBinding.doAddInputStream(AbstractClassMetaDataMappingBinding.java:39)
	at org.compass.core.config.binding.AbstractInputStreamMappingBinding.internalAddInputStream(AbstractInputStreamMappingBinding.java:198)
	at org.compass.core.config.binding.AbstractInputStreamMappingBinding.addInputStream(AbstractInputStreamMappingBinding.java:180)
	at org.compass.core.config.CompassMappingBinding.addInputStream(CompassMappingBinding.java:191)
	at org.compass.core.config.CompassConfiguration.addScan(CompassConfiguration.java:593)
	at org.compass.core.config.CompassConfiguration.addScan(CompassConfiguration.java:547)

I looked through code:

AnnotationsBindingUtils.java
public static Class getCollectionParameterClass(Class<?> clazz, Type type) {
        if (Collection.class.isAssignableFrom(clazz)) {
            if (type instanceof ParameterizedType) {
                ParameterizedType paramType = (ParameterizedType) type;
                Type[] actualTypeArguments = paramType.getActualTypeArguments();
                if (actualTypeArguments != null && actualTypeArguments.length == 1) {
                    return (Class) actualTypeArguments[0];
                }
            }
        }
        return null;
    }

and for me it looks like the problem is in straight casting of actualTypeArguments[0] to Class, when actually it is ParameterizedTypeImpl.

Possible, there should be something like this:

AnnotationsBindingUtils.java
public static Class getCollectionParameterClass(Class<?> clazz, Type type) {
        if (Collection.class.isAssignableFrom(clazz)) {
            if (type instanceof ParameterizedType) {
                ParameterizedType paramType = (ParameterizedType) type;
                Type[] actualTypeArguments = paramType.getActualTypeArguments();
                if (actualTypeArguments != null && actualTypeArguments.length == 1) {
                    Type actualType = actualTypeArguments[0];
                    if (actualType instanceof Class) {
                        return (Class) actualTypeArguments[0];
                    } else if (actualType instanceof ParameterizedType) {
                        return (Class) ((ParameterizedType) actualType).getRawType();
                    }
                }
            }
        }
        return null;
    }


 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Shay Banon added a comment - 08/Jan/10 05:49 AM
Fixed, applied the changes you suggested.