Matthew Drozdz Matthew Drozdz - 1 month ago 7
Java Question

TomCat - Constructor threw exception when trying to read from File

I have some methods below and basically my issue is when I try to read from a .txt file. The application works fine in memory. When I add the decode() to the overloaded constructor I get the following error in Tomcat Server logs:
Constructor threw exception; nested exception is java.lang.NumberFormatException: For input string: ""

When I look more at this it points to this line in the decode method
currentDVD.setDvdId(Integer.parseInt((currentTokens[0]))); but I can't seem to figure out what the issue is. At one point I was able to read from the file and then I was trying to get the encode method to work and something happened at some point. Any help would be appreciated.

public class DvdLibraryInFileImpl implements DvdLibraryDao {

private Map<Integer, DVD> dvdMap = new HashMap<>();
public static final String DVD_FILE = "dvd.txt";
public static final String DELIMITER = "::";
private static int dvdIdCounter = 0;

public DvdLibraryInFileImpl() throws FileNotFoundException {
decode();

}


@Override
public DVD addDVD(DVD dvd) {

dvd.setDvdId(dvdIdCounter);

dvdIdCounter++;

dvdMap.put(dvd.getDvdId(), dvd);

return dvd;
}

@Override
public DVD getDVDById(int dvdId) {
return dvdMap.get(dvdId);
}

@Override
public List<DVD> getAllDVDSByName(String searchByName) {
throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public List<DVD> getAllDVDS() {
List<DVD> allDVDS = new ArrayList<>(dvdMap.values());
return allDVDS;
}

@Override
public void updateDVD(DVD dvd) {
dvdMap.put(dvd.getDvdId(), dvd);
}

@Override
public void removeDVD(int dvdId) {
dvdMap.remove(dvdId);
}


@Override
public void decode() throws FileNotFoundException {
Scanner sc = new Scanner(new BufferedReader(new FileReader(DVD_FILE)));
String[] currentTokens;
while (sc.hasNextLine()) {
String currentLine = sc.nextLine();
currentTokens = currentLine.split(DELIMITER);

DVD currentDVD = new DVD();

currentDVD.setDvdId(Integer.parseInt((currentTokens[0])));
currentDVD.setTitle(currentTokens[1]);
currentDVD.setReleaseDate(currentTokens[2]);
currentDVD.setMpaaRating(currentTokens[3]);
currentDVD.setDirectorsName(currentTokens[4]);
currentDVD.setStudio(currentTokens[5]);
currentDVD.setUserRating(currentTokens[6]);

dvdMap.put(Integer.parseInt((currentTokens[0])), currentDVD);
}

}


@Override
public void encode() throws IOException {
PrintWriter out = new PrintWriter(new FileWriter(DVD_FILE));
Set<Integer> keySet = dvdMap.keySet();
for (Integer i : keySet) {

out.print((dvdMap.get(i)).getDvdId());
out.print(DELIMITER);

out.print((dvdMap.get(i)).getTitle());
out.print(DELIMITER);

out.print((dvdMap.get(i)).getReleaseDate());
out.print(DELIMITER);

out.print((dvdMap.get(i)).getMpaaRating());
out.print(DELIMITER);

out.print((dvdMap.get(i)).getDirectorsName());
out.print(DELIMITER);

out.print((dvdMap.get(i)).getStudio());
out.print(DELIMITER);

out.print((dvdMap.get(i)).getUserRating());
out.println("");

}
out.flush();
out.close();
}
}

Answer

The problem is because currentLine does NOT have the proper input data received (from user entry).

You should ensure that currentTokens is having proper DvdId set (should be numeric value), otherwise Integer.parseInt((currentTokens[0])) line will throw NumberFormatException for non-numeric or empty ("") data.

You need to ensure that the input data entered is correct with numeric dvdid.

For example, enter below data: 1234::DVDTITLE::29-OCT-2016::RATING1::DIRECTOR::STUDIO::RATING2

I strongly recommend you to add the input validations to handle the scenarios like entering the non-numeric values or rating higher that max value or director name containg numeric values, etc....