'cannot access class' 오류 해결 방법

JavaBeginner
지금 연습하기

소개

Java 프로그래밍에서 'cannot access class' 오류는 개발자들이 자주 직면하는 일반적인 문제입니다. 이 오류는 코드에서 여러 가지 이유로 접근할 수 없는 클래스를 사용하려고 할 때 발생합니다. 이 오류를 이해하는 것은 효과적인 Java 애플리케이션을 작성하는 데 필수적입니다.

이 실습 랩에서는 'cannot access class' 오류의 근본 원인을 배우고 이를 해결하기 위한 실질적인 해결책을 구현할 것입니다. 실제 예제를 통해 작업함으로써 Java 코드에서 접근성 문제를 진단하고 수정하는 데 필요한 귀중한 기술을 습득할 수 있습니다.

'Cannot Access Class' 오류가 있는 Java 프로젝트 생성

이 단계에서는 Java 프로젝트 구조를 생성하고 실제 'Cannot Access Class' 오류를 경험하게 됩니다. 이를 통해 오류가 실제로 어떻게 발생하는지 이해할 수 있습니다.

프로젝트 구조 설정

먼저, 터미널에서 다음 명령을 실행하여 프로젝트 디렉토리에 있는지 확인합니다.

pwd

다음과 같은 출력이 표시되어야 합니다.

/home/labex/project

설정 스크립트는 이미 기본 Java 프로젝트 구조를 생성했습니다. 다음 명령을 사용하여 이를 살펴보겠습니다.

ls -la

다음과 유사한 출력이 표시되어야 합니다.

total 12
drwxr-xr-x 4 labex labex 4096 May  5 10:00 .
drwxr-xr-x 5 labex labex 4096 May  5 10:00 ..
drwxr-xr-x 2 labex labex 4096 May  5 10:00 bin
-rwxr-xr-x 1 labex labex  105 May  5 10:00 compile.sh
-rwxr-xr-x 1 labex labex   64 May  5 10:00 run.sh
drwxr-xr-x 3 labex labex 4096 May  5 10:00 src

Java 클래스 생성

이제 'Cannot Access Class' 오류를 보여주는 두 개의 Java 클래스를 생성해 보겠습니다.

먼저, com.example.util 패키지에 Helper 클래스를 생성합니다. WebIDE 파일 탐색기에서 해당 파일로 이동하거나 다음 명령을 사용하여 파일을 엽니다.

mkdir -p src/main/java/com/example/util

WebIDE 에서 src/main/java/com/example/util로 이동하여 Helper.java라는 새 파일을 생성합니다. 다음 코드를 추가합니다.

package com.example.util;

class Helper {
    public void helperMethod() {
        System.out.println("This is a helper method.");
    }
}

이 클래스에는 기본 (패키지-private) 접근 제한자가 있으므로 동일한 패키지 내에서만 접근할 수 있습니다.

다음으로, Helper 클래스에 접근하려는 Main 클래스를 com.example.app 패키지에 생성합니다. WebIDE 에서 src/main/java/com/example/app로 이동하여 Main.java라는 새 파일을 생성합니다. 다음 코드를 추가합니다.

package com.example.app;

import com.example.util.Helper;

public class Main {
    public static void main(String[] args) {
        System.out.println("Attempting to access the Helper class...");

        // Try to create an instance of the Helper class
        Helper helper = new Helper();
        helper.helperMethod();

        System.out.println("Successfully accessed the Helper class!");
    }
}

컴파일 및 오류 관찰

이제 제공된 스크립트를 사용하여 Java 프로젝트를 컴파일해 보십시오.

./compile.sh

다음과 유사한 오류 메시지가 표시되어야 합니다.

src/main/java/com/example/app/Main.java:3: error: cannot access Helper
import com.example.util.Helper;
                      ^
  class file for com.example.util.Helper not found
src/main/java/com/example/app/Main.java:9: error: cannot find symbol
        Helper helper = new Helper();
        ^
  symbol:   class Helper
  location: class Main
src/main/java/com/example/app/Main.java:9: error: cannot find symbol
        Helper helper = new Helper();
                            ^
  symbol:   class Helper
  location: class Main
3 errors

이것이 'Cannot Access Class' 오류입니다. Helper 클래스를 생성했지만, Helper 클래스에 기본 접근 제한자가 있어 자체 패키지 내에서만 접근할 수 있으므로 Main 클래스는 이에 접근할 수 없습니다.

다음 단계에서는 이러한 유형의 접근 문제를 식별하고 해결하는 방법을 배우게 됩니다.

접근 제한자 문제 이해 및 해결

이전 단계에서 Helper 클래스가 기본 (패키지-private) 접근 권한을 가지고 있었기 때문에 'Cannot Access Class' 오류가 발생했습니다. Java 접근 제한자를 이해하고 이 문제를 해결해 보겠습니다.

Java 접근 제한자 이해

Java 는 네 가지 유형의 접근 제한자를 제공합니다.

  1. private: 동일한 클래스 내에서만 접근 가능
  2. default (제한자 없음): 동일한 패키지 내에서만 접근 가능
  3. protected: 동일한 패키지 내 및 하위 클래스에서 접근 가능
  4. public: 어디에서나 접근 가능

이 경우, Helper 클래스는 기본 접근 제한자를 가지고 있으며, 이는 com.example.util 패키지 내에서만 접근할 수 있음을 의미합니다. Main 클래스가 com.example.app 패키지에 있기 때문에 Helper 클래스에 접근할 수 없습니다.

접근 제한자 문제 해결

이 문제를 해결하려면 Helper 클래스의 접근 제한자를 기본에서 public 으로 변경해야 합니다. WebIDE 에서 Helper.java 파일을 열고 다음과 같이 수정합니다.

package com.example.util;

public class Helper {
    public void helperMethod() {
        System.out.println("This is a helper method.");
    }
}

class 선언 앞에 public 키워드가 추가된 것을 확인하십시오. 이렇게 하면 Helper 클래스를 모든 패키지에서 접근할 수 있습니다.

재컴파일 및 솔루션 테스트

이제 Java 프로젝트를 다시 컴파일합니다.

./compile.sh

컴파일이 성공하면 오류 메시지가 표시되지 않습니다. 애플리케이션을 실행하여 제대로 작동하는지 확인해 보겠습니다.

./run.sh

다음과 같은 출력이 표시되어야 합니다.

Attempting to access the Helper class...
This is a helper method.
Successfully accessed the Helper class!

이 출력은 이제 Main 클래스가 Helper 클래스에 접근하여 해당 메서드를 호출할 수 있음을 확인합니다.

솔루션 이해

Helper 클래스의 접근 제한자를 기본에서 public 으로 변경함으로써 Main 클래스가 있는 com.example.app 패키지를 포함하여 모든 패키지에서 접근할 수 있도록 했습니다.

이는 다른 패키지에서 클래스에 접근해야 할 때 'Cannot Access Class' 오류에 대한 일반적인 해결책입니다. 클래스를 해당 패키지 외부에서 접근 가능하게 하려면 public으로 선언해야 합니다.

다음 단계에서는 'Cannot Access Class' 오류의 또 다른 일반적인 원인인 잘못된 패키지 구조에 대해 배우게 됩니다.

패키지 구조 문제 해결

'Cannot Access Class' 오류의 또 다른 일반적인 원인은 잘못된 패키지 구조입니다. 이 단계에서는 Java 에서 패키지 구조 문제를 식별하고 해결하는 방법을 배우게 됩니다.

Java 에서 패키지 구조 이해

Java 에서 패키지 구조는 디렉토리 구조와 일치해야 합니다. 예를 들어, com.example.util 패키지의 클래스는 com/example/util 디렉토리에 위치해야 합니다.

물리적 디렉토리 구조가 패키지 선언과 일치하지 않으면 접근 제한자가 올바르더라도 'Cannot Access Class' 오류가 발생합니다.

패키지 구조 문제가 있는 클래스 생성

이 문제를 보여주기 위해 잘못된 패키지 선언을 가진 새 Java 클래스를 생성해 보겠습니다. src/main/java/com/example/util 디렉토리에 다음 내용으로 Logger.java라는 새 파일을 생성합니다.

package com.example.logger; // Incorrect package declaration

public class Logger {
    public void log(String message) {
        System.out.println("LOG: " + message);
    }
}

패키지 선언은 com.example.logger이지만 파일은 com/example/util 디렉토리에 있습니다. 이 불일치로 인해 'Cannot Access Class' 오류가 발생합니다.

이제 Logger 클래스를 사용하려는 src/main/java/com/example/app 디렉토리에 LogTest.java라는 새 파일을 생성합니다.

package com.example.app;

import com.example.logger.Logger;

public class LogTest {
    public static void main(String[] args) {
        Logger logger = new Logger();
        logger.log("Testing logger");
    }
}

컴파일 및 오류 관찰

Java 프로젝트를 컴파일해 보십시오.

./compile.sh

다음과 유사한 오류 메시지가 표시되어야 합니다.

src/main/java/com/example/app/LogTest.java:3: error: package com.example.logger does not exist
import com.example.logger.Logger;
                        ^
src/main/java/com/example/app/LogTest.java:6: error: cannot find symbol
        Logger logger = new Logger();
        ^
  symbol:   class Logger
  location: class LogTest
src/main/java/com/example/app/LogTest.java:6: error: cannot find symbol
        Logger logger = new Logger();
                            ^
  symbol:   class Logger
  location: class LogTest
3 errors

이 오류는 컴파일러가 com.example.logger 패키지에서 Logger 클래스를 찾을 수 없기 때문에 발생합니다. 해당 패키지가 없거나 디렉토리 구조가 패키지 선언과 일치하지 않기 때문입니다.

패키지 구조 문제 해결

이 문제를 해결하는 두 가지 방법이 있습니다.

  1. 패키지 선언을 디렉토리 구조와 일치하도록 변경합니다.
  2. 파일을 패키지 선언과 일치하는 디렉토리 구조로 이동합니다.

첫 번째 방법을 사용해 보겠습니다. Logger.java 파일을 열고 패키지 선언을 디렉토리 구조와 일치하도록 수정합니다.

package com.example.util; // Correct package declaration

public class Logger {
    public void log(String message) {
        System.out.println("LOG: " + message);
    }
}

또한 LogTest.java 파일에서 import 문을 업데이트합니다.

package com.example.app;

import com.example.util.Logger; // Updated import

public class LogTest {
    public static void main(String[] args) {
        Logger logger = new Logger();
        logger.log("Testing logger");
    }
}

재컴파일 및 솔루션 테스트

이제 Java 프로젝트를 다시 컴파일합니다.

./compile.sh

이제 컴파일이 오류 없이 성공해야 합니다. LogTest 클래스를 실행하는 간단한 스크립트를 만들어 보겠습니다.

echo "java -cp bin com.example.app.LogTest" > ./runlog.sh
chmod +x ./runlog.sh

이제 LogTest 클래스를 실행합니다.

./runlog.sh

다음과 같은 출력이 표시되어야 합니다.

LOG: Testing logger

이는 패키지 선언이 디렉토리 구조와 일치하므로 LogTest 클래스가 이제 Logger 클래스에 접근할 수 있음을 확인합니다.

솔루션 이해

'Cannot Access Class' 오류가 발생하면 항상 다음을 확인하십시오.

  1. 소스 파일의 패키지 선언이 디렉토리 구조와 일치하는지 확인합니다.
  2. import 문이 클래스가 있는 패키지를 올바르게 참조하는지 확인합니다.

이 두 가지 조건을 충족하면 Java 프로젝트에서 많은 'Cannot Access Class' 오류를 방지할 수 있습니다.

import 문 문제 처리

이 마지막 단계에서는 누락되거나 잘못된 import 문으로 인해 발생하는 'Cannot Access Class' 오류를 식별하고 해결하는 방법을 배우게 됩니다.

Java 에서 import 문 이해

import 문은 Java 컴파일러에게 코드에서 사용되는 클래스를 어디에서 찾아야 하는지 알려줍니다. 다른 패키지의 클래스를 import 하지 않고 사용하거나, 잘못 import 하면 'Cannot Access Class' 오류가 발생합니다.

import 문 없이 클래스 생성

적절한 import 문 없이 다른 패키지의 클래스를 사용하는 클래스를 만들어 보겠습니다. src/main/java/com/example/util 디렉토리에 다음 내용으로 Calculator.java라는 새 파일을 생성합니다.

package com.example.util;

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public int subtract(int a, int b) {
        return a - b;
    }
}

이제 Calculator 클래스를 import 하지 않고 사용하는 src/main/java/com/example/app 디렉토리에 CalculatorDemo.java라는 새 파일을 생성합니다.

package com.example.app;

// Missing import for Calculator class

public class CalculatorDemo {
    public static void main(String[] args) {
        Calculator calculator = new Calculator(); // Error: Cannot access Calculator

        int sum = calculator.add(5, 3);
        System.out.println("5 + 3 = " + sum);

        int difference = calculator.subtract(10, 4);
        System.out.println("10 - 4 = " + difference);
    }
}

컴파일 및 오류 관찰

Java 프로젝트를 컴파일해 보십시오.

./compile.sh

다음과 유사한 오류 메시지가 표시되어야 합니다.

src/main/java/com/example/app/CalculatorDemo.java:6: error: cannot find symbol
        Calculator calculator = new Calculator();
        ^
  symbol:   class Calculator
  location: class CalculatorDemo
src/main/java/com/example/app/CalculatorDemo.java:6: error: cannot find symbol
        Calculator calculator = new Calculator();
                                    ^
  symbol:   class Calculator
  location: class CalculatorDemo
2 errors

이 오류는 CalculatorDemo 클래스가 Calculator 클래스를 import 하지 않고 사용하려고 하기 때문에 발생합니다.

import 문 문제 해결

이 문제를 해결하려면 CalculatorDemo.java 파일에 적절한 import 문을 추가합니다.

package com.example.app;

import com.example.util.Calculator; // Added import statement

public class CalculatorDemo {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        int sum = calculator.add(5, 3);
        System.out.println("5 + 3 = " + sum);

        int difference = calculator.subtract(10, 4);
        System.out.println("10 - 4 = " + difference);
    }
}

재컴파일 및 솔루션 테스트

이제 Java 프로젝트를 다시 컴파일합니다.

./compile.sh

이제 컴파일이 오류 없이 성공해야 합니다. CalculatorDemo 클래스를 실행하는 간단한 스크립트를 만들어 보겠습니다.

echo "java -cp bin com.example.app.CalculatorDemo" > ./runcalc.sh
chmod +x ./runcalc.sh

이제 CalculatorDemo 클래스를 실행합니다.

./runcalc.sh

다음과 같은 출력이 표시되어야 합니다.

5 + 3 = 8
10 - 4 = 6

이는 올바른 import 문을 추가했으므로 CalculatorDemo 클래스가 이제 Calculator 클래스에 접근할 수 있음을 확인합니다.

솔루션 이해

'Cannot Access Class' 오류가 발생하면 다음을 확인하십시오.

  1. 사용하려는 클래스를 import 했는지 확인합니다.
  2. import 문이 올바른 패키지를 가리키는지 확인합니다.
  3. import 하려는 클래스가 public 인지 확인합니다 (2 단계에서 배웠습니다).

Java 는 클래스를 import 하는 두 가지 방법을 제공합니다.

  1. 단일 유형 import (Single-type import): import com.example.util.Calculator;
  2. 요청 시 import (On-demand import): import com.example.util.*;

단일 유형 import 는 사용되는 클래스를 명확하게 보여주므로 일반적으로 선호됩니다. 요청 시 import (와일드카드 * 사용) 는 패키지의 모든 클래스를 import 하며, 이는 서로 다른 패키지에 동일한 이름의 클래스가 있는 경우 이름 충돌을 일으킬 수 있습니다.

import 문이 올바른지 확인하면 Java 프로젝트에서 많은 'Cannot Access Class' 오류를 방지할 수 있습니다.

요약

이 랩에서는 Java 에서 'cannot access class' 오류를 식별하고 해결하는 방법을 배웠습니다. 이제 이 오류의 세 가지 주요 원인을 이해하게 되었습니다.

  1. 접근 제한자 문제 (Access Modifier Issues): 클래스가 적절한 접근 제한자로 선언되지 않은 경우 특정 위치에서 접근할 수 없습니다. 클래스를 public으로 만들면 모든 패키지에서 접근할 수 있습니다.

  2. 패키지 구조 문제 (Package Structure Issues): Java 파일의 패키지 선언은 디렉토리 구조와 일치해야 합니다. 불일치가 있으면 컴파일러가 클래스를 찾을 수 없어 'cannot access class' 오류가 발생합니다.

  3. import 문 문제 (Import Statement Issues): 다른 패키지의 클래스는 import 문을 사용하여 적절하게 import 해야 합니다. 누락되거나 잘못된 import 문은 'cannot access class' 오류로 이어집니다.

이러한 원인과 해결책을 이해함으로써 Java 프로젝트에서 'cannot access class' 오류를 효과적으로 진단하고 해결할 수 있습니다. 이 지식은 시간을 절약하고 더 강력하고 유지 관리 가능한 Java 코드를 작성하는 데 도움이 될 것입니다.