Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Finding Methods Calls Programmatically

DZone's Guide to

Finding Methods Calls Programmatically

· Java Zone
Free Resource

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

In the current project a defect was raised with the following exception attached:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

After I dug into the code, I found the cause was simple. There was no rounding mode given for calculations that might produce big decimals, like in this example:

BigDecimal.ONE.divide(BigDecimal.valueOf(3));

Every senior developer knows about this trap, but it’s still easy to forget. A default of BigDecimal.ROUND_HALF_UP, applied when no rounding mode is defined explicitly, would have made the method more safe to use.

How is it possible to prevent such failures in the future and avoid dividing a single big decimal parameter ad infinitum? One could use Checkstyle rules, use FindBugs rules or create a simple unit test.

I chose the unit test, so the question became “How can I find all the methods that call a given method in Java?” This is not possible with the standard Reflection API, but I had already used OW2′s ASM for such tasks, so it wasn’t too hard to create a JUnit assertion for it.

Just include this in your unit tests:

// Path to your project's '*.class' files
final File classesDir = new File("target/classes");
// Can be used to exclude some files/packages
final FileFilter fileFilter = new FileFilter() {
@Override
public boolean accept(File file) {
return !file.getPath().contains("my/pkg/to/exclude");
}
};
// Define methods to find
final MCAMethod divide = new MCAMethod("java.math.BigDecimal",
"java.math.BigDecimal divide(java.math.BigDecimal)");
final MCAMethod setScale = new MCAMethod("java.math.BigDecimal",
"java.math.BigDecimal setScale(int)");
// Fails if any class calls one of the two methods
AssertUsage.assertMethodsNotUsed(classesDir, fileFilter,
divide, setScale);

The full source code can be found at GitHub.

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Published at DZone with permission of Michael Schnell, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}