Recursion to map phone number to strings
Here are some comments from my side:


The end parameter is unnecessary. You can just test for start &gt;= letters.length instead. Also, you might want to rename start.
It might make sense to wrap your algorithm in a callable method such as private void printSequences(String[] letters), which just kicks off the recursion by calling printSequences(letters, 0, "").
As to your bug, it depends on how exactly you are calling the method above (what is start and end).
Your test for letters[start] == null does not seems necessary if the letters array is well-behaved (i.e., does not contain null).
Recursion is a decent way to solve this problem.
Your bug comes from the fact that when you process "-" as a digit, you generate null in letters. When processing letters, you don't call your function recursively but just return. That way, nothing is ever printed, which explains the behavior you describe. The proper way to handle that case would be to call the method recursively without appending anything to the prefix (or to make sure there are no null entries in letters, which I believe is the better way, see point 7).
I would use a List&lt;String&gt; for letters. That way you don't end up with null entries.
Your IllegalArgumentException should describe the problem. For instance, it could say "Got illegal phoneNumber".
Your digits map should map characters to strings, not strings to strings. That way you don't have to coerce the character into string with phoneNumber.charAt(i) + "".