I've been updating an existing library to throw exceptions to help improve debugging by people using the library.
At first, I thought I'd define exceptions specific to each class, however it turns out most of those exceptions are simply extensions of existing runtime exceptions (e.g., FooNegativeIntArgumentException extends IllegalArgumentException, FooNullBarException extends NullPointerException) with specific messages.
What are the trade-offs of defining new exceptions vs. using existing ones? Are there any conventions/best-practices?
Also, given the need for backwards compatibility, most (if not all) of these exceptions are runtime exceptions.