Method Ordering from Class.getMethods

Skip to end of metadata
Go to start of metadata

Several GlassFish bugs have been discovered when running with Java SE 7 due to a change in the return value of the Class.getMethods and Class.getDeclaredMethods calls. This page discusses the change in the Java SE implementation, examples of GlassFish bugs that have already been found and why the bugs only showed up with Java SE 7, and examples of how to fix this issue.

Background

The Class.getMethods javadoc (and Class.getDeclaredMethods) from Java SE 6 says:

The elements in the array returned are not sorted and are not in any particular order.

Despite this statement, up through Java SE 6 and up until build 128 of Java SE 7, the methods were returned in a consistent order from run to run of the JVM and within a single run.  However, starting with build 129 of Java SE 7, according to bug 7023180, there was a change in the implementation of the JVM that causes the order of the methods in the return value to vary, both from run to run and within a single run of the JVM. So for example, given the following class:

One call to A.class.getMethods() might return [ getX, getY ] while another call might return [ getY, getX ]. The actual order depends on class loading, the JVM symbol table, and various other factors within the JVM.

GlassFish Example Issue

Several JIRA bugs (18133, 18184, 18368) have been filed against GlassFish where the root cause is due to this change. In each of these cases, there is a loop over the return value of Class.getMethods, and the logic within the loop is looking for a method with particular characteristics. However, the logic was not precise enough about the method being sought, and with earlier JVM releases, the code happened to find the method it was looking for first.  With newer Java SE 7 releases, a different (wrong) method is found.  For example, consider bug 18133.  Here, the loop looks like this:

.The class referenced by parentType has the following two methods:

The string methodName in this case is "getNode".  Depending on the order of the array returned by getMethods, this loop may find either of the methods.  Later in the method, targetMethod.invoke is called, expecting to pass in no arguments.  If the second method is found by the loop, the invoke call throws an exception.

The fix for the bug depends on the what the loop is actually searching for. In this case, the method not only has to have the given name, but it must also be annotated with an annotation that extends the InhabitantAnnotation. So to correct this code, the if statement in the loop has to be changed to check not only for the name of the method, but for the desired annotation.

With the other bugs, the check that is made on the method is more complex, and in each case, the fix was to add a more specific check on the method, either looking for the number of parameters that the method accepts or the methods return type.

Usage in GlassFish

Using Netbeans we've attempted to search the GlassFish trunk for all uses of Class.getMethods(), Class.getDeclaredMethods(). Those results are summarized on the following wiki page:

GetMethods Usage in Source

Tasks have been created to track code inspection of the files in the above list. You can see those tasks here:

Jira tasks for get*Methods() code inspection

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Sign up or Log in to add a comment or watch this page.


The individuals who post here are part of the extended Oracle community and they might not be employed or in any way formally affiliated with Oracle. The opinions expressed here are their own, are not necessarily reviewed in advance by anyone but the individual authors, and neither Oracle nor any other party necessarily agrees with them.