This seems to work nicely:
Random random = new Random();
public int[] fourRandoms(int limit) {
    int[] randoms = new int[4];
    int[] three = new int[3];
    for (int i = 0; i < 3; i++) {
        three[i] = random.nextInt(limit);
    }
    int min = Math.min(three[0], Math.min(three[1], three[2]));
    int max = Math.max(three[0], Math.max(three[1], three[2]));
    int mid = three[0] + three[1] + three[2] - max - min;
    randoms[0] = min - 0;
    randoms[1] = mid - min;
    randoms[2] = max - mid;
    randoms[3] = limit - max;
    return randoms;
}
public void test() {
    for (int i = 1; i < 10; i++) {
        int[] randoms = fourRandoms(100);
        int sum = Arrays.stream(randoms).sum();
        System.out.println(Arrays.toString(randoms) + " = " + sum);
    }
}
It's an implementation of @SpaceTrucker's idea.
Alternatively - using Java 8 Streams.
public int[] nRandomsThatSumToLimit(int n, int limit) {
    return IntStream
            .concat(
                    // Stream n-1 random ints and sort them.
                    random.ints(n - 1, 0, limit).sorted(),
                    // Plus the final limit value.
                    IntStream.of(limit))
            // Convert into a stream of differences.
            .map(new IntUnaryOperator() {
                // Maintain the previous.
                int p = 0;
                @Override
                public int applyAsInt(int n) {
                    // Difference.
                    int d = n - p;
                    // Persist.
                    p = n;
                    return d;
                }
            }).toArray();
}