0

I have an ArrayList containing Movie objects which I produced from a List containing File objects using this method:

// returns a list containing movie objects with correct names
private static ArrayList<Movie> createMovieObjs(Collection<File> videoFiles) {
    ArrayList<Movie> movieArrayList = new ArrayList<>();
    Matcher matcher;

    for (File file : videoFiles) {
        matcher = Movie.NAME_PATTERN.matcher(file.getName());
        while (matcher.find()) {
            String movieName = matcher.group(1).replaceAll("\\.", " ");
            Movie movie = new Movie(movieName);

            if (!movieArrayList.contains(movie)) {
                movieArrayList.add(movie);
            }
        }
    }
    return movieArrayList;

}

Everything works fine in above code, getting correct ArrayList.

Then I want to parse info for each Movie object in this ArrayList and set that info to that Movie object:

     // want to parse genre, release year and imdbrating for every Movie object
    for (Movie movie : movieArrayList) {
        try {
            movie.imdbParser();
        } catch (IOException e) {
            System.out.println("Parsing failed: " + e);
        }
    }

Here is Movie.imdbParser which uses Movie.createXmlLink (createXmlLink works fine on its own, so thas imdbParser - tested both):

private String createXmlLink() {
    StringBuilder sb = new StringBuilder(XML_PART_ONE);
    // need to replace spaces in movie names to "+" - api works that way
    String namePassedToXml = this.title.replaceAll(" ", "+");
    sb.append(namePassedToXml);
    sb.append(XML_PART_TWO);
    return sb.toString();
}

// parses IMDB page and sets releaseDate, genre and imdbRating in Movie objects
public void imdbParser() throws IOException {
    String xmlLink = createXmlLink();

    // using "new Url..." because my xml is on the web, not on my disk
    Document doc = Jsoup.parse(new URL(xmlLink).openStream(), "UTF-8", "", Parser.xmlParser());
    Element movieFromXml = doc.select("movie").first();

    // using array to extract only last genre name - usually the most substantive one
    String[] genreArray = movieFromXml.attr("genre").split(", ");
    this.genre = genreArray[genreArray.length - 1];

    this.imdbRating = Float.parseFloat(movieFromXml.attr("imdbRating"));

    // using array to extract only year of release
    String[] dateArray = movieFromXml.attr("released").split(" ");
    this.releaseYear = Integer.parseInt(dateArray[2]);

}

Problems seems to be with accessing Movie objects, it doesn't create good XMLLink so when it tries to access genre in XML it throws NPE. My error:

Exception in thread "main" java.lang.NullPointerException
at com.michal.Movie.imdbParser(Movie.java:79)
at com.michal.Main.main(Main.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Movie.java:79 is:

String[] genreArray = movieFromXml.attr("genre").split(", ");

and Main.java:52 is:

             movie.imdbParser();
doublemc
  • 3,021
  • 5
  • 34
  • 61
  • 2
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Mistalis Jan 18 '17 at 10:10
  • It's not, I know what NPE is, just can't find a way to fix my particular problem. – doublemc Jan 18 '17 at 10:11
  • inspect the downloaded xml, maybe the movie element does not have a genre attribute – nandsito Jan 18 '17 at 10:16
  • 1
    `movieFromXml.attr("genre")` possibly returns `null`, you should check it. That perhaps happens when there is no attribute "genre". – MC Emperor Jan 18 '17 at 10:16

2 Answers2

2

When you make a chain of calling method like this: movieFromXml.attr("genre").split(", "), you have to make sure that each of the preceding element is not null. In this case, you have to make sure that movieFromXml is not null and movieFromXml.attr("genre") is not null.

Duy Nguyen
  • 531
  • 2
  • 5
2

A lot of errors such as this are caused by the data not being as you expect. Often when dealing with a lot of data then sometimes it can be just a single record that does not "conform"!

You say that this line is causing you problems;

String[] genreArray = movieFromXml.attr("genre").split(", ");

So split the line down and debug your application to find the issue. If you can't debug then export the results to a log file.

  1. Check that movieFromXml is not NULL.
  2. Check that movieFromXml contains a "genre" attribute as you expect
  3. Check that the data in the attribute can be split as you expect, and produces a valid output.

Often, it is good to view the data being retrieved prior to this call. I often find it useful to dump the data out to file and then load it in an external viewer to check that it is how I expect.

jason.kaisersmith
  • 8,712
  • 3
  • 29
  • 51