Has successfully recreate this defect.
I think the null value of superType is the root cause for this defect.
On Tue, Dec 9, 2008 at 2:59 PM, Kevin Zhou <[EMAIL PROTECTED]> wrote:
> Thereinto, StandBeanInfo.mergeProps method is used to merge the
> PropertyDescriptor with superclass.
> The "superType" is the type of one of its super classes's propreties.
>
>
> On Tue, Dec 9, 2008 at 2:53 PM, Kevin Zhou <[EMAIL PROTECTED]> wrote:
>
>> From the trace, the NPE is thrown from StandBeanInfo.mergeProps() (line
>> 295):
>> if (subType != null &&subType.getName().equals(superType.getName())) {
>> //295
>> ...
>> }
>> where "superType" may be null.
>> Next Action: Will Construct test framework for this, and check whether
>> this is the root cause for this defect.
>>
>>
>> On Tue, Dec 9, 2008 at 2:17 PM, chunrong lai <[EMAIL PROTECTED]>wrote:
>>
>>>
>>> hi, colleagues:
>>> Sorry for the late report. But I see that the struts test suite is
>>> breaking due to r647921 with below stackTrace:
>>>
>>> Caused by: java.lang.NullPointerException
>>> at
>>> java.beans.StandardBeanInfo.mergeProps(StandardBeanInfo.java:295)
>>> at
>>> java.beans.StandardBeanInfo.mergeBeanInfo(StandardBeanInfo.java:209)
>>> at java.beans.Introspector.getBeanInfoImpl(Introspector.java:282)
>>> at
>>> java.beans.Introspector.getBeanInfoImplAndInit(Introspector.java:347)
>>> at java.beans.Introspector.getBeanInfo(Introspector.java:162)
>>> at
>>> freemarker.ext.beans.BeansWrapper.populateClassMapWithBeanInfo(BeansW
>>> rapper.java:844)
>>> ... 52 more
>>>
>>> To reproduce the error one needs to (reproducible in windows and
>>> Linux platforms)
>>> (1) Start a webserver
>>> (1.1) Extract apache-tomcat-6.0.18.tar.gz from (
>>> http://tomcat.apache.org/download-60.cgi) and cd the extracted directory
>>> "apache-tomcat-6.0.18".
>>> (1.2) Create apache-tomcat-6.0.18/my_base,
>>> apache-tomcat-6.0.18/struts_test, apache-tomcat-6.0.18/struts_test/logs,
>>> apache-tomcat-6.0.18/struts_test/temp,
>>> apache-tomcat-6.0.18/struts_test/webapps/,
>>> apache-tomcat-6.0.18/struts_test/work,
>>> (1.3) Copy struts2-showcase-2.0.6.war (in
>>> struts-2.0.6-all/apps/ extracted from
>>> http://archive.apache.org/dist/struts/binaries/struts-2.0.6-all.zip) to
>>> apache-tomcat-6.0.18/struts_test, copy apache-tomcat-6.0.18/conf to
>>> apache-tomcat-6.0.18/struts_test
>>> (1.4) set
>>> CATALINA_BASE=…./apache-tomcat-6.0.18/my_base/struts_test, set
>>> JRE_HOME=......
>>> (1.5) cd …./apache-tomcat-6.0.18/, $bin/catalina.sh run (or
>>> catalina.bat for windows platform)
>>>
>>> (2) Run the attached test case seperatedly
>>> (2.1) Unzip the htmlunit-2.3.zip from
>>> http://sourceforge.net/project/showfiles.php?group_id=47038 and include
>>> the jar files from "htmlunit-2.3/lib into CLASSPATH
>>> (2.2) Compile and run the attached test case (also listed below),
>>> check the content of the result named debug.html to see the reported
>>> exception
>>>
>>> import java.io.*;
>>> import java.net.URL;
>>> import java.lang.Thread;
>>> import java.util.*;
>>> import java.io.FileOutputStream;
>>> import com.gargoylesoftware.htmlunit.WebClient;
>>> import com.gargoylesoftware.htmlunit.html.HtmlPage;
>>>
>>> public class struts_test_debug{
>>> public static void test_1(){
>>> try{
>>> URL baseurl=new URL("http://localhost:8080");
>>> String p = "/struts2-showcase-2.0.6/tags/non-ui/debug.jsp";
>>> final WebClient webClient = new WebClient();
>>> final HtmlPage page = (HtmlPage)webClient.getPage(new
>>> URL(baseurl,p));
>>> //get the source code of webpage
>>> String pHtml = page.getWebResponse().getContentAsString();
>>> writeFile(pHtml);
>>> System.out.println("Generated file: 'Debug.html' in local");
>>> }catch(Exception e){}
>>> }
>>>
>>> public static void main(String args[]){
>>> System.out.println("test start!");
>>> System.out.println("Reading remote file ...");
>>> test_1();
>>> System.out.println("test finished!");
>>> }
>>> public static void writeFile(String pHtml){
>>> try{
>>> FileOutputStream out = new FileOutputStream("Debug.html",false);
>>> out.write(pHtml.getBytes());
>>> }catch(Exception e){}
>>> }
>>> }
>>>
>>>
>>> From [EMAIL PROTECTED] Subject svn commit: r647921 - in
>>> /harmony/enhanced/classlib/trunk/modules/beans/src:
>>> main/java/java/beans/StandardBeanInfo.java
>>> test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
>>> Date Mon, 14 Apr 2008 18:00:13 GMT
>>>
>>> Author: ayza
>>> Date: Mon Apr 14 11:00:08 2008
>>> New Revision: 647921
>>>
>>> URL: http://svn.apache.org/viewvc?rev=647921&view=rev
>>> Log:
>>> Applying patches from HARMONY-5675 ([classlib][beans] Introspector unable
>>> to determine set
>>> method correctly)
>>>
>>> Modified:
>>>
>>> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
>>>
>>> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
>>>
>>> Modified:
>>> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
>>> URL:
>>> http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java?rev=647921&r1=647920&r2=647921&view=diff
>>> ==============================================================================
>>> ---
>>> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
>>> (original)
>>> +++
>>> harmony/enhanced/classlib/trunk/modules/beans/src/main/java/java/beans/StandardBeanInfo.java
>>> Mon Apr 14 11:00:08 2008
>>> @@ -47,6 +47,22 @@
>>>
>>> private static final String SUFFIX_LISTEN = "Listener"; //$NON-NLS-1$
>>>
>>> + private static final String STR_NORMAL = "normal"; //$NON-NLS-1$
>>> +
>>> + private static final String STR_INDEXED = "indexed"; //$NON-NLS-1$
>>> +
>>> + private static final String STR_VALID = "valid"; //$NON-NLS-1$
>>> +
>>> + private static final String STR_INVALID = "invalid"; //$NON-NLS-1$
>>> +
>>> + private static final String STR_PROPERTY_TYPE = "PropertyType";
>>> //$NON-NLS-1$
>>> +
>>> + private static final String STR_IS_CONSTRAINED = "isConstrained";
>>> //$NON-NLS-1$
>>> +
>>> + private static final String STR_SETTERS = "setters"; //$NON-NLS-1$
>>> +
>>> + private static final String STR_GETTERS = "getters"; //$NON-NLS-1$
>>> +
>>> private boolean explicitMethods = false;
>>>
>>> private boolean explicitProperties = false;
>>> @@ -276,7 +292,8 @@
>>> // Sub is PropertyDescriptor
>>> if (subIndexedType == null) {
>>> // Same property type
>>> - if (subType.getName().equals(superType.getName())) {
>>> + if (subType != null &&
>>> + subType.getName().equals(superType.getName()))
>>> {
>>> if ((subGet == null) && (superGet != null)) {
>>> subDesc.setReadMethod(superGet);
>>> }
>>> @@ -481,8 +498,6 @@
>>> * Introspects the supplied class and returns a list of the public
>>> methods
>>> * of the class
>>> *
>>> - * @param beanClass -
>>> - * the class
>>> * @return An array of MethodDescriptors with the public methods. null
>>> if
>>> * there are no public methods
>>> */
>>> @@ -533,8 +548,8 @@
>>> * Introspects the supplied class and returns a list of the Properties
>>> of
>>> * the class
>>> *
>>> - * @param beanClass -
>>> - * the Class
>>> + * @param stopClass -
>>> + * the to introspecting at
>>> * @return The list of Properties as an array of PropertyDescriptors
>>> * @throws IntrospectionException
>>> */
>>> @@ -557,6 +572,9 @@
>>> introspectSet(theMethods[i].getMethod(), propertyTable);
>>> }
>>>
>>> + // fix possible getter & setter collisions
>>> + fixGetSet(propertyTable);
>>> +
>>> // If there are listener methods, should be bound.
>>> MethodDescriptor[] allMethods = introspectMethods(true);
>>> if (stopClass != null) {
>>> @@ -586,17 +604,17 @@
>>> if (table == null) {
>>> continue;
>>> }
>>> - String normalTag = (String) table.get("normal"); //$NON-NLS-1$
>>> - String indexedTag = (String) table.get("indexed");
>>> //$NON-NLS-1$
>>> + String normalTag = (String) table.get(STR_NORMAL);
>>> + String indexedTag = (String) table.get(STR_INDEXED);
>>>
>>> if ((normalTag == null) && (indexedTag == null)) {
>>> continue;
>>> }
>>>
>>> - Method get = (Method) table.get("normalget"); //$NON-NLS-1$
>>> - Method set = (Method) table.get("normalset"); //$NON-NLS-1$
>>> - Method indexedGet = (Method) table.get("indexedget");
>>> //$NON-NLS-1$
>>> - Method indexedSet = (Method) table.get("indexedset");
>>> //$NON-NLS-1$
>>> + Method get = (Method) table.get(STR_NORMAL + PREFIX_GET);
>>> + Method set = (Method) table.get(STR_NORMAL + PREFIX_SET);
>>> + Method indexedGet = (Method) table.get(STR_INDEXED +
>>> PREFIX_GET);
>>> + Method indexedSet = (Method) table.get(STR_INDEXED +
>>> PREFIX_SET);
>>>
>>> PropertyDescriptor propertyDesc = null;
>>> if (indexedTag == null) {
>>> @@ -619,7 +637,7 @@
>>> } else {
>>> propertyDesc.setBound(false);
>>> }
>>> - if (table.get("isConstrained") == Boolean.TRUE) { //$NON-NLS-1$
>>> + if (table.get(STR_IS_CONSTRAINED) == Boolean.TRUE) {
>>> //$NON-NLS-1$
>>> propertyDesc.setConstrained(true);
>>> }
>>> propertyList.add(propertyDesc);
>>> @@ -659,13 +677,20 @@
>>> @SuppressWarnings("unchecked")
>>> private static void introspectGet(Method theMethod,
>>> HashMap<String, HashMap> propertyTable) {
>>> - String methodName = theMethod.getName();
>>> - if (methodName == null) {
>>> +
>>> + String methodName = theMethod.getName();
>>> + int prefixLength = 0;
>>> + String propertyName;
>>> + Class propertyType;
>>> + Class[] paramTypes;
>>> + HashMap table;
>>> + ArrayList<Method> getters;
>>> +
>>> + if (methodName == null) {
>>> return;
>>> }
>>>
>>> - int prefixLength = 0;
>>> - if (methodName.startsWith(PREFIX_GET)) {
>>> + if (methodName.startsWith(PREFIX_GET)) {
>>> prefixLength = PREFIX_GET.length();
>>> }
>>>
>>> @@ -677,153 +702,325 @@
>>> return;
>>> }
>>>
>>> - String propertyName =
>>> decapitalize(methodName.substring(prefixLength));
>>> - // validate property name
>>> + propertyName = decapitalize(methodName.substring(prefixLength));
>>> +
>>> + // validate property name
>>> if (!isValidProperty(propertyName)) {
>>> return;
>>> }
>>>
>>> - Class propertyType = theMethod.getReturnType();
>>> + // validate return type
>>> + propertyType = theMethod.getReturnType();
>>>
>>> - // check return type getMethod
>>> - if (propertyType.getName().equals(Void.TYPE.getName())) {
>>> - return;
>>> - }
>>> + if (propertyType == null || propertyType == void.class) {
>>> + return;
>>> + }
>>>
>>> // isXXX return boolean
>>> if (prefixLength == 2) {
>>> - if
>>> (!propertyType.getName().equals(Boolean.TYPE.getName())) {
>>> + if (!(propertyType == boolean.class)) {
>>> return;
>>> }
>>> }
>>>
>>> - // indexed get method
>>> - Class[] paramTypes = theMethod.getParameterTypes();
>>> -
>>> - if (paramTypes.length > 1) {
>>> + // validate parameter types
>>> + paramTypes = theMethod.getParameterTypes();
>>> + if (paramTypes.length > 1 ||
>>> + (paramTypes.length == 1 && paramTypes[0] != int.class)) {
>>> return;
>>> }
>>>
>>> - String tag = "normal"; //$NON-NLS-1$
>>> -
>>> - if (paramTypes.length == 1) {
>>> - if
>>> (paramTypes[0].getName().equals(Integer.TYPE.getName())) {
>>> - tag = "indexed"; //$NON-NLS-1$
>>> - } else {
>>> - return;
>>> - }
>>> + //
>>>
>>> - }
>>> -
>>> - HashMap table = propertyTable.get(propertyName);
>>> + table = propertyTable.get(propertyName);
>>> if (table == null) {
>>> table = new HashMap();
>>> propertyTable.put(propertyName, table);
>>> }
>>>
>>> - // the "get" propertyType is conflict with "set" propertyType
>>> - Class oldPropertyType = (Class) table.get(tag +
>>> "PropertyType"); //$NON-NLS-1$
>>> - if ((oldPropertyType != null)
>>> - &&
>>> (!oldPropertyType.getName().equals(propertyType.getName()))) {
>>> - table.put(tag, "invalid"); //$NON-NLS-1$
>>> - table.remove(tag + "set"); //$NON-NLS-1$
>>> - } else {
>>> - table.put(tag, "valid"); //$NON-NLS-1$
>>> - }
>>> -
>>> - table.put(tag + "PropertyType", propertyType); //$NON-NLS-1$
>>> + getters = (ArrayList<Method>) table.get(STR_GETTERS);
>>> + if (getters == null) {
>>> + getters = new ArrayList<Method>();
>>> + table.put(STR_GETTERS, getters);
>>> + }
>>>
>>> - // According to the spec "is" method should be used prior to
>>> "get"
>>> - if (prefixLength == 3) {
>>> - if (!table.containsKey(tag + "get")) { //$NON-NLS-1$
>>> - table.put(tag + "get", theMethod); //$NON-NLS-1$
>>> - }
>>> - } else {
>>> - table.put(tag + "get", theMethod); //$NON-NLS-1$
>>> - }
>>> - }
>>> + // add current method as a valid getter
>>> + getters.add(theMethod);
>>> + }
>>>
>>> @SuppressWarnings("unchecked")
>>> private static void introspectSet(Method theMethod,
>>> HashMap<String, HashMap> propertyTable) {
>>> - String methodName = theMethod.getName();
>>> - if (methodName == null) {
>>> - return;
>>> - }
>>>
>>> - int prefixLength = 0;
>>> - if (methodName.startsWith(PREFIX_SET)) {
>>> - prefixLength = PREFIX_GET.length();
>>> - }
>>> + String methodName = theMethod.getName();
>>> + String propertyName;
>>> + Class returnType;
>>> + Class[] paramTypes;
>>>
>>> - if (prefixLength == 0) {
>>> + if (methodName == null || !methodName.startsWith(PREFIX_SET)) {
>>> return;
>>> }
>>>
>>> - String propertyName =
>>> decapitalize(methodName.substring(prefixLength));
>>> + propertyName = decapitalize(methodName.substring(
>>> + PREFIX_SET.length()));
>>>
>>> // validate property name
>>> if (!isValidProperty(propertyName)) {
>>> return;
>>> }
>>>
>>> - Class returnType = theMethod.getReturnType();
>>> + // validate return type
>>> + returnType = theMethod.getReturnType();
>>>
>>> - if (!returnType.getName().equals(Void.TYPE.getName())) {
>>> +// if (!returnType.getName().equals(Void.TYPE.getName())) {
>>> + if (!(returnType == void.class)) {
>>> return;
>>> }
>>>
>>> - // indexed get method
>>> - Class[] paramTypes = theMethod.getParameterTypes();
>>> + // validate param types
>>> + paramTypes = theMethod.getParameterTypes();
>>>
>>> - if ((paramTypes.length == 0) || (paramTypes.length > 2)) {
>>> + if (paramTypes.length == 0 || paramTypes.length > 2 ||
>>> + (paramTypes.length == 2 && paramTypes[0] != int.class)) {
>>> return;
>>> }
>>>
>>> - String tag = "normal"; //$NON-NLS-1$
>>> -
>>> - Class propertyType = paramTypes[0];
>>> -
>>> - if (paramTypes.length == 2) {
>>> - if (paramTypes[0].getName().equals(Integer.TYPE.getName())) {
>>> - tag = "indexed"; //$NON-NLS-1$
>>> - propertyType = paramTypes[1];
>>> - } else {
>>> - return;
>>> - }
>>> - }
>>> + //
>>>
>>> HashMap table = propertyTable.get(propertyName);
>>> if (table == null) {
>>> table = new HashMap();
>>> + propertyTable.put(propertyName, table);
>>> }
>>>
>>> - Class oldPropertyType = (Class) table.get(tag + "PropertyType");
>>> //$NON-NLS-1$
>>> - if ((oldPropertyType != null)
>>> - &&
>>> (!oldPropertyType.getName().equals(propertyType.getName()))) {
>>> - table.put(tag, "invalid"); //$NON-NLS-1$
>>> - return;
>>> + ArrayList<Method> setters = (ArrayList<Method>)
>>> table.get(STR_SETTERS);
>>> + if (setters == null) {
>>> + setters = new ArrayList<Method>();
>>> + table.put(STR_SETTERS, setters);
>>> }
>>>
>>> - table.put(tag, "valid"); //$NON-NLS-1$
>>> - table.put(tag + "set", theMethod); //$NON-NLS-1$
>>> - table.put(tag + "PropertyType", propertyType); //$NON-NLS-1$
>>> -
>>> // handle constrained
>>> Class[] exceptions = theMethod.getExceptionTypes();
>>> for (Class e : exceptions) {
>>> if (e.equals(PropertyVetoException.class)) {
>>> - table.put("isConstrained", Boolean.TRUE); //$NON-NLS-1$
>>> + table.put(STR_IS_CONSTRAINED, Boolean.TRUE); //$NON-NLS-1$
>>> + }
>>> + }
>>> +
>>> + // add new setter
>>> + setters.add(theMethod);
>>> + }
>>> +
>>> + /**
>>> + * Checks and fixs all cases when several incompatible checkers /
>>> + * getters were specified for single property.
>>> + * @param propertyTable
>>> + * @throws IntrospectionException
>>> + */
>>> + private void fixGetSet(HashMap<String, HashMap> propertyTable)
>>> + throws IntrospectionException {
>>> +
>>> + if (propertyTable == null) {
>>> + return;
>>> + }
>>> +
>>> + for (String key : propertyTable.keySet()) {
>>> + HashMap<String, Object> table = propertyTable.get(key);
>>> + ArrayList<Method> getters = (ArrayList<Method>)
>>> table.get(STR_GETTERS);
>>> + ArrayList<Method> setters = (ArrayList<Method>)
>>> table.get(STR_SETTERS);
>>> +
>>> + Method normalGetter = null;
>>> + Method indexedGetter = null;
>>> + Method normalSetter = null;
>>> + Method indexedSetter = null;
>>> +
>>> + Class normalPropType = null;
>>> + Class indexedPropType = null;
>>> +
>>> + if (getters == null) {
>>> + getters = new ArrayList<Method>();
>>> + }
>>> +
>>> + if (setters == null) {
>>> + setters = new ArrayList<Method>();
>>> + }
>>> +
>>> + // retrieve getters
>>> + for (Method getter: getters) {
>>> + // checks if it's a normal getter
>>> + if (getter.getParameterTypes() == null ||
>>> + getter.getParameterTypes().length == 0) {
>>> + // normal getter found
>>> + if (normalGetter == null ||
>>> + getter.getName().startsWith(PREFIX_IS)) {
>>> + normalGetter = getter;
>>> + }
>>> + }
>>> +
>>> + // checks if it's an indexed getter
>>> + if (getter.getParameterTypes() != null &&
>>> + getter.getParameterTypes().length == 1 &&
>>> + getter.getParameterTypes()[0] == int.class) {
>>> + // indexed getter found
>>> + if (indexedGetter == null ||
>>> + getter.getName().startsWith(PREFIX_IS)) {
>>> + indexedGetter = getter;
>>> + }
>>> + }
>>> + }
>>> +
>>> + // retrieve normal setter
>>> + if (normalGetter != null) {
>>> + // Now we will try to look for normal setter of the same
>>> type.
>>> + Class propertyType = normalGetter.getReturnType();
>>> +
>>> + for (Method setter: setters) {
>>> + if (setter.getParameterTypes().length == 1 &&
>>> +
>>> propertyType.equals(setter.getParameterTypes()[0]))
>>> + {
>>> + normalSetter = setter;
>>> + break;
>>> + }
>>> + }
>>> + } else {
>>> + // Normal getter wasn't defined. Let's look for the last
>>> + // defined setter
>>> +
>>> + for (Method setter: setters) {
>>> + if (setter.getParameterTypes().length == 1) {
>>> + normalSetter = setter;
>>> + }
>>> + }
>>> }
>>> +
>>> + // retrieve indexed setter
>>> + if (indexedGetter != null) {
>>> + // Now we will try to look for indexed setter of the same
>>> type.
>>> + Class propertyType = indexedGetter.getReturnType();
>>> +
>>> + for (Method setter: setters) {
>>> + if (setter.getParameterTypes().length == 2 &&
>>> + setter.getParameterTypes()[0] == int.class &&
>>> +
>>> propertyType.equals(setter.getParameterTypes()[1]))
>>> + {
>>> + indexedSetter = setter;
>>> + break;
>>> + }
>>> + }
>>> + } else {
>>> + // Indexed getter wasn't defined. Let's look for the last
>>> + // defined indexed setter
>>> +
>>> + for (Method setter: setters) {
>>> + if (setter.getParameterTypes().length == 2 &&
>>> + setter.getParameterTypes()[0] == int.class) {
>>> + indexedSetter = setter;
>>> + }
>>> + }
>>> + }
>>> +
>>> + // determine property type
>>> + if (normalGetter != null) {
>>> + normalPropType = normalGetter.getReturnType();
>>> + } else if (normalSetter != null) {
>>> + normalPropType = normalSetter.getParameterTypes()[0];
>>> + }
>>> +
>>> + // determine indexed getter/setter type
>>> + if (indexedGetter != null) {
>>> + indexedPropType = indexedGetter.getReturnType();
>>> + } else if (indexedSetter != null) {
>>> + indexedPropType = indexedSetter.getParameterTypes()[1];
>>> + }
>>> +
>>> + // convert array-typed normal getters to indexed getters
>>> + if (normalGetter != null &&
>>> normalGetter.getReturnType().isArray())
>>> + {
>>> +
>>> + }
>>> +
>>> + // RULES
>>> + // These rules were created after performing extensive
>>> black-box
>>> + // testing of RI
>>> +
>>> + // RULE1
>>> + // Both normal getter and setter of the same type were defined;
>>> + // no indexed getter/setter *PAIR* of the other type defined
>>> + if (normalGetter != null && normalSetter != null &&
>>> + (indexedGetter == null || indexedSetter == null) &&
>>> + normalPropType != indexedPropType) {
>>> +// String tag = normalPropType.isArray() ?
>>> +// STR_INDEXED : STR_NORMAL;
>>> + String tag = STR_NORMAL;
>>> +
>>> + table.put(tag, STR_VALID);
>>> + table.put(tag + PREFIX_GET, normalGetter);
>>> + table.put(tag + PREFIX_SET, normalSetter);
>>> + table.put(tag + STR_PROPERTY_TYPE, normalPropType);
>>> + continue;
>>> + }
>>> +
>>> + // RULE2
>>> + // normal getter and/or setter was defined; no indexed
>>> + // getters & setters defined
>>> + if ((normalGetter != null || normalSetter != null) &&
>>> + indexedGetter == null && indexedSetter == null) {
>>> +// String tag = normalPropType.isArray() ?
>>> +// STR_INDEXED : STR_NORMAL;
>>> + String tag = STR_NORMAL;
>>> +
>>> + table.put(tag, STR_VALID);
>>> + table.put(tag + PREFIX_GET, normalGetter);
>>> + table.put(tag + PREFIX_SET, normalSetter);
>>> + table.put(tag + STR_PROPERTY_TYPE, normalPropType);
>>> + continue;
>>> + }
>>> +
>>> + // RULE3
>>> + // mix of normal / indexed getters and setters are defined.
>>> Types
>>> + // are compatible
>>> + if ((normalGetter != null || normalSetter != null) &&
>>> + (indexedGetter != null || indexedSetter != null) &&
>>> + normalPropType.isArray() &&
>>> + normalPropType.getComponentType() == indexedPropType) {
>>> + table.put(STR_NORMAL, STR_VALID);
>>> + table.put(STR_NORMAL + PREFIX_GET, normalGetter);
>>> + table.put(STR_NORMAL + PREFIX_SET, normalSetter);
>>> + table.put(STR_NORMAL + STR_PROPERTY_TYPE, normalPropType);
>>> +
>>> + table.put(STR_INDEXED, STR_VALID);
>>> + table.put(STR_INDEXED + PREFIX_GET, indexedGetter);
>>> + table.put(STR_INDEXED + PREFIX_SET, indexedSetter);
>>> + table.put(STR_INDEXED + STR_PROPERTY_TYPE,
>>> indexedPropType);
>>> +
>>> + continue;
>>> + }
>>> +
>>> + // RULE4
>>> + // no normal normal getter / setter.
>>> + // Only indexed getter and/or setter is given
>>> + // no normal setters / getters defined
>>> + if (normalSetter == null && normalGetter == null &&
>>> + (indexedGetter != null || indexedSetter != null)) {
>>> + table.put(STR_INDEXED, STR_VALID);
>>> + table.put(STR_INDEXED + PREFIX_GET, indexedGetter);
>>> + table.put(STR_INDEXED + PREFIX_SET, indexedSetter);
>>> + table.put(STR_INDEXED + STR_PROPERTY_TYPE,
>>> + indexedPropType);
>>> + continue;
>>> + }
>>> +
>>> + // default rule - invalid property
>>> + table.put(STR_NORMAL, STR_INVALID);
>>> + table.put(STR_INDEXED, STR_INVALID);
>>> }
>>> - propertyTable.put(propertyName, table);
>>> +
>>> }
>>>
>>> /**
>>> * Introspects the supplied Bean class and returns a list of the
>>> Events of
>>> * the class
>>> *
>>> - * @param beanClass
>>> * @return the events
>>> * @throws IntrospectionException
>>> */
>>>
>>> Modified:
>>> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
>>> URL:
>>> http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java?rev=647921&r1=647920&r2=647921&view=diff
>>> ==============================================================================
>>> ---
>>> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
>>> (original)
>>> +++
>>> harmony/enhanced/classlib/trunk/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/IntrospectorTest.java
>>> Mon Apr 14 11:00:08 2008
>>> @@ -2331,4 +2331,254 @@
>>> assertFalse(pd.getName().equals("invisible"));
>>> }
>>> }
>>> +
>>> + /**
>>> + * Tests tricky cases when several conflicting set/get methods are
>>> defined.
>>> + * All these tests pass on RI.
>>> + * This is a regression test for HARMONY-5675
>>> + * @throws IntrospectionException
>>> + */
>>> + public void test5675() throws IntrospectionException {
>>> + BeanInfo bInfo;
>>> +
>>> + for (Class clz: new Class[] {TstBean5675.class,
>>> TstBean5675_2.class}) {
>>> +
>>> + bInfo = Introspector.getBeanInfo(clz);
>>> +
>>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors()) {
>>> +
>>> + if (desc.getName().equals("prop1")) {
>>> + assertNotNull("invalid get method",
>>> desc.getReadMethod());
>>> + assertEquals("get method has invalid return type",
>>> + Integer.class,
>>> desc.getReadMethod().getReturnType());
>>> + assertNotNull("invalid set method",
>>> desc.getWriteMethod());
>>> + assertEquals("invalid set method",
>>> + "setProp1", desc.getWriteMethod().getName());
>>> + assertNotNull("set method don't have any parameters",
>>> + desc.getWriteMethod().getParameterTypes());
>>> + assertEquals("set method has invalid parameters",
>>> + Integer.class,
>>> + desc.getWriteMethod().getParameterTypes()[0]);
>>> + }
>>> + }
>>> + }
>>> +
>>> + for (Class clz : new Class[] {TstBean5675_3.class,
>>> TstBean5675_5.class,
>>> + TstBean5675_6.class}) {
>>> +
>>> + bInfo = Introspector.getBeanInfo(clz);
>>> +
>>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors()) {
>>> +
>>> + if (desc.getName().equals("prop1")) {
>>> + assertNull("Non-null get method",
>>> desc.getReadMethod());
>>> + assertNull("Non-null set method",
>>> desc.getWriteMethod());
>>> + }
>>> + }
>>> + }
>>> +
>>> + bInfo = Introspector.getBeanInfo(TstBean5675_4.class);
>>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors()) {
>>> +
>>> + if (desc.getName().equals("prop1")) {
>>> + assertNotNull("invalid get method", desc.getReadMethod());
>>> + assertEquals("get method has invalid return type",
>>> + Integer.class, desc.getReadMethod().getReturnType());
>>> + assertNull("Non-null set method", desc.getWriteMethod());
>>> + }
>>> + }
>>> +
>>> + bInfo = Introspector.getBeanInfo(TstBean5675_7.class);
>>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors()) {
>>> +
>>> + if (desc.getName().equals("prop1")) {
>>> + assertNull("Non-null get method", desc.getReadMethod());
>>> + assertEquals("invalid set method",
>>> + "setProp1", desc.getWriteMethod().getName());
>>> + assertNotNull("set method don't have any parameters",
>>> + desc.getWriteMethod().getParameterTypes());
>>> + assertEquals("set method has invalid parameters",
>>> + Integer.class,
>>> + desc.getWriteMethod().getParameterTypes()[0]);
>>> + }
>>> + }
>>> +
>>> + bInfo = Introspector.getBeanInfo(TstBean5675_8.class);
>>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors()) {
>>> +
>>> + if (desc.getName().equals("prop1")) {
>>> + assertNotNull("invalid get method", desc.getReadMethod());
>>> + assertEquals("get method has invalid return type",
>>> + Integer[].class,
>>> desc.getReadMethod().getReturnType());
>>> + assertNull("Non-null set method", desc.getWriteMethod());
>>> + }
>>> + }
>>> +
>>> + bInfo = Introspector.getBeanInfo(TstBean5675_9.class);
>>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors()) {
>>> +
>>> + if (desc.getName().equals("prop1")) {
>>> + assertNull("Non-null get method", desc.getReadMethod());
>>> + assertNotNull("invalid set method", desc.getWriteMethod());
>>> + assertEquals("invalid set method",
>>> + "setProp1", desc.getWriteMethod().getName());
>>> + assertNotNull("set method don't have any parameters",
>>> + desc.getWriteMethod().getParameterTypes());
>>> + assertEquals("set method has invalid parameters",
>>> + Integer[].class,
>>> + desc.getWriteMethod().getParameterTypes()[0]);
>>> + }
>>> + }
>>> +
>>> + bInfo = Introspector.getBeanInfo(TstBean5675_10.class);
>>> + for (PropertyDescriptor desc: bInfo.getPropertyDescriptors()) {
>>> +
>>> + if (desc.getName().equals("prop1")) {
>>> + assertNotNull("invalid get method", desc.getReadMethod());
>>> + assertEquals("get method has invalid return type",
>>> + Integer[].class,
>>> desc.getReadMethod().getReturnType());
>>> + assertNotNull("invalid set method", desc.getWriteMethod());
>>> + assertEquals("invalid set method",
>>> + "setProp1", desc.getWriteMethod().getName());
>>> + assertNotNull("set method don't have any parameters",
>>> + desc.getWriteMethod().getParameterTypes());
>>> + assertEquals("set method has invalid parameters",
>>> + Integer[].class,
>>> + desc.getWriteMethod().getParameterTypes()[0]);
>>> + }
>>> + }
>>> +
>>> + }
>>> +
>>> + class TstBean5675 {
>>> +
>>> + public void setProp1(String uri) {}
>>> +
>>> + public void setProp1(Integer i) {}
>>> +
>>> +
>>> + public Integer getProp1() {
>>> + return null;
>>> + }
>>> +
>>> + }
>>> +
>>> +
>>> + class TstBean5675_2 {
>>> +
>>> + public Integer getProp1() {
>>> + return null;
>>> + }
>>> +
>>> + public String getProp1(int n) {
>>> + return null;
>>> + }
>>> +
>>> + public void setProp1(Integer val) {}
>>> +
>>> +
>>> + }
>>> +
>>> + class TstBean5675_3 {
>>> +
>>> + public String getProp1(int n) {
>>> + return null;
>>> + }
>>> +
>>> + public void setProp1(int n, String uri) {}
>>> +
>>> + public void setProp1(Integer i) {}
>>> +
>>> + public Integer getProp1() {
>>> + return null;
>>> + }
>>> +
>>> + }
>>> +
>>> + class TstBean5675_4 {
>>> +
>>> + public void setProp1(String val) {}
>>> +
>>> + public Integer getProp1() {
>>> + return null;
>>> + }
>>> +
>>> + }
>>> +
>>> + class TstBean5675_5 {
>>> +
>>> + public Integer getProp1() {
>>> + return null;
>>> + }
>>> +
>>> +// public void setProp1(Integer val) {}
>>> +
>>> + public String getProp1(int n) {
>>> + return null;
>>> + }
>>> +
>>> + public void setProp1(int n, String uri) {}
>>> +
>>> +
>>> + }
>>> +
>>> + class TstBean5675_6 {
>>> +
>>> + public Integer getProp1() {
>>> + return null;
>>> + }
>>> +
>>> +// public void setProp1(Integer val) {}
>>> +//
>>> +// public String getProp1(int n) {
>>> +// return null;
>>> +// }
>>> +
>>> + public void setProp1(int n, String uri) {}
>>> +
>>> +
>>> + }
>>> +
>>> + class TstBean5675_7 {
>>> + public void setProp1(String val) {}
>>> + public void setProp1(Integer val) {}
>>> + }
>>> +
>>> + class TstBean5675_8 {
>>> + public Integer[] getProp1() {
>>> + return null;
>>> + }
>>> +
>>> + //public void setProp1(Integer[] val) {}
>>> +
>>> + public Integer getProp1(int n) {
>>> + return null;
>>> + }
>>> +
>>> + public void setProp1(int n, Integer val) {}
>>> + }
>>> +
>>> + class TstBean5675_9 {
>>> + public void setProp1(Integer[] val) {}
>>> +
>>> + public Integer getProp1(int n) {
>>> + return null;
>>> + }
>>> +
>>> + }
>>> +
>>> + class TstBean5675_10 {
>>> + public Integer[] getProp1() {
>>> + return null;
>>> + }
>>> +
>>> + public void setProp1(Integer[] val) {}
>>> +
>>> + public Integer getProp1(int n) {
>>> + return null;
>>> + }
>>> +
>>> + public void setProp1(int n, Integer val) {}
>>> + }
>>> +
>>> }
>>>
>>>
>>>
>>
>