`

java.lang.reflect.MalformedParameterizedTypeException

    博客分类:
  • JAVA
 
阅读更多

尝试spring3.0的新特性,在原本是spring207,spring256混杂的工程里引入了spring3.x然后很简单的一个bean初始化失败,报以下异常

 

Caused by: java.lang.reflect.MalformedParameterizedTypeException
	at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(Unknown Source)
	at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(Unknown Source)
	at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(Unknown Source)
	at sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(Unknown Source)
	at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Unknown Source)
	at sun.reflect.generics.tree.ClassTypeSignature.accept(Unknown Source)
	at sun.reflect.generics.repository.ClassRepository.getSuperInterfaces(Unknown Source)
	at java.lang.Class.getGenericInterfaces(Unknown Source)
	at org.springframework.core.GenericTypeResolver.getTypeVariableMap(GenericTypeResolver.java:151)
	at org.springframework.core.GenericTypeResolver.resolveParameterType(GenericTypeResolver.java:81)
	at org.springframework.beans.GenericTypeAwarePropertyDescriptor.getWriteMethodParameter(GenericTypeAwarePropertyDescriptor.java:109)
	at org.springframework.beans.GenericTypeAwarePropertyDescriptor.getPropertyType(GenericTypeAwarePropertyDescriptor.java:91)
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1289)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
	... 14 more

 

    然后找出抛出异常的jdk源码

 

 

private void validateConstructorArguments() {
     TypeVariable[] formals = this.rawType.getTypeParameters();
 
   if (formals.length != this.actualTypeArguments.length) {
     throw new MalformedParameterizedTypeException();
   }
    for (int i = 0; i < this.actualTypeArguments.length; ++i);
}

 

利用jdk的fastdebug版本可以看到formals.length == 0 而this.actualTypeArguments.length ==1

并且:

actualTypeArguments 是 【interface org.springframework.core.task.TaskExecutor】

rawType 是【interface org.springframework.beans.factory.FactoryBean】并且不具有泛型参数,故猜测这里需要一个泛型参数是TaskExecutor的FactoryBean。

 

ok,下面开始找出这个bean的实例化是如何进行的,这个bean是spring3.0中新提供的,配置方式如下:

 

<task:executor id="myExecutor" pool-size="5"/>
 

 

通过debug跟踪到spring的BeanDefinitionParserDelegate这个类,然后看如下这个方法

 

 

public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
		String namespaceUri = ele.getNamespaceURI();
		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
		if (handler == null) {
			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
			return null;
		}
		return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
	}
 

为了跟踪这个bean的默认bean实现,我们看他的NamespaceHandler是什么,通过看DefaultNamespaceHandlerResolver这个类可以得知,所有的handler都是从META-INF/spring.handlers文件中读出的,同时如果你打开了debug log的话可以看到他会打印出所有默认的handler,例如打印如下

 

 

Loaded mappings [{http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler, http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler, http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler, http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler, http://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler, http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler, http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler, http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler, http://www.springframework.org/schema/jms=org.springframework.jms.config.JmsNamespaceHandler, http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler, http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler}]

 

这里就有我这次使用到的TaskNamespaceHandler 然后依次找到了 ExecutorBeanDefinitionParser这个类,看到里面的getBeanClassName方法返回的是org.springframework.scheduling.config.TaskExecutorFactoryBean。同时这个类实现了FactoryBean<TaskExecutor>这个接口。发现原来已经给了一个带泛型的FactoryBean了。那到底是哪里的问题呢,继续跟踪。。

 

借助jdk源码以及fastdebug版本,跟踪到sun.reflect.generics.repository.ClassRepository 和 sun.reflect.generics.factory.CoreReflectionFactory这个2个类,看到里面有对应的泛型信息,但是取到的却不对,继续跟踪到Class这个类,其中核心的会使用这个方法

 

public TypeVariable<Class<T>>[] getTypeParameters() {
	if (getGenericSignature() != null) 
	    return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
	else
	    return (TypeVariable<Class<T>>[])new TypeVariable[0];
    }
 

 

debug看到第一个if没通过,所以返回一个空的,那第一个getGenericSignature方法就至关重要了。下面debug这个方法,以下是方法签名:

 // Generic signature handling
    private native String getGenericSignature();

 一看是native方法,好吧直接断了我继续debug的耐心了。不过到这里已经有了一些眉目了,针对这个问题产生的原因,既然是从class的本地元信息中获得泛型信息,那说明这个class文件可能真的就不存在这些元信息,那这样可能就是jar包污染了。然后将spring 207 256的jar包都删除,只保留3.0的,重新debug发现,这次native就有返回值了。程序不再报错了。

 

 

总结:以后遇到这个异常,多半先检查下jar包版本是否存在多个版本,然后最后统一只使用到其中的一个版本来测试,这种问题太难排查了,先把环境搞干净了再debug吧。

分享到:
评论
4 楼 aptech406328627 2016-07-08  
大神,请接收我的膜拜吧,纠结了两天的问题,就这么让你给解决了
3 楼 xukunddp 2016-03-22  
谢谢1楼,我也遇到,搞定了
2 楼 u012273744 2015-04-01  
楼主太厉害了,我也遇到了
1 楼 daoyongyu 2014-08-28  
楼主强人,确实是jar包冲突的问题,我也遇到了。
项目中用到阿里的dubbo框架,它引用的是spring 2.5.6.SEC03,而我项目中有用spring 3.1.x,所以导致冲突。 在maven中将spring的依赖去除了。

             <dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.4.9</version>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>

相关推荐

    scrcpy投屏 AssertionError: java.lang.reflect.InvocationTargetExcep

    标题中的问题“scrcpy投屏 AssertionError: java.lang.reflect.InvocationTargetException”是用户在尝试使用Scrcpy时遇到的一个常见错误。这个错误通常意味着在执行某个方法时,Java运行时环境遇到了未预期的情况。...

    解决axis2-CodegenWizardPluginBUG- java.lang.reflect.InvocationTargetException

    标题中的“解决axis2-CodegenWizardPluginBUG- java.lang.reflect.InvocationTargetException”指的是在使用Apache Axis2的CodegenWizardPlugin工具时遇到的一个错误。这个工具是Axis2框架的一部分,用于自动生成...

    java.lang.reflect.Proxy 学习资料 讲解 例子 源码

    java.lang.reflect.Proxy 学习资料 讲解 例子 源码 java.lang.reflect.Proxy 学习资料 讲解 例子 源码 java.lang.reflect.Proxy 学习资料 讲解 例子 源码

    Java.lang.reflect 包下常用的类及方法简介

    在Java编程语言中,`java.lang.reflect`包是核心库的一部分,它提供了运行时访问类、接口、字段和方法的能力。这个包对于理解和操作对象的动态特性至关重要,尤其是在实现反射机制时。反射允许我们在程序运行期间...

    WebLogic错误 java.lang.AssertionError: Registered more than one

    Caused by: java.lang.RuntimeException: javax.management.remote.JMXServerErrorException: java.lang.AssertionError: Registered more than one instance with the same objectName : com.bea:Name=wl04,Type=...

    MyEclipse axis2 wsdl java.lang.reflect.invocationtargetexception

    MyEclipse axis2 wsdl java.lang.reflect.invocationtargetexception code gen 大家要注意一定要仔细,这个问题基本上缺少包引起的,而且一定要clean 如果需要axis2插件 以及这个plugins中的包在我的其他资源里面有

    java.lang.IllegalArgumentException:Input == null的异常处理

    at javax.imageio.ImageIO.read(ImageIO.java:1388) at com.pleanwar.fiying.FlyingObject.loadImage(FlyingObject.java:52) at com.pleanwar.hero.HeroAirPlean.(HeroAirPlean.java:22) Exception in thre

    Java reflect 机制详解

    免费共享,很详细的介绍了反射机制的原理,适合追根究底的java学习者

    commons-lang3-3.1jar:org.apache.commons.lang3.StringUtils等.

    `org.apache.commons.lang3.reflect.FieldUtils`类则是关于反射操作的工具类,它提供了一些安全且方便的方法来访问和修改对象的字段。这些方法包括但不限于: 1. `getField()`:安全地获取类或对象的字段,即使该...

    Android Caused by: java.lang.ClassNotFoundException解决办法

    "Android Caused by: java.lang.ClassNotFoundException解决办法" 在 Android 开发中,ClassNotFoundException 是一个常见的异常,它通常发生在应用程序启动或运行时。这个异常的出现告诉我们,Java 虚拟机无法找到...

    BEWINDOWEB#bewindoweb.github.io#00078-编写basedao的时候报错:java.lang.C

    编写basedao的时候报错:java.lang.Class cannot be cast to java.lang.reflect.Parameterized

    jaxen.jar和dom4j.jar

    at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run...

    axis2 InvocationTargetException

    标题 "axis2 InvocationTargetException" 描述的是一个与Apache Axis2框架相关的编程问题,该问题通常在执行服务调用时出现,提示"InvocationTargetException"。这可能是由于多种原因引起的,包括但不限于错误的服务...

    aop面向切面需要的jar包

    Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.Access...

    API规范JAVA.pdf

    * java.lang.reflect 是 Java 2 Platform 的一部分,提供了类和接口,以获得关于类和对象的反射信息。 20、数学运算:java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类...

    JAVA反射实现和实现机制

    5. **`java.lang.reflect.Modifier`**:提供对成员的修饰符的访问。 ##### 基本使用方法 1. **获取成员方法信息**: - `Method[] getMethods()`:获取公开的方法。 - `Method getMethod(String name, Class&lt;?&gt;.....

    wsdl生成java客户端报错

    java.lang.reflect.invocationtargetexception问题的解决方法之一

    java 请求的方法不存在(NoSuchMethodException)

    3. **Java动态代理**:基于`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`,实现对目标对象的代理,用于拦截方法调用。 综上所述,`NoSuchMethodException`是Java编程中需要关注的一个重要异常...

    什么是java中的反射机制(reflect).docx

    Java 反射机制的实现是通过 java.lang.Class 类和 java.lang.reflect 包来实现的。Class 类代表了 Java 中的一个类,而 java.lang.reflect 包提供了许多反射类,例如 Constructor、Method、Field 等。 Constructor ...

Global site tag (gtag.js) - Google Analytics