NullPointerException в jsp, но не в консоли - PullRequest
1 голос
/ 22 июля 2011

RecupData Мой класс возвращает исключение NullPointerException только в Интернете. Я подключаюсь к pgsql db 8.3.7 - скрипт хорошо работает в syso 'console' - но создается тестовое исключение NullPointerException

Вот метод, который выдает исключение:

/**
 * 
 */
package com.servlet.pgsql;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 *
 */
public class RecupData {

    /**
     * Connection connection
     */

    static String SqlSinRef     = "SELECT * FROM \"SINref\""; // view in pgsql - contain only 1 column
    static Connection connection;
    static Statement statement;



    /**
     * cette méthode sert pour toutes les connections de la classe RecupData
     */
    public static Statement state() {

        try{
           connection = UniqueConnection.getInstance();
           statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
        }
        catch(Exception e) {    e.printStackTrace();    }

        return statement;
    }


    public static String htmlListeRefDossier() {

        ResultSet resultat;

        String listeHtml    =   "<form>\n" +
                                "\t<select>\n";     

        try {
            resultat = state().executeQuery(SqlSinRef);
            while(resultat.next()) {
                listeHtml = listeHtml+"\t\t<option>"+resultat.getString(1)+"</option>\n";   }
        }
        catch (SQLException e) {
            listeHtml = listeHtml+"sql exception sortie";
            e.printStackTrace();
        }
        catch (NullPointerException e) {
            listeHtml = listeHtml+"null pointer exception -sortie";
            e.printStackTrace();
        }


        listeHtml = listeHtml+"\t</select>\n</form>";
        return listeHtml;

    }


    /*
     * valable just pour le dev
    * method main only for test in console
     */
    public static void main(String[] args) throws SQLException {

        System.out.println(htmlListeRefDossier());

    }
    /*
     * A SUPPRIMER  
     */

} // fin class

это UniqueConnection:

public class UniqueConnection {

  private volatile static Connection connect;

  public static Connection getInstance(){

    if(connect == null){
      synchronized(Connection.class){
        try {  connect = DriverManager.getConnection(url, user, passwd);  }
        catch(SQLException e) { e.printStackTrace(); }
      }
    }
    return connect; 
  } 

}

не могли бы вы взглянуть? Спасибо!

Ответы [ 2 ]

1 голос
/ 22 июля 2011

Смотрите здесь:

public static Statement state() {

    try{
       connection = UniqueConnection.getInstance();
       statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    }
    catch(Exception e) {    e.printStackTrace();    }

    return statement;
}

Ваша обработка исключений плохая.Если UniqueConnection.getInstance() или connection.createStatement() выдает исключение, то код немедленно перейдет в блок catch, тем самым не затрагивая переменную statement, которая, таким образом, остается null.Поскольку вы просто печатаете трассировку стека на стандартный вывод и продолжаете поток кода вместо того, чтобы выдавать полноценное исключение, код продолжается в строке return statement.Поскольку statement по-прежнему null, вы получите NullPointerException всякий раз, когда пытаетесь вызвать метод для возвращаемого значения.

resultat = state().executeQuery(SqlSinRef); // state() returns null, so NPE!

Вам необходимо прочитать трассировку стека, которая печатается внутриcatch предложение для реальной причины проблемы, а не той, которая вызвана NPE.Или, что еще лучше, создайте реальное исключение, чтобы код немедленно остановился вместо продолжения потока и работы с переменными, которые, возможно, null.

Исправили все ваши catch предложения, которые просто поглощают исключение.и печатать трассировку, чтобы вместо этого выдать реальное исключение:

catch(SomeException e) { throw e; }

Или, лучше, просто удалить их и использовать вместо этого предложение throws в объявлении метода.Блок try следует использовать только тогда, когда вы можете обработать исключение разумным способом (т. Е. Выбрать альтернативный путь, отобразить экран ошибки для конечного пользователя и прервать код и т. Д .; просто напечатайте трассировку ипродолжение с null переменными определенно не является правильным альтернативным путем), или всякий раз, когда вы хотите использовать finally блок для закрытия и освобождения дорогих ресурсов.1037 * a SQLException: no suitable driver, потому что загрузка драйвера не удалась с ClassNotFoundException org.postgresql.Driver, и вы исключили это исключение таким же образом.


Не связано с проблемой: естьболее серьезные проблемы с вашим кодом.

  • Вы объявили дорогие ресурсы базы данных, такие как соединение, оператор и набор результатов, как static переменные класса.Это не потокобезопасно!Он будет хорошо работать в приложении, которое использует их один раз , а затем немедленно выключается.Но он с треском провалится в приложении, которое использует их несколько раз во время выполнения, например в веб-приложении.

  • Вы не не хотите использовать «уникальное соединение» в течение всего срока службы веб-приложения.Средняя база данных автоматически закроет ее, если она будет открыта слишком долго.Вам необходимо получить и закрыть соединение, выписку и набор результатов в кратчайшие сроки.Если вы хотите улучшить производительность соединения, вам следует вместо этого использовать пул соединений.

  • Ваш уровень доступа к данным очень тесно связан с уровнем представления.Вы строите какой-то фрагмент HTML внутри класса доступа к базе данных, а не внутри файла JSP.

Исправьте это соответствующим образом.Вы можете найти некоторые примеры в ответах на следующие вопросы:

0 голосов
/ 22 июля 2011

Я предполагаю, что здесь statement будет нулевым:

statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                       ResultSet.CONCUR_READ_ONLY);

Я предполагаю, что это как-то связано с оператором synchronized, поскольку сервлеты и jsp обычно должны быть собраны как thread-safe манера

Пожалуйста, попробуйте инициализировать ваше соединение в пределах вашего RecupData, но без каких-либо операторов synchronized и static и посмотрите, работает ли это - может также быть проблемой для вашего Classloader, чтона некоторых серверах приложений это совсем не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...