Merge Sort Error when Merging Sub-Arrays Back Together

I get an ArrayIndexOutOfBounds error on line 157 because the index j is 10 when the largest index is 9. Any ideas what I need to change to keep merge sort working while fixing this error? This code is from my virtual school class but doesn’t seem to work.

package assignment;
import flvs.Movie;
import java.util.concurrent.ThreadLocalRandom;

public class MovieClient3
{
static void traverseMovies(Movie[] movies)
{
    for(flvs.Movie m : movies)
    {
        System.out.printf("Title: %s, Year: %d, Studio: %s%n", m.getTitle(), m.getYear(), m.getStudio());
    }
}

public static void main(String[] args)
{
    Movie[] movies = new Movie[]
    {
        new Movie("ABC", 2005, "Studio 03"),
        new Movie("DEF", 2006, "Studio 02"),
        new Movie("GHI", 2001, "Studio 01"),
        new Movie("JKL", 2003, "Studio 04"),
        new Movie("MNO", 2002, "Studio 05"),
        new Movie("PQR", 2007, "Studio 06"),
        new Movie("ST", 2010, "Studio 07"),
        new Movie("UV", 2009, "Studio 08"),
        new Movie("WX", 2008, "Studio 10"),
        new Movie("YZ", 2007, "Studio 09")
    };

    jumbleArray(movies);
    System.out.println("Jumbling array...");
    Movie[] jumbled = movies.clone();
    System.out.println("Jumbled array:");
    traverseMovies(movies);

    MergeSortByTitle(movies, 0, movies.length);
    System.out.println();
    System.out.println("Sorted array using title:");
    traverseMovies(movies);
    /*
    System.out.println();
    System.out.println("Jumbling array again...");
    movies = jumbled;

    mergeSortByTitle(movies, 2);
    System.out.println();
    System.out.println("Sorted array using title (inverted):");
    traverseMovies(movies);

    System.out.println();
    System.out.println("Jumbling array again...");
    movies = jumbled;

    mergeSortByYear(movies, 1);
    System.out.println();
    System.out.println("Sorted array using year:");
    traverseMovies(movies);

    System.out.println();
    System.out.println("Jumbling array again...");
    movies = jumbled;

    mergeSortByYear(movies, 2);
    System.out.println();
    System.out.println("Sorted array using year (inverted):");
    traverseMovies(movies);

    System.out.println();
    System.out.println("Jumbling array again...");
    movies = jumbled;

    mergeSortByStudio(movies, 1);
    System.out.println();
    System.out.println("Sorted array using studio:");
    traverseMovies(movies);

    System.out.println();
    System.out.println("Jumbling array again...");
    movies = jumbled;

    mergeSortByStudio(movies, 2);
    System.out.println();
    System.out.println("Sorted array using studio (inverted):");
    traverseMovies(movies);*/

}

static void jumbleArray(Object[] array)
{
    int index;
    Object temp;
    ThreadLocalRandom random = ThreadLocalRandom.current();
    for (int i = 0; i < array.length - 1; i++)
    {
        index = random.nextInt(i + 1);
        temp = array[index];
        array[index] = array[i];
        array[i] = temp;
    }
}

static boolean compare(Movie a, Movie b, String mode)
{
    if(mode.equals("title"))
        return a.getTitle().compareTo(b.getTitle()) >= 0;
    else
        return true;
}

static void MergeSortByTitle(Movie[] array, int left, int right)
{
    if(left == right) return;

    int mid = (left + right)/2;

    MergeSortByTitle(array, left, mid); 
    MergeSortByTitle(array, mid + 1, right);

    merge(array, left, mid, right, "title");
}

//  Left run is A[iLeft :iRight-1].
// Right run is A[iRight:iEnd-1  ].
static void merge(Movie[] array, int left, int mid, int right, String mode)
{
    Movie[] temp = new Movie[right - left + 1];

    int i = left;
    int j = mid + 1;
    int n = 0;

    while(i <= mid || j <= right) // put elements (sorted) into temp
    {
        System.out.println("i: " + i + "    j: " + j + "    left: " + left + "   right: " + right);
        if(i > mid) //we have emptied the left half, insert the right half
        { 
            temp[n] = array[j]; 
            j++;
        }
        else if(j > right) //we have emptied the right half, insert the left half
        {
            temp[n] = array[i]; 
            i++;
        }
        else if(compare(array[i], array[j], "title"))
        {
            // both sections have values so we compare and see if
            // smallest is in i position − if so, pull from there
            temp[n] = array[i]; 
            i++;
        }
        else
        {
            // smallest is in j position − pull from there
            temp[n] = array[j]; 
            j++;
            } 
            n++;
        }
        // put elements back into a in a[left] to a[right] 
        for(int k = left; k <= right; k++) 
            array[k] = temp[k - left];
}

static void mergeSortByYear(Movie[] array, int left, int right)
{

}

static void mergeSortByStudio(Movie[] array, int left, int right)
{

}

}

dummy text at the bottom because stackoverflow makes me add superfluous text that doesnt need to be here filler filler