반응형

Java는 강력하고 안정적인 언어로 다양한 웹 프로젝트에서 널리 사용됩니다. 하지만 프로젝트를 진행하다 보면 크고 작은 오류가 발생하기 마련입니다. 이러한 오류는 개발 과정에서 디버깅 시간을 늘리고 생산성을 저하시키는 요인이 됩니다. 이번 글에서는 Java 기반 웹 프로젝트에서 자주 발생하는 오류와 그 해결 방법을 정리하였습니다.


1. NullPointerException

오류 설명

Java에서 NullPointerException은 가장 빈번히 발생하는 오류 중 하나입니다. 객체가 null인 상태에서 해당 객체의 메서드나 필드에 접근하려고 시도할 때 발생합니다.

발생 상황 예시

String name = null;
System.out.println(name.length());

해결 방법

  1. null 체크를 통해 방지합니다.
  2. if (name != null) { System.out.println(name.length()); }
  3. Optional을 활용하여 null 값을 처리합니다.
  4. Optional<String> optionalName = Optional.ofNullable(name); optionalName.ifPresent(n -> System.out.println(n.length()));
  5. 초기 값을 할당하거나 null을 피하도록 설계합니다.
  6. String name = "";

2. ClassNotFoundException

오류 설명

JVM이 특정 클래스를 로드하려고 시도했지만 해당 클래스를 찾을 수 없을 때 발생합니다. 이는 주로 클래스 경로가 잘못 설정되었거나 필요한 라이브러리가 누락된 경우입니다.

발생 상황 예시

Class.forName("com.example.NonExistentClass");

해결 방법

  1. 필요한 라이브러리가 classpath에 포함되었는지 확인합니다.
    • Maven 프로젝트에서는 pom.xml에 필요한 의존성을 추가하세요.
      <dependency>
          <groupId>com.example</groupId>
          <artifactId>example-library</artifactId>
          <version>1.0.0</version>
      </dependency>
      
  2. IDE 설정에서 클래스 경로를 확인하고 누락된 라이브러리를 추가합니다.
  3. 서버에서 발생하는 경우, 배포 시 모든 종속 라이브러리가 포함되었는지 확인합니다.

3. NoClassDefFoundError

오류 설명

NoClassDefFoundError는 컴파일 시에는 존재했던 클래스가 런타임 시에 로드되지 않을 때 발생합니다. 이는 주로 배포 환경에서의 설정 문제로 인해 나타납니다.

발생 상황 예시

MyClass myClass = new MyClass();

해결 방법

  1. JAR 파일이 올바르게 배포되었는지 확인합니다.
  2. Maven을 사용하는 경우, mvn clean install 명령을 사용하여 프로젝트를 다시 빌드합니다.
  3. 종속성이 누락되지 않도록 shade 플러그인이나 assembly 플러그인을 사용하여 단일 JAR 파일로 패키징합니다.

4. SQLException

오류 설명

SQLException은 데이터베이스 작업 중에 발생하는 오류로, 잘못된 쿼리나 데이터베이스 연결 문제로 인해 발생합니다.

발생 상황 예시

Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "user", "password");
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM non_existent_table");

해결 방법

  1. SQL 쿼리의 문법을 검토합니다.
  2. 데이터베이스 URL, 사용자 이름, 비밀번호가 정확한지 확인합니다.
  3. 데이터베이스 드라이버가 올바르게 설정되었는지 확인합니다.
    • 예: MySQL 드라이버 추가
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.32</version>
      </dependency>
      
  4. 예외 처리를 통해 문제를 로그로 기록하고 디버깅합니다.
  5. try { // DB 작업 } catch (SQLException e) { e.printStackTrace(); }

5. OutOfMemoryError

오류 설명

OutOfMemoryError는 JVM 힙 메모리가 부족할 때 발생합니다. 이는 메모리 누수나 지나치게 큰 데이터 구조를 사용할 때 나타납니다.

발생 상황 예시

List<String> largeList = new ArrayList<>();
while (true) {
    largeList.add("Memory Leak");
}

해결 방법

  1. JVM 힙 크기를 늘립니다.
    • 예: -Xmx1024m 옵션 추가
  2. 메모리 누수를 방지합니다.
    • 사용하지 않는 객체는 null로 설정하여 GC가 수집할 수 있도록 합니다.
    • 큰 데이터를 처리할 때는 스트리밍 방식을 사용합니다.
  3. 프로파일링 도구를 사용하여 메모리 사용 패턴을 분석합니다.
    • VisualVM, JProfiler 등

6. StackOverflowError

오류 설명

StackOverflowError는 재귀 호출이 너무 깊어져 스택 메모리가 초과되었을 때 발생합니다.

발생 상황 예시

public int factorial(int n) {
    return n * factorial(n - 1);
}

해결 방법

  1. 재귀 호출 대신 반복문을 사용합니다.
  2. public int factorial(int n) { int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; }
  3. 재귀 호출의 종료 조건을 명확히 설정합니다.
  4. public int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); }

7. ConcurrentModificationException

오류 설명

ConcurrentModificationException은 컬렉션을 순회하는 동안 해당 컬렉션을 수정하려고 할 때 발생합니다.

발생 상황 예시

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
for (String item : list) {
    if (item.equals("B")) {
        list.remove(item);
    }
}

해결 방법

  1. Iterator를 사용하여 수정합니다.
  2. Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { if (iterator.next().equals("B")) { iterator.remove(); } }
  3. Stream API를 사용하여 필터링합니다.
  4. list = list.stream() .filter(item -> !item.equals("B")) .collect(Collectors.toList());

8. IllegalArgumentException

오류 설명

메서드에 잘못된 인자가 전달될 때 발생합니다. 이는 주로 인자의 유효성을 검증하지 않을 때 나타납니다.

발생 상황 예시

public void setAge(int age) {
    if (age < 0) {
        throw new IllegalArgumentException("Age cannot be negative");
    }
    this.age = age;
}

해결 방법

  1. 입력값 검증 로직을 추가합니다.
  2. 적절한 예외 메시지를 제공하여 디버깅을 용이하게 합니다.

마무리

Java 기반 웹 프로젝트에서는 다양한 오류가 발생할 수 있지만, 오류의 원인을 이해하고 적절히 대처하면 문제를 효과적으로 해결할 수 있습니다. 위에서 소개한 사례들은 자주 발생하는 오류들이므로, 사전에 방지하고 해결 방안을 익혀 두면 프로젝트 개발 속도를 크게 향상시킬 수 있습니다.

반응형

+ Recent posts