Hugo, The root cause of the problem comes from this line of change, it is very subtle, but it indeed causes the problem
Method getMorMethod = dpCls.getDeclaredMethod(methodName, (Class<?>)null); There is a subtle difference between Method getMorMethod = dpCls.getDeclaredMethod(methodName, (Class<?>)null); and Method getMorMethod = dpCls.getDeclaredMethod(methodName, null); a plain null will direct Java to search for a method with no parameters, but a casting of it (Class<?>)null breaks the contract of getDeclareMethod(String, Class<?>…) since Class<?>… is actually of type Class<?>[] so if we really wants explicit typing, it should be written as Method getMorMethod = dpCls.getDeclaredMethod(methodName, (Class<?>[])null); Kelven On 1/23/14, 9:16 AM, "Min Chen" <min.c...@citrix.com> wrote: >It failed in invoking addVmwareDC, where we will invoke vmware API to get >CustomeField. Using java generics, class reflection failed in finding that >declared method, thus throwing NoSuchMethodFound exception. > >Thanks >-min > >On 1/22/14 10:52 PM, "Hugo Trippaers" <h...@trippaers.nl> wrote: > >>Sorry about that :-( Thanks for finding and fixing it. >> >>Where did you encounter the error? I wonder why i didn¹t catch it with my >>tests against vmware. >> >>Cheers, >> >>Hugo >> >>On 23 jan. 2014, at 03:01, Min Chen <min.c...@citrix.com> wrote: >> >>> FYI, I checked in a fix 206c35c620a8e7a707f371e5a9e5dfd795912f5b for >>>this >>> to unblock my testing. >>> >>> Thanks >>> -min >>> >>> On 1/22/14 5:43 PM, "Kelven Yang" <kelven.y...@citrix.com> wrote: >>> >>>> Master VMware was broken by this commit >>>> >>>> author Hugo >>>> >>>>Trippaers<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=se >>>>a >>>>rc >>>> >>>>h;h=b20add810e5751f53946f695b6223a8016f104a5;s=Hugo+Trippaers;st=author >>>>> >>>> >>>><htrippa...@schubergphilis.com><https://git-wip-us.apache.org/repos/asf >>>>? >>>>p= >>>> >>>>cloudstack.git;a=search;h=b20add810e5751f53946f695b6223a8016f104a5;s=ht >>>>r >>>>ip >>>> pa...@schubergphilis.com;st=author> >>>> Wed, 22 Jan 2014 08:34:46 +0000 (09:34 +0100) >>>> committer Hugo >>>> >>>>Trippaers<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=se >>>>a >>>>rc >>>> >>>>h;h=b20add810e5751f53946f695b6223a8016f104a5;s=Hugo+Trippaers;st=commit >>>>t >>>>er >>>>> >>>>> >>>>><htrippa...@schubergphilis.com><https://git-wip-us.apache.org/repos/as >>>>>f >>>>>?p >>>>> >>>>>=cloudstack.git;a=search;h=b20add810e5751f53946f695b6223a8016f104a5;s= >>>>>h >>>>>tr >>>>> ippa...@schubergphilis.com;st=committer> >>>> Wed, 22 Jan 2014 08:37:34 +0000 (09:37 +0100) >>>> commit b20add810e5751f53946f695b6223a8016f104a5 >>>> tree >>>> >>>>89e7e66704b09959bc5d77e4e20562e6dcc05306<https://git-wip-us.apache.org/ >>>>r >>>>ep >>>> >>>>os/asf?p=cloudstack.git;a=tree;h=89e7e66704b09959bc5d77e4e20562e6dcc053 >>>>0 >>>>6; >>>> hb=b20add810e5751f53946f695b6223a8016f104a5> >>>> >>>>tree<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=tree;h= >>>>8 >>>>9e >>>> >>>>7e66704b09959bc5d77e4e20562e6dcc05306;hb=b20add810e5751f53946f695b6223a >>>>8 >>>>01 >>>> 6f104a5> | >>>> >>>>snapshot<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=sna >>>>p >>>>sh >>>> ot;h=b20add810e5751f53946f695b6223a8016f104a5;sf=tgz> >>>> parent >>>> >>>>86124138a1a9129dedaf0f73fcd570156bfe53f6<https://git-wip-us.apache.org/ >>>>r >>>>ep >>>> >>>>os/asf?p=cloudstack.git;a=commit;h=86124138a1a9129dedaf0f73fcd570156bfe >>>>5 >>>>3f >>>> 6> >>>> >>>>commit<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=commi >>>>t >>>>;h >>>> =86124138a1a9129dedaf0f73fcd570156bfe53f6> | >>>> >>>>diff<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=commitd >>>>i >>>>ff >>>> >>>>;h=b20add810e5751f53946f695b6223a8016f104a5;hp=86124138a1a9129dedaf0f73 >>>>f >>>>cd >>>> 570156bfe53f6> >>>> Get rid of compiler warnings in vmware-base >>>> >>>> Min and I spent two hours on this to trace down the cause, Hugo, >>>>please >>>> do test before check-in even if it seems like to remove compiler >>>>warning, >>>> but because of the tricky business with Java generics, it does cause >>>> problem at runtime >>>> >>>> One of the problem comes from following code, please checkout my >>>>comments >>>> below. >>>> >>>> -Kelven >>>> >>>> >>>> import org.apache.log4j.Logger; >>>> >>>> @@ >>>> >>>>-144,6<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=blob; >>>>f >>>>=v >>>> >>>>mware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java;h=3c2 >>>>c >>>>81 >>>> >>>>d8a5ea3e242a6407ab5a0d2710fa1d0b73;hb=3c2c81d8a5ea3e242a6407ab5a0d2710f >>>>a >>>>1d >>>> 0b73#l144> >>>> >>>>+144,7<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=blob; >>>>f >>>>=v >>>> >>>>mware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java;h=e81 >>>>6 >>>>65 >>>> >>>>f71b76a3772b13dae5cc0733d26220c64a;hb=e81665f71b76a3772b13dae5cc0733d26 >>>>2 >>>>20 >>>> c64a#l144> @@ public class VmwareClient { >>>> ServiceContent serviceContent = >>>> vimPort.retrieveServiceContent(svcInstRef); >>>> >>>> // Extract a cookie. See vmware sample program >>>> com.vmware.httpfileaccess.GetVMFiles >>>> + @SuppressWarnings("unchecked") >>>> Map<String, List<String>> headers = (Map<String, >>>> >>>>List<String>>)((BindingProvider)vimPort).getResponseContext().get(Messa >>>>g >>>>eC >>>> ontext.HTTP_RESPONSE_HEADERS); >>>> List<String> cookies = headers.get("Set-cookie"); >>>> String cookieValue = cookies.get(0); >>>> @@ >>>> >>>>-256,17<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=blob >>>>; >>>>f= >>>> >>>>vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java;h=3c >>>>2 >>>>c8 >>>> >>>>1d8a5ea3e242a6407ab5a0d2710fa1d0b73;hb=3c2c81d8a5ea3e242a6407ab5a0d2710 >>>>f >>>>a1 >>>> d0b73#l256> >>>> >>>>+257,18<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=blob >>>>; >>>>f= >>>> >>>>vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java;h=e8 >>>>1 >>>>66 >>>> >>>>5f71b76a3772b13dae5cc0733d26220c64a;hb=e81665f71b76a3772b13dae5cc0733d2 >>>>6 >>>>22 >>>> 0c64a#l257> @@ public class VmwareClient { >>>> * @throws Exception >>>> * in case of error. >>>> */ >>>> - public Object getDynamicProperty(ManagedObjectReference mor, >>>>String >>>> propertyName) throws Exception { >>>> + @SuppressWarnings("unchecked") >>>> + public <T> T getDynamicProperty(ManagedObjectReference mor, >>>>String >>>> propertyName) throws Exception { >>>> List<String> props = new ArrayList<String>(); >>>> props.add(propertyName); >>>> List<ObjectContent> objContent = retrieveMoRefProperties(mor, >>>> props); >>>> >>>> >>>> >>>> - Object propertyValue = null; >>>> + T propertyValue = null; >>>> >>>> [Kelven] This is a wrong change, since propertyValue is intermediate >>>> variable that could have type that is different than the returning >>>>type. >>>> It will eventually cause getDeclaredMethod() call to fail at runtime >>>> >>>> >>>> if (objContent != null && objContent.size() > 0) { >>>> List<DynamicProperty> dynamicProperty = >>>> objContent.get(0).getPropSet(); >>>> if (dynamicProperty != null && dynamicProperty.size() > 0) >>>>{ >>>> DynamicProperty dp = dynamicProperty.get(0); >>>> - propertyValue = dp.getVal(); >>>> + propertyValue = (T)dp.getVal(); >>>> /* >>>> * If object is ArrayOfXXX object, then get the XXX[] >>>>by >>>> * invoking getXXX() on the object. >>>> @@ >>>> >>>>-274,13<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=blob >>>>; >>>>f= >>>> >>>>vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java;h=3c >>>>2 >>>>c8 >>>> >>>>1d8a5ea3e242a6407ab5a0d2710fa1d0b73;hb=3c2c81d8a5ea3e242a6407ab5a0d2710 >>>>f >>>>a1 >>>> d0b73#l274> >>>> >>>>+276,13<https://git-wip-us.apache.org/repos/asf?p=cloudstack.git;a=blob >>>>; >>>>f= >>>> >>>>vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java;h=e8 >>>>1 >>>>66 >>>> >>>>5f71b76a3772b13dae5cc0733d26220c64a;hb=e81665f71b76a3772b13dae5cc0733d2 >>>>6 >>>>22 >>>> 0c64a#l276> @@ public class VmwareClient { >>>> * >>>> ArrayOfManagedObjectReference.getManagedObjectReference() >>>> * returns ManagedObjectReference[] array. >>>> */ >>>> - Class dpCls = propertyValue.getClass(); >>>> + Class<? extends Object> dpCls = >>>>propertyValue.getClass(); >>>> String dynamicPropertyName = dpCls.getName(); >>>> if (dynamicPropertyName.indexOf("ArrayOf") != -1) { >>>> String methodName = "get" + >>>> dynamicPropertyName.substring(dynamicPropertyName.indexOf("ArrayOf") + >>>> "ArrayOf".length(), dynamicPropertyName.length()); >>>> >>>> - Method getMorMethod = >>>> dpCls.getDeclaredMethod(methodName, null); >>>> - propertyValue = >>>>getMorMethod.invoke(propertyValue, >>>> (Object[])null); >>>> + Method getMorMethod = >>>> dpCls.getDeclaredMethod(methodName, (Class<?>)null); >>>> + propertyValue = >>>> (T)getMorMethod.invoke(propertyValue, (Object[])null); >>>> } >>>> } >>>> } >>> >> >