Expanding on McDowell's proposal to process the binary classes, I wrote some code that I've used with success for a relatively large codebase, and I'd like to share: https://bitbucket.org/Oddwarg/java-sigfpe-emulator/
I used Krakatau to disassemble and reassemble class files. A small Java class containing the public, static helper methods float notZero(float f) and double notZero(double f) must be added to the application as a part of the process.
The modification to the bytecode assembly is, in principle, very simple: When an fdiv or ddiv instruction is encountered, a call to the appropriate notZero function is inserted first.
L28: fload_0
L29: fload_1
invokestatic Method owg/sigfpe/SIGFPE notZero (F)F
L30: fdiv
L31: fstore_2
In this example, the line between L29 and L30 was inserted by the program.
The notZero call consumes the top of the operand stack as its argument, which is the divisor. If the divisor is not zero, then it is returned, putting it back on top of the operand stack. If the divisor is zero, then an ArithmeticException is thrown instead.
Calling a method and making sure the operand stack remains the same avoids most of the problems related to Stack Map Frames and operand stack overflow, but I did have to ensure the distance between .stack same-type frames remains below a threshold. They are repeated on demand.
I hope this will be useful to someone. I've spent more than enough time manually searching for floating point divisions by zero myself.