This question is not looking for a solution to a problem but an explanation of why a problem may have arisen (or not!).
The Javadocs for Class.getMethods()
say:
The elements in the array returned are not sorted and are not in any particular order.
The thing is, this: we’ve been using a neat little Java templating library called JMTE for maybe a couple of years now, with no problems. This uses JSTL-like syntax to inject model values into templates. In particular, we’ve been using something like this to render a price:
${vendor.currency.symbol} ${order.amount}
The first of these translates to the the following:
vendor.getCurrency().getSymbol()
where getCurrency()
returns a java.util.Currency object. Currency has two methods for getting the currency symbol - one that takes a specific Locale and one that uses the default.
public String getSymbol(Locale locale)
For the last 18 months or so, everything has been running fine, with currency codes/symbols appearing in emails. Then 5 days ago, we started getting a random IllegalArgumentException
thrown when trying to substitute ${vendor.currency.symbol}
After a bit of debugging I found the cause, deep inside JMTE:
for (Method method : declaredMethods) {
if (Modifier.isPublic(method.getModifiers())
&& (method.getName().equals("get" + suffix) ||
method.getName().equals("is" + suffix))) {
value = method.invoke(o, (Object[]) null);
....
}
}
i.e., Whether getSymbol()
or getSymbol(Locale)
was called is completely at the mercy of the return order of Class.getMethods()
(not in any particular order). I added a test to ensure the method has 0 parameters and my problem was solved.
Now, by a strange coincidence, someone else happened to submit an identical fix on the very same day that we first observed this behaviour.
What’s puzzling is that this code has been running for 18 months with no problems, then all of a sudden, this behaviour appears.
When I created a test case it failed roughly 50% of the time, as one would expect (there are 2 matching methods, returned in no particular order), so I'm puzzled (amazed) it worked for 18 months and 10^5 executions. (It's conceivable, but unlikely, that it has failed but succeeded on subsequent retries).
Purely out of curiosity, I’m wondering if there’s anything in the Java runtime that might cause this latent behaviour to suddenly appear. It’s even more puzzling that a fix for this behaviour should be provided by someone else on the same day for a project that is mature and stable - suggesting perhaps that the same latent behaviour suddenly realised itself elsewhere.
So, the question is: does anyone know what factors might influence the order of the methods returned by Class.getMethods()
?
Aucun commentaire:
Enregistrer un commentaire