Non c'entra assolutamente nulla con MySQL. Quella è una eccezione Java, che sta a significare che uno dei due oggetti che stai usando è nullo.
Quindi, o è nullo "con" o è nullo "array".
Tra l'altro stai usando delle PreparedStatement in modo assolutamente sbagliato: che senso ha usare delle PreparedStatement senza usarne i metodi per cui sono state inventate? Perchè concatenare i valori dei parametri con l'uso degli apici singoli (approccio che ti porta ad avere un potenziale problema di SQL Injection, oltre a problemi derivanti da possibili formattazioni dettate dal dialetto usato dal DB) quando usandole correttamente ti eviti tutto questo sbattimento e ti metti anche al riparo da dati malevoli?
StringBuilder sql = new StringBuilder();
sql.append("UPDATE table_products ");
sql.append("SET expiration_date = null ");
sql.append("WHERE product_code = ?");
PreparedStatement pstmt = null;
try {
pstmt = con.prepareStatement( sql.toString() );
pstmt.setString(1, array[0]);
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (pstmt != null) {
try { pstmt.close(); } catch (Exception e) { }
}
}
Qui almeno hai modo di sapere cos'è nullo: se la NPE ti viene sollevata alla prima riga dentro il blocco try/catch sai che è nulla la connessione.
Se ti viene sollevata alla riga dopo sai che è nullo l'array.