Java with MySQL, JDBC, and CachedRowSet: Having trouble with an “Invalid cursor position” error

I’m going through an old tutorial made by a previous instructor I had for a class. The tutorial is about how to create a MySQL database and connect to it through JDBC. It also uses a GUI for displaying the data. The tutorial shows how to insert data into the database using text fields and a button. I’m now trying to delete the data using a Delete button. The database is a simple database containing course information. Here are the details:

+---------------+--------------+------+-----+---------+-------+
| Field         | Type         | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| course_name   | varchar(100) | YES  |     | NULL    |       |
| course_number | varchar(50)  | NO   | PRI | NULL    |       |
| enrollment    | int(2)       | YES  |     | NULL    |       |
| start_date    | varchar(10)  | YES  |     | NULL    |       |
| end_date      | varchar(10)  | YES  |     | NULL    |       |
+---------------+--------------+------+-----+---------+-------+

My problem is the data will be deleted from the database, and the row will disappear from the GUI, but a new row will form at the bottom of the table where each column says java.sql.SQLException: Invalid cursor position. This program uses a model, view and controller. My deleteRow() method is on line 150 in CourseListTableModel.java. The CourseListTableController implements ListSelectionListener and RowSetListener, so you can find their implemented methods in CourseListTableController.java.

The Model CourseListTableModel.java:

package courselisttablemodel;
import javax.swing.table.*;
import javax.swing.event.*;
import java.sql.*;
import javax.sql.*;
import javax.sql.rowset.*;
import com.sun.rowset.CachedRowSetImpl;
/**
 * Model for the courselist table. Contains database-specific code to read the
 * data from the database into the table model.
 */

// java.sql.SQLException: Invalid cursor position

public class CourseListTableModel extends AbstractTableModel {

    CachedRowSet courseListRowSet; // Contains data
    ResultSetMetaData metadata; // Additional info about the data
    Connection connection;
    Statement statement;
    int numcols, numrows; // Number of rows and columns

    public CourseListTableModel() {
        // Change this code to use a separate class for connecting and reading
        // from the database
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
        } catch (Exception e) {
            System.err.println("Unable to find and load driver");
            System.exit(1);
        }

        try {

            connection = DriverManager.getConnection("jdbc:mysql://localhost/test1",
                    "root", "password");
        } catch (SQLException sqlerr) {
            System.out.println(sqlerr.getMessage());
            System.out.println(sqlerr.getSQLState());
            System.out.println(sqlerr.getErrorCode());
        }

        System.out.println("Connected Successfully");

        try {
            connection.setAutoCommit(false);
            courseListRowSet = new CachedRowSetImpl();
            courseListRowSet.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
            courseListRowSet.setConcurrency(ResultSet.CONCUR_UPDATABLE);
            courseListRowSet.setCommand("SELECT * FROM courselist");
            courseListRowSet.execute(connection);

            metadata = courseListRowSet.getMetaData();
            numcols = metadata.getColumnCount();
            numrows = courseListRowSet.size();
            courseListRowSet.first();
        } catch (SQLException exp) {
            exp.printStackTrace();
        }
    }

    public CourseListTableModel(RowSet rowSet, Connection conn) {
        try {
            courseListRowSet = (CachedRowSet) rowSet;
            courseListRowSet.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
            courseListRowSet.setConcurrency(ResultSet.CONCUR_UPDATABLE);
            metadata = courseListRowSet.getMetaData();
            numcols = metadata.getColumnCount();
            numrows = courseListRowSet.size();
            connection = conn;
        } catch(SQLException exp) {
            exp.printStackTrace();
        }
    }

    // Gets the total number of rows
    public int getRowCount() {
        return numrows;
    }

    // Gets the total number of columns
    public int getColumnCount() {
        return numcols;
    }

    // Gets the value of an object at a given row and column
    public Object getValueAt(int row, int col) {
        try {
            courseListRowSet.absolute(row + 1);
            Object obj = courseListRowSet.getObject(col + 1);
            if (obj == null)
                return null;
            else
                return obj.toString();
        } catch (SQLException err) {
            return err.toString();
        }
    }

    // Returns false because cells are not editable
    public boolean isCellEditable(int row, int col) {
        return false;
    }

    // Returns the name of a column
    public String getColumnName(int col) {
        try {
            return metadata.getColumnLabel(col + 1);
        } catch (SQLException err) {
            return err.toString();
        }
    }

    // Sets the value of an object at a given row and column
    public void setValueAt(Object aValue, int row, int col) {
        try {
            courseListRowSet.moveToInsertRow();
            System.out.println(aValue + " setValueAt " + (row+1) + " " + (col+1));
            courseListRowSet.updateObject(col+1, (String) aValue);
        } catch (SQLException err) {
            err.getMessage();
            err.printStackTrace();
        }
    }

    // Adds a row to the database
    public void addRow(Object[] array) {
        try {
            courseListRowSet.last();
            courseListRowSet.moveToInsertRow();
            courseListRowSet.updateString("course_name", (String) array[0]);
            courseListRowSet.updateString("course_number", (String) array[1]);
            courseListRowSet.updateInt("enrollment", Integer.valueOf((String) array[2]).intValue());
            courseListRowSet.updateString("start_date", (String) array[3]);
            courseListRowSet.updateString("end_date", (String) array[4]);
            courseListRowSet.insertRow();
            courseListRowSet.moveToCurrentRow();
            courseListRowSet.acceptChanges(connection);
        } catch(SQLException err) {
            err.getMessage();
            err.printStackTrace();
        }
    }

    // NEED TO FINISH MAKING THIS
    // Deletes a row from the database
    // PROBLEM: The row will be deleted from the database, and the row in the GUI will disappear, but there will be a
    // new row at the bottom of the table where each field is "java.sql.SQLException: Invalid cursor position".
    public void deleteRow(Object[] array) {
        try {
            System.out.println("Executing deleteRow()");
            courseListRowSet.first();

            while (!courseListRowSet.getString("course_number").equals(array[1]))
                courseListRowSet.next();

            courseListRowSet.deleteRow();
            courseListRowSet.first();
            courseListRowSet.acceptChanges(connection);
        } catch(SQLException err) {
            err.getMessage();
            err.printStackTrace();
        }
    }

    // Right now I'm using this to show the position of the cursor
    public void updateRow(Object[] array) {
        try {

            System.out.println("Current row = " + courseListRowSet.getRow());

        } catch(SQLException err) {
            err.getMessage();
            err.printStackTrace();
        }
    }

    // Returns the current CachedRowSet in the TableModel
    public CachedRowSet getRowSet() {
        return courseListRowSet;
    }

    // Helps preserve the old connection for the new TableModel
    public Connection getConnection() {
        return connection;
    }

    public void getCursorPosition() {
        try {
            System.out.println("Row number = " + courseListRowSet.getRow());
        } catch(SQLException err) {
            err.getMessage();
            err.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // TODO code application logic here
        CourseListGUI2 courseListGUI2 = new CourseListGUI2();
        courseListGUI2.setVisible(true);
    }

}

The View: CourseListGUI2.java (I’ve left out some GUI code that’s probably not important)

// CourseListGUI2.java
// GUI for the program

package courselisttablemodel;

import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;


public class CourseListGUI2 extends javax.swing.JFrame {

    private JTable jtable1; // The table displayed on the GUI
    private CourseListTableController courseListTableController = null;

    public CourseListGUI2() {

        // This method creates the labels and textfields on the GUI
        initComponents();

        // Creates a controller for the table
        courseListTableController = new CourseListTableController(this);

        // Add a table JTable to the GUI
        addJTable();

        // Make primary key non-editable
        // courseNumberTextField.setEditable(false);
    }

    public void addJTable() {
        // Add the data and column names to a JTable
        jtable1 = new JTable(courseListTableController.getTableModel());

        // Add a ListSelectionListener to the table
        jtable1.getSelectionModel().addListSelectionListener(courseListTableController);

        // Add the table to a scrollpane
        JScrollPane scrollpane = new JScrollPane(jtable1);

        // Create a window
        // This was originally jPanel
        jPanel2.setLayout(new BorderLayout());
        jPanel2.add(scrollpane, BorderLayout.CENTER);

        // User can only select one row at a time
        jtable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    }

    // Update the JTable
    public void updateTable() {
        jtable1.setModel(courseListTableController.getTableModel());
    }

    // Set data on the courseNameTextField
    public void setCourseNameTextField(String name) {
        courseNameTextField.setText(name);
    }

    // Set data on the courseNumberTextField
    public void setCourseNumberTextField(String value) { courseNumberTextField.setText(value); }

    // Set data on the enrollmentTextField
    public void setEnrollmentTextField(String num) {
        enrollmentTextField.setText(num);
    }

    // Set data on the startDateTextField
    public void setStartDateTextField(String startDate) {
        startDateTextField.setText(startDate);
    }

    // Set data on the endDateTextField
    public void setEndDateTextField(String endDate) {
        endDateTextField.setText(endDate);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        // Details for the Add button
        addButton.setText("Add");
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        // Details for the Delete button
        deleteButton.setText("Delete");
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteButtonActionPerformed(evt);
            }
        });

        // Details for the Update button
        updateButton.setText("Update");
        updateButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateButtonActionPerformed(evt);
            }
        });

    }// </editor-fold>//GEN-END:initComponents

    // Code for the add button
    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        // TODO add your handling code here:
        String[] array = new String[jtable1.getColumnCount()];
        array[0] = courseNameTextField.getText();
        array[1] = courseNumberTextField.getText();
        array[2] = enrollmentTextField.getText();
        array[3] = startDateTextField.getText();
        array[4] = endDateTextField.getText();

        // Send data to the controller to add it to the model
        courseListTableController.addRow(array);

//        ( (DefaultTableModel) jtable1.getModel()).fireTableDataChanged();
    }//GEN-LAST:event_addButtonActionPerformed

    // Code for the delete button
    // NEED TO FINISH MAKING THIS. SEE addRow() METHODS IN
    // CourseListTableController.java (LINE 65) and CouseListTableModel.java (LINE 149)
    private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
        // TODO add your handling code here:
        String[] array = new String[jtable1.getColumnCount()];
        array[0] = courseNameTextField.getText();
        array[1] = courseNumberTextField.getText();
        array[2] = enrollmentTextField.getText();
        array[3] = startDateTextField.getText();
        array[4] = endDateTextField.getText();

        // Send data to the controller to remove it from the model
        courseListTableController.deleteRow(array);
    }//GEN-LAST:event_deleteButtonActionPerformed

    // Code for the update button
    private void updateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateButtonActionPerformed
        // TODO add your handling code here:
        String[] array = new String[jtable1.getColumnCount()];
        array[0] = courseNameTextField.getText();
        array[1] = courseNumberTextField.getText();
        array[2] = enrollmentTextField.getText();
        array[3] = startDateTextField.getText();
        array[4] = endDateTextField.getText();

        // Send data to the controller to update it in the model
        courseListTableController.updateRow(array);
    }//GEN-LAST:event_updateButtonActionPerformed    
}

The Controller CourseListTableController.java:

package courselisttablemodel;
import javax.sql.RowSetEvent;
import javax.sql.RowSetListener;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableModel;

/**
 * Glue between the view (CourseListGUI) and the model (CourseListTableModel).
 * No database specific code here. Contains a reference to both the TableModel
 * and the GUI.
 */

public class CourseListTableController implements ListSelectionListener, RowSetListener {

    private CourseListTableModel tableModel = null;
    private CourseListGUI2 gui;

    public CourseListTableController(CourseListGUI2 gui) {
        this.gui = gui;
        // Create the tableModel using the data in the cachedRowSet
        tableModel = new CourseListTableModel();
        tableModel.getRowSet().addRowSetListener(this);
    }

    // Get the table model
    public TableModel getTableModel() {
        return tableModel;
    }

    // Method from the ListSelectionListener Interface
    // Called whenever the value of the selection changes.
    public void valueChanged(ListSelectionEvent e) {
        // Prevent action from being performed twice
        // https://stackoverflow.com/questions/5865343/why-does-jtable-always-trigger-listselectionlistener-twice
        if (!e.getValueIsAdjusting()) {

            ListSelectionModel selectModel = (ListSelectionModel) e.getSource();

            int firstIndex = selectModel.getMinSelectionIndex();

            // Read the data in each column using getValue and display it on
            // corresponding textfield
            gui.setCourseNameTextField((String) tableModel.getValueAt(firstIndex, 0));
            gui.setCourseNumberTextField((String) tableModel.getValueAt(firstIndex, 1));
            gui.setEnrollmentTextField((String) tableModel.getValueAt(firstIndex, 2));
            gui.setStartDateTextField((String) tableModel.getValueAt(firstIndex, 3));
            gui.setEndDateTextField((String) tableModel.getValueAt(firstIndex, 4));
        }
    }

    // Add a row to the database using addRow() in CourseListTableModel
    public void addRow(String[] array) {
        tableModel.addRow(array);
    }

    // Delete a row to the database using deleteRow() in CourseListTableModel
    // NEED TO FINISH MAKING THIS. THERE IS A deleteRow() METHOD IN
    // CourseListTableModel.java ON LINE 149
    public void deleteRow(String[] array) { tableModel.deleteRow(array); }

    // Update a row to the database using updateRow() in CourseListTableModel
    public void updateRow(String[] array) {
        tableModel.updateRow(array);
    }

    // Method from the RowSetListener Interface
    // Notifies registered listeners that a RowSet object has had a change in one of its rows.
    // Have not changed this to handle deleting a row.
    public void rowChanged(RowSetEvent event) {
        try {

            // Get the index of the inserted row
            tableModel.getRowSet().moveToCurrentRow();

            // getRowSet() is a method in CourseListTableModel that returns a CachedRowSet object
            // getRow() is a method in ResultSet that returns the current row
            int firstIndex = tableModel.getRowSet().getRow();

            // Create a new table model with the new data
            tableModel = new CourseListTableModel(tableModel.getRowSet(), tableModel.getConnection());

            //update the JTable with the data
            gui.updateTable();

            // Read the data in each column using getValueAt and display it on
            // the corresponding textfield
            gui.setCourseNameTextField((String) tableModel.getValueAt(firstIndex, 0));
            gui.setCourseNumberTextField((String) tableModel.getValueAt(firstIndex, 1));
            gui.setEnrollmentTextField((String) tableModel.getValueAt(firstIndex, 2));
            gui.setStartDateTextField((String) tableModel.getValueAt(firstIndex, 3));
            gui.setEndDateTextField((String) tableModel.getValueAt(firstIndex, 4));
        } catch (Exception exp) {
            exp.getMessage();
            exp.printStackTrace();
        }
    }

    // Method from the RowSetListener Interface
    // Notifies registered listeners that a RowSet object's cursor has moved.
    // Have not changed this to handle deleting a row.
    public void cursorMoved(RowSetEvent event) { }

    // Method from the RowSetListener Interface
    // Notifies registered listeners that a RowSet object in the given RowSetEvent object has changed its entire contents.
    // Have not changed this to handle deleting a row.
    public void rowSetChanged(RowSetEvent event) { }

}

Does anyone have any idea about where the issue is coming from and how to fix it? I’m thinking it has something to do with deleteRow() in the model or maybe the rowChanged() or valueChanged() methods in the controller. I was thinking maybe I need to alter the code for rowChanged() to handle both inserting and deleting, but I’m unsure about how to go about doing that (if I’m even correct about it). Sorry for the long post, and thanks for reading.

Java Try-Catch Issue with Scanner

I have a code for handling error ArithmeticError in Java.. But there is a compilation error of ElementNotFound when I use the variables n and m in my code ..
Code:

import java.util.*;
class Abc {
    public static void main(String args[] ) throws Exception {
        Scanner sc = new Scanner(System.in);
        try{
            int n = sc.nextInt();
            int m = sc.nextInt();
            if(m < 0 || n < 0){
                throw new ArithmeticException();
            }
        }
        catch(ArithmeticException ex){
            System.out.println("Invalid!");
        }
        int i = 1,k=0;
        while( (i * i )  <= (m + n)){  // Error in this line
            if((i * i) == (m + n)){  // Error in this line also
                k = 1;  
                break;
            }
            i += 1;
         }
         if(k == 1){
             System.out.println(i);
         }
         else{
             System.out.println("-1");
         }
   }
}

On removing the try catch block, the code compiles and runs as intended..

Bounded wildcards for class and super class array

I have a class Shape and a class Circle that extends Shape as follows:

public class Shape {
  private double area;
  public Shape(double thatArea) {
      this.area = thatArea;
  }

  public double getArea() {
      return this.area;
  }
}

public class Circle extends Shape {
    private double radius;
    public Circle(double radius) {
        super(3.14*radius*radius);
    }

    public double getRadius() {
        return this.radius;
    }
}

Supposed that I create an array of shapes as follows

Shape[] shapes = new Shape[3];
shapes[0] = new Shape(100.0);
shapes[1] = new Circle(5.0);
shapes[2] = new Shape(35.0);

And have a filter by area method like this

public Shape[] filterByMaxArea(double maxArea) {
    ArrayList<Shape> shapeResult = new ArrayList<>();

    for (Shape s : shapes) {
        if (s.getArea < maxArea) shapeResult.add(s);
    }

    return (Shape[]) shapeResult.toArray();
}

If I call the filterByMaxArea() method like this

filterByMaxArea(1000); // in order to include the 
circle too

Then the compiler throws a ClassCastException

Exception in thread "main" java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to [Lmypackage.Shape;
at mypackage.Main.filterByMaxArea(Main.java:74)

Where line 74 in the code is this

return (Shape[]) shapeResult.toArray();

Can someone explain me why does the cast fail even though the Circle is a subtype of Shape and previously I had an array of Shape and Circle instances ?

P.S I have tried also declaringthe ArrayList with bounded wildcards like this
without any luck.

 ArrayList<? extends Shape> shapeResult = new ArrayList<>();

log4j2 version ‘2.10’ configuration pattern

Something strange is happening when i’m trying to use log4j2 version 2.10.

Every example including those ones from log4j2 documentation seems wrong.

Consider this example from: https://logging.apache.org/log4j/2.x/manual/configuration.html

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

Using the above example i got the following output:

log4j:WARN Continuable parsing error 2 and column 30
log4j:WARN Document root element "Configuration", must match DOCTYPE root "null".
log4j:WARN Continuable parsing error 2 and column 30
log4j:WARN Document is invalid: no grammar found.
log4j:ERROR DOM element is - not a <log4j:configuration> element.
log4j:WARN No appenders could be found for logger (utils.Xablau).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

And nothing is logged.

To solve this i have to use other pattern like this:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} [%-5p] [%t] %m%n" />
        </layout>
    </appender>

    <appender name="FILE" class="org.apache.log4j.FileAppender">
        <param name="file"
               value="C:/tmp/logs/functional-test.log" />
        <param name="immediateFlush" value="true" />
        <param name="threshold" value="debug" />
        <param name="append" value="true" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n" />
        </layout>
    </appender>

    <category name="se.jayway.ddsteps">
        <priority value="info"></priority>
    </category>

    <root>
        <priority value="INFO"></priority>
        <appender-ref ref="console" />
        <appender-ref ref="FILE" />
    </root>

</log4j:configuration>

That’s the only way it works and log stuff.

btw i’m using the following maven dependency imports:

<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.10.0</version>
            <type>test-jar</type>
            <scope>test</scope>
        </dependency>

Polling empty queue – JCIP listing 7.7

In this code

public class NoncancelableTask {
    public Task getNextTask(BlockingQueue<Task> queue) {
        boolean interrupted = false;
        try {
            while (true) {
                try {
                    return queue.take();
                } catch (InterruptedException e) {
                    interrupted = true;
                    // fall through and retry
                }
            }
        } finally {
            if (interrupted)
                Thread.currentThread().interrupt();
        }
    }

    interface Task {
    }
}

What if queue is already empty? Code will swallow first exception, then retry – and wait forever?
I thought main idea of interruption is cancellation of task if it stuck on some blocking method like Thread.sleep, BlockingQueue.take(), etc.

There is similar question What is the point of restoring the interrupted status in JCIP listing 7.7? , but I don’t have enough reputation to post a comment

Airline flight code in java String

I have string question. How to resolve this problem? Airline flight codes are typically composed of two characters which represent the airline and three or four numbers which represent the flight number. For example: FR1234: airline is Ryanair and the flight number is 1234.  Write a program that asks the user to enter a flight code and the program should then print out the Airline and Flight Number.  The program should keep asking the user to enter a flight code until the user enters the word END.  The program should work for the following flight codes where X represents a number: FRXXXX Ryanair EIXXXX Aer Lingus AFXXXX Air France AAXXX American Airlines BEXXX Fly Be  A message if any part of the flight code is invalid. A sample run of the program could be as follows: Please enter a flight code: FR1234 Airline: Ryanair Flight Number: 1234 Please enter a flight code: E112345 Invalid flight code. Please enter a flight code: AA222 Airline: American Airlines Flight Number: 222 Please … Could anyone know, do I need use substring or just if statement and check every flight code?

Is there a function to provide the first day of the month?

In Java I can get the first day of the month by this way:

GregorianCalendar date;
//Some code
int first = new GregorianCalendar(date.get(Calendar.YEAR),
            date.get(Calendar.MONTH), 1).get(Calendar.DAY_OF_WEEK);

I’m wondering if there a function to do that directly, Because I can’t find a function that grabs this vital information.

Jasper Reports print unconfigured report in xlsx, docx, csv, rtf, etc

good evening!
I have a web application that prints PDF reports without problems, but when I try to print these reports in xlsx, docx, csv, rtf, etc … the reports are all unconfigured
The browser tries to save the file always with the xhtml extension

I wonder if anyone has already gone through this and could you help me?

follow below code

public void gerarJasper(String name, String type, List data, Map params) throws IllegalArgumentException, RuntimeException, Exception {

    boolean found = false;
    for (int i = 0; i < VALID_TYPES.length; i++) {
        if (VALID_TYPES[i].equals(type)) {
            found = true;
            break;
        }
    }
    if (!found) {
        throw new IllegalArgumentException("Tipo solicitado '" + type + "' inválido");
    }

    // Procurar recurso de design de relatório compilado
    ExternalContext econtext = FacesContext.getCurrentInstance().getExternalContext();

    InputStream stream = econtext.getResourceAsStream(PREFIX + name + SUFFIX);
    if (stream == null) {
        throw new IllegalArgumentException("O relatório '" + name + "' não existe");
    }

    FacesContext fc = FacesContext.getCurrentInstance();
    ServletContext context = (ServletContext)fc.getExternalContext().getContext();
    String path = context.getRealPath(File.separator) + "resources/jasper" + File.separator;
    String logo = context.getRealPath(File.separator) + "resources/imagens" + File.separator;
    params.put("SUBREPORT_DIR", path);
    params.put("LOGO_DIR", logo);                

    JRDataSource ds = new JRBeanArrayDataSource(data.toArray());
    JasperPrint jasperPrint = null;
    try {
        jasperPrint = JasperFillManager.fillReport(stream, params, ds);
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new FacesException(e);
    } finally {
        try {
            stream.close();
        } catch (IOException e) {
        }
    }

    JRExporter exporter = null;
    HttpServletResponse response = (HttpServletResponse) econtext.getResponse();
    FacesContext fcontext = FacesContext.getCurrentInstance();
    try {
        response.setContentType(type);
        if ("application/pdf".equals(type)) {
            exporter = new JRPdfExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
        } else if ("text/html".equals(type)) {
            exporter = new JRHtmlExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter());
            // Tornar imagens disponíveis para a saída HTML
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();
            request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
            exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, new HashMap());
            // A seguinte instrução requer mapeamento / imagem
            // para o imageServlet no web.xml.
            //
            // Este servlet serve imagens, incluindo imagens px
            // para espaçamento.
            //
            // Sirva as imagens diretamente para não
            // incorrermos em tempo extra associado a
            // a uma solicitação JSF para uma entidade não-JSF.
            exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + "/image?image=");
        }else if("application/xlsx".equals(type)){
            exporter = new JRXlsxExporter();                
            exporter.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);                
            exporter.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, response.getOutputStream());
            //exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS,new Boolean(true));                                
            exporter.setParameter(JRXlsExporterParameter.OUTPUT_FILE, name+".xlsx");
            exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
            exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
            exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
            exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);

        }else if("application/csv".equals(type)){
            exporter = new JRCsvExporter();             
            exporter.setParameter(JRCsvExporterParameter.JASPER_PRINT, jasperPrint);                
            exporter.setParameter(JRCsvExporterParameter.OUTPUT_STREAM, response.getOutputStream());
            exporter.setParameter(JRCsvExporterParameter.OUTPUT_FILE_NAME, name+".csv");
        }else if("application/docx".equals(type)){
            exporter = new JRDocxExporter();
            exporter.setParameter(JRDocxExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRDocxExporterParameter.OUTPUT_STREAM, response.getOutputStream());
        } else if("application/rtf".equals(type)){
            exporter = new JRRtfExporter();
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());
        }
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new FacesException(e);
    }

    try {
        exporter.exportReport();
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new FacesException(e);
    }
    fcontext.responseComplete();
}

java.lang.reflect.InvocationTargetException error with onClick()

So I’m working with a few media players. The app opens up and there’s an animated GIF View, background music, and another audio file, voice instruction on how to use the app.

When the user clicks the gif view, the audio instructions are supposed to stop, and the app generates a response, also in the form of an mp3.

If they tap again, it generates a quote, once again, in the form of an mp3.

The trouble is, if the user doesn’t know how to use the app and isn’t patient, then they will keep tapping the screen and eventually, all these audio files will overlap and play all at the same time.

To prevent this I used some if statements and released the audio.

Now I get an error on the very first click…

Here’s my code:

    public void onClick(View view){
    final GifImageView clicked = (GifImageView) findViewById(R.id.gif);
    count ++;

    int random = randomGenerator.nextInt(6) * 1;

    if (count % 2 == 1 && count % 3 != 0){
        quotes.reset();
        quotes.stop();
        quotes.release();
        quotes = null;

        introVoice.reset();
        introVoice.stop();
        introVoice.release();
        introVoice = null;

        if (random == 1) {
            response = MediaPlayer.create(this, R.raw.veryunfavorable);
            response.start();
            Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            // Vibrate for 500 milliseconds
            v.vibrate(2500);
            clicked.setImageResource(R.drawable.red);
        }

Here’s My LogCat:

FATAL EXCEPTION: main
Process: com.example.okunato.chance, PID: 4755
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4728)
at android.view.View.performClick(View.java:5640)
at android.view.View$PerformClick.run(View.java:22455)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6196)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4723)
at android.view.View.performClick(View.java:5640) 
at android.view.View$PerformClick.run(View.java:22455) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6196) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778) 
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.media.MediaPlayer.reset()’ on a null object reference
at com.example.okunato.chance.MainActivity.onClick(MainActivity.java:153)
at java.lang.reflect.Method.invoke(Native Method) 
at android.view.View$DeclaredOnClickListener.onClick(View.java:4723) 
at android.view.View.performClick(View.java:5640) 
at android.view.View$PerformClick.run(View.java:22455) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6196) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778) 

Any help would be much appreciated. Thanks in advance!