In my code I have a generic "Value" POJO, which contains value itself and it's class:
public class Value<T extends Serializable> implements Serializable {
private T value;
private Class<T> type;
...
}
I am using Spring Data GemFire and "repositories" feature of Spring Data (the DAOs are created automatically from interfaces). When Spring creates DAO for this bean I got:
FactoryBean threw exception on object creation; nested exception is java.lang.SecurityException: Can not make a java.lang.Class constructor accessible
:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'conditionProcessor': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalStatusElementDAO': FactoryBean threw exception on object creation; nested exception is java.lang.SecurityException: Can not make a java.lang.Class constructor accessible
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:307) ~[spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) ~[spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) ~[spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) ~[spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) ~[spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [spring-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973) [tomcat-embed-core-7.0.52.jar:7.0.52]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467) [tomcat-embed-core-7.0.52.jar:7.0.52]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-7.0.52.jar:7.0.52]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) [tomcat-embed-core-7.0.52.jar:7.0.52]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) [tomcat-embed-core-7.0.52.jar:7.0.52]
at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_51]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_51]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_51]
at java.lang.Thread.run(Thread.java:744) [na:1.7.0_51]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalStatusElementDAO': FactoryBean threw exception on object creation; nested exception is java.lang.SecurityException: Can not make a java.lang.Class constructor accessible
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:151) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:103) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1514) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:445) ~[spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:419) ~[spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:544) ~[spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:155) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:304) ~[spring-context-4.0.2.RELEASE.jar:4.0.2.RELEASE]
... 22 common frames omitted
Caused by: java.lang.SecurityException: Can not make a java.lang.Class constructor accessible
at java.lang.reflect.AccessibleObject.setAccessible0(AccessibleObject.java:139) ~[na:1.7.0_51]
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:129) ~[na:1.7.0_51]
at org.springframework.util.ReflectionUtils.makeAccessible(ReflectionUtils.java:444) ~[spring-core-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.data.mapping.PreferredConstructor.<init>(PreferredConstructor.java:57) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.buildPreferredConstructor(PreferredConstructorDiscoverer.java:106) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.model.PreferredConstructorDiscoverer.<init>(PreferredConstructorDiscoverer.java:74) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.model.BasicPersistentEntity.<init>(BasicPersistentEntity.java:79) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.model.BasicPersistentEntity.<init>(BasicPersistentEntity.java:62) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.gemfire.mapping.GemfirePersistentEntity.<init>(GemfirePersistentEntity.java:40) ~[spring-data-gemfire-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.data.gemfire.mapping.GemfireMappingContext.createPersistentEntity(GemfireMappingContext.java:38) ~[spring-data-gemfire-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.data.gemfire.mapping.GemfireMappingContext.createPersistentEntity(GemfireMappingContext.java:29) ~[spring-data-gemfire-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:246) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:398) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:579) ~[spring-core-4.0.2.RELEASE.jar:4.0.2.RELEASE]
at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:260) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:171) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:140) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentEntity(AbstractMappingContext.java:66) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.gemfire.repository.support.GemfireRepositoryFactory.getEntityInformation(GemfireRepositoryFactory.java:81) ~[spring-data-gemfire-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.data.gemfire.repository.support.GemfireRepositoryFactory.getTargetRepository(GemfireRepositoryFactory.java:97) ~[spring-data-gemfire-1.3.3.RELEASE.jar:1.3.3.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:136) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:153) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:43) ~[spring-data-commons-1.5.3.RELEASE.jar:na]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:144) ~[spring-beans-4.0.2.RELEASE.jar:4.0.2.RELEASE]
... 32 common frames omitted
How can I store java.lang.Class
in GemFire with Spring Data?
UPD:
public interface GlobalStatusElementDAO
extends CrudRepository<GlobalStatusElement, String>
{
}
@Region("xxx")
public class GlobalStatusElement<T extends Serializable>
extends Value<T>
{
public GlobalStatusElement( final Class<T> type )
{
super( type );
}
}
Class objects are generally not amenable to serialising via reflection. It is significantly easier to simply store the full class name and instantiate the class object from the name when you need it.
You could achieve this by either changing your Value
class to store the class name as a String
instead of the class object, or by changing how Value
gets serialised.
For the second option, this can be done either by making Value
implement DataSerializable
, or by registering a DataSerializer
for Value