Falta el caso base
public static int factorial(int n) {
return n * factorial(n - 1);
}
Nunca para. Baja a 0, a -1, a -2... hasta que la pila se llena y la JVM lanza StackOverflowError.
public static int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}