[JSP] 2020.11.14 개발일지(NullPointerException trouble shooting)

초보개발자
9 min readNov 14, 2020

--

*개인적인 개발 경험담을 다룬 글이라 반말인 점 미리양해 부탁드립니다.

에러발생 경위와 해결과정

  1. JSP를 통해 게시판을 구현하기 위해 클론코딩을 시작했다. 그리고 이 날 수강한 강의의 내용은 다음과 같았다.
  2. login.jsp에서 form태그로 아이디, 패스워드 값을 입력받는다 → 이 값을 UserDAO객체로 전달한다. → DAO객체가 MySQL로 접근해서 전달받은 아이디, 패스워드가 일치하는지 확인한다. → 일치 여부에 따라 특정 액션을 취한다.(main.jsp로 이동한다던가 아이디가 존재하지 않는다는 팝업창을 띄워준다던가)
  3. 강의 내용을 따라 코드를 타이핑했다. 그 후 eclipse의 run on server를 누르려는 순간, IDE에서 빨간 느낌표를 뿜어냈고 그 부분을 대수롭지 않게 더블클릭으로 해결했다.
설명-31번 줄에 보이는 빨간 느낌표
설명-느낌표를 클릭하니 팝업창이 발생했고
설명-팝업 창의 제일 윗줄을 선택하니 빨간 느낌 표가 사라졌다!

4. 하지만 이렇게 해도 브라우저의 localhost는 내게 원하는 결과를 돌려주지 않았다. 분명 mysql과 java를 연결하는 jdbc(Jar형식)파일도 lib에 적용시켜 주었는데 무엇이 문제일까 고민하다가 순간 Connection 객체인 conn에 대해 잘못된 설정 값을 인자로 넣었나? 생각이 들었다.

설명-conn 부분이 ‘4’번에서 언급하는 부분

5. dbURL은 강의에서는 3306이었지만 나는 terminal로 port를 찾아본 결과, port번호가 0이어서 저렇게 넣은거였고 dbID는 강의와 똑같이 ‘root’를 넣어준 것인데 혹시 모르니 다시 찾아보기로 했다.

왼쪽의 ’mysql server status’로 오른쪽의 port번호를 확인했었다! 분명 0이다.
하지만 port번호를 show global variables like ‘port’를 통해 다시 확인한 결과 0이 아니라 3306이였음
(use mysql; → select user from user;)로 dbID를 다시 확인해도 ‘root’는 처음에 확인한 것과 같은 값이었다.
port번호를 변경했다

6. port번호 변경 후에 시도해봐도 브라우저의 localhost는 내게 원하는 결과를 주지 않았다,, 그러던 중 강의 게시판에서 다른 유저분들이 이 부분에 대해 설정을 달리 해주어야 한다고 안내해주었고 그 코드로 수정하게 되었다.

dbURL부분, Class.forName 이부분을 수정함

7. 아 이제 다 끝났구나 하며 실행해보았지만 역시 원하는대로 흘러가지 않았다. 그리고 다음과 같은 에러와 마주했다.

설명-제일 위의 커서로 블록처리 한 부분이 에러내용

8. NullPointerException?(이 글의 제목에 언급한 에러) 그리고 pstmt.executeQuery()부분에서 발생? Java 강의 때 NullPointerException이 null을 가리키는 reference로 함수 호출 시에 발생하는 거라고 배워서 알았지만 pstmt는 null일수가 없는데? 싶어 막막했다. 그래도 왜 null인지 알아보기 시작했다.

9. 처음엔 pstmt = conn.prepareStatement(sql); 이부분에서 문제가 발생하는건가? conn이 제대로 문젠가? 싶었다.(애초에 conn이 문제였다면 위의 try catch문의 exception에서 걸러졌겠지만 이땐 몰랐다)

‘9번’에서 언급하는 코드가 30번 줄이다.

10. 그래서 pstmt2와 sql2를 만들어 수행하니 MySQL DB에서 값이 가져와지는 것을 보고 DB와의 연결문제는 아니란 걸 확신했다. 그럼 어디가 문제지?

sql2와 pstmt2를 만들어 수행하니 이번엔 NullPointerExeption이 발생하지 않았다.
콘솔창에 왼쪽의 문구가 출력 되지도 않았고 오른쪽처럼 MySQL에서 유저 아이디를 불러왔기 때문에 JSP와 MySQL 연동은 확실한 부분이었다.

11. login함수의 parameter(String userID, String userPassword)로 제대로된 값이 전달이 안되는건가? 싶어서 login함수를 호출하는 곳인 loginAction.jsp에서 값을 인자로 넘기기 전에 out.print()를 통해 인자 값을 출력해봐도 문제는 없었다.

설명-왼쪽은 login함수에 값을 넘기기 전 loginAction.jsp 부분이며 인자 값을 출력 해본 결과가 오른쪽

12. 포기를 고민하던 순간, 위의 원인들을 종합적으로 분석해봤을 때 setString쪽에 문제가 있다고 감이 왔고 setString을 MySQL문서에서 찾아보았다.

왼쪽 setString부분에 심증이 생겼다. 저기가 아니면 도무지 이유가 없었기 때문이다. 오른 쪽은 Oracle사이트의 setString 예제

13. 이때까지도 심증만 있을 뿐 뭐가 문제인진 몰랐다. setString에서 넘겨받는 인자값이 잘못된 것도 아니었고 문법도 잘 맞게 적어줬는데 왜 계속 nullpointerException이 발생하지?라고 생각하던 찰나 코드를 다시 보았다. ‘pstmt = setString(1, userID);’?? 대입연산자?? 이때 쎄한 느낌을 받았다. setString함수가 저렇게 단독으로 쓰이는데 반환 값으로 PreparedStatement 객체형이라는 것이 이상하게 느껴졌기 때문이다. 그리고 다시 Oracle의 예제를 저 부분에 포커스를 맞춰 들여다본 결과..

14. 역시 ‘pstmt = setString(1, userID)’가 아니라 ‘pstmt.setString(1, userID)’가 맞았다. 그리고 드디어 브라우저의 localhost에서 내가 염원하던 결과 창을 볼 수 있었다.

결국 급하게 클론코딩을 하다가 ‘.’ 대신 ‘=’을 치게되서 발생한 문제였던 것이다.

결론

내 실수를 되짚어보면 결국 과정 3번에서 빨간 느낌표는 저런식으로 해결하면 안됐던 문제였다. 또 코드를 직접 타이핑하지말고 복붙으로 진행했으면 발생하지 않았을 문제였다. 그래도 삽질하며 trouble shooting했던 경험은 나름대로 교훈이 있었고 다음의 비슷한 유형의 문제에서 미래의 나를 구원해줄 것이기에 너무 억울해하지는 않기로 했다. 다만 비슷한 실수는 반복하지 않도록 주의해야겠다.

이번 일로 얻은 성과

1.try, catch문에서 catch쪽을 어떻게 활용해야하는지 알것 같다.(어디서 오류가 발생하는지만 알아도 스트레스가 확 줄어드는 기분)

2.prepareStatement의 setString 함수를 이해하게 되었다.(파라미터의 의미, 함수로 인해 객체가 어떤 변화를 갖는지, 공식 문서/예제를 확인하는 것의 중요성)

3.단순 코드는 복붙해야한다는 것을 깨달았다.(동시에 삽질에서도 배움은 있다는 것을 느꼈고)

4.환경설정 방법, 콘솔 오류내용을 돌아보면서 발생한 문제에 대해 차분히 분석해보는 시간을 가질 수 있었다.(오류메시지를 차분히 분석해보면 의외로 답이 보인다?)

5.MySQL port확인, dbID확인, JSP의 흐름 파악(인자가 어디서 와서 어디로 가는지 눈 크게 뜨고 파악하려다보니) 등 뭔가 형언할 수 없지만 뭉뚱그려진 것이 JSP개발에 한 발짝 다가가게 해준 기분이 들었다.(정신승리인가?)

참고 사이트

  1. port번호 확인방법을 알게 된 곳
  2. MySQL의 사용자 조회방법을 알게 된 곳
  3. 인프런 강의게시판의 어떤 유저분이 올려주신 코드4
  4. MySQL setString 설명 예제

https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

--

--

No responses yet