
사용환경
운영체제: MacOS Sonoma 14
IDE: IntelliJ IDEA 2023.3.2 (Ultimate Edition)
Java: Java 17
순수 Java를 사용하여 객체지향 프로그래밍을 연습해보려고 인텔리제이를 이용해서 Java프로젝트를 생성했는데 아래 사진과 같이 자바에 내장된 System라이브러리를 인식하지 못하는 오류가 발생하였다.

System클래스를 들어가보니 "Library source does not match the bytecode for class System"라고 경고 문구가 나와있고, 클래스 파일은 정상적으로 빌드된걸 보아하니 컴파일 과정에서 문제가 있는듯 하였다.
생각해보니 나는 매일 IDE가 알아서 빌드해주는 프로젝트 위에서 코드를 구현하고 프로젝트를 만들어가고 있었다.
이 문제를 해결하는 방법은 구글링을 통해 버튼을 몇 개 따라누르면 해결할 수 있겠지만 이 계기를 통해서 내가 IDE에 요청한 프로젝트는 어떻게 생성되는지에 대한 과정을 가볍게나마 알아보려고 한다.
먼저 어떻게 해결방법을 확인해보고 해결방법안에 보이지 않는 과정이 어떻게 진행된것인지 알아보자.
해결방법
인텔리제이의 메뉴툴에서 File > Invalidate Caches > Invalidate and Restart 를 순서대로 클릭하면 프로젝트가 다시 빌드되면서 System라이브러리에 발생했던 오류가 사라지고 println()메서드가 정상적으로 수행되는 것을 확인할 수 있다.
해결과정으로 유추해보건데,
인텔리제이는 여러가지 사용자에 따라서 수많은 라이브러리들을 포함시켜 프로젝트를 빌드할 수 있고 아닐수도 있다.
만약 수많은 라이브러리들을 포함하여 프로젝트를 생성할 경우 사용자 입장에서는 프로젝트를 빌드하는데만 엄청난 시간을 들여야할 것이다.
그 문제를 해결하기위해 프로젝트를 빌드하는 과정을 캐시로 처리하는 듯 보였다.
나는 그 캐시과정에서 어떤 문제가 생겨 자바 라이브러리를 제대로 불러오지 못하는듯 하였다.
분석해보기
실제로 내가 유추한 캐시관련 문제가 맞는듯 하였고 문제를 깊이 파보기위해서는 선수지식으로
빌드, 컴파일과 같은 지식들이 필요하다 생각하였고 그 부분에 대한 것들을 검색하고 알아보았다.
Build
지금 생각해보니 빌드는 프로젝트의 첫 시작점이라고도 할 수 있는데, '빌드'라고 하면 그냥 Gradle, Maven밖에 생각이 나지 않는다..
가장 기초적이었던 부분을 간과했던 자신에게 반성한다...

프로젝트를 생성할 때 항상 보게되는 화면이다.
Build system옵션으로 InteliJ, Maven, Gradle을 선택할 수 있다.
먼저 빌드의 정의는
"소스코드와 필요한 리소스를 모아 실행 가능한 프로그램으로 변환하는 과정으로 개발자가 작성한 소스코드를 컴퓨터가 이해할 수 있는 바이너리 파일로 변환하고 라이브러리 및 종속성을 통합하여 최종적으로 사용자가 실행할 수 있는 프로그램을 생성하는 것을 의미한다."
나는 빌드가 단순히 프로젝트를 생성할 때 개발자의 편의를 위해 프로젝트에 라이브러리를 종속시켜줌과 동시에 프로젝트를 만들어주는 역할만 수행하는 줄 알았는데, 지금보니 컴파일, 테스트, 배포 과정 모두 빌드에 포함되는 과정이라는 것을 처음알았다.
또한 빌드에도 여러가지 방식이 있는데 그 중 하나가 증분 빌드이다.
증분 빌드는 변경된 부분만 빌드를 하는 방식으로 변경되지 않은 부분은 빌드하지 않음으로써 빌드하는 과정을 최적화하여 빠른 빌드를 할 수 있게한다. 증분 빌드방식을 사용하는 Build system중 하나가 바로 IntelliJ이다.
증분빌드는 마치 HTTP통신에서 서버로부터 HTML, CSS, 이미지 파일과같은 정적인 소스들을 클라이언트가 받을때 캐시방식을 통해 전달받는 방식과 유사한듯 하였다.
생각해보니 예전에 인프런에서 김영한님의 강의를 들을 때 테스트 코드를 실행할 때 인텔리제이 설정에서 빌드 도구를 Gradle에서 IntelliJ IDEA로 변경함으로써 테스트속도를 좀 더 빨리 수행하는 방법을 알려주셨었는데,
이는 빌드 도구를 인텔리제이 자체 빌드로 변경함으로써 증분 빌드를 하게하고, 그를 통해 테스트 코드의 수행을 보다 빠르게 할 수 있었던 것이다.
이를 통해 왜 빌드툴을 인텔리제이로 선택했을 때 테스트코드가 빠르게 수행되는지 알게되었고,
이는 테스트코드를 수행한다는 것이 빌드에 포함된다는 것을 알게되었다.
컴파일
사람이 읽을 수 있도록 프로그래머가 작성한 코드를 컴파일러가 컴퓨터가 이해할 수 있는 비교적 저차원 언어로 변경하는 과정을 컴파일이라고 한다. 마치 번역가와 같은 역할이다.
예를 들어서 System.out.println("HELLO"); 라는 코드를 컴파일과정을 거치면 010101000(예시)와 같은 결과물이 만들어지게 되고 이를 바이트 코드라고 한다.
Java에서는 이런 컴파일러를 JVM에 포함하고 있다.
보다 깊은 이해를위해 자바의 컴파일과정을 간단하게나마 살펴보았다.
먼저 테스트하기위한 Java코드를 작성한다.
public class Main {
public static void main(String[] args) {
System.out.println("hello");
}
}
위 Main클래스의 현재 상태는 컴파일되기 전으로 .java라는 확장자를 갖는 소스코드 파일입니다.
그리고 터미널에서 javac Main.java 명령어를 입력하여 자바 컴파일러로 Main소스코드 파일을 컴파일합니다.
그럼 현재상태는 컴파일과정을 거쳐 컴퓨터들이 이해할 수 있는 바이너리 파일이 생성된 것입니다.
이 때에는 Main.class 라는 확장자를 갖게됩니다.

컴파일러를 통해 생성된 class파일을 실제로 읽어보면 사람이 해석할 수 없는 이진파일로 이루어져있습니다.
이제 Main.class파일은 JVM을 통해 실행될 준비가 완료된 것입니다!
마치 사람이 실행하는 .exe 파일과 같이 .class파일은 JVM입장에서의 .exe파일과 같은 형태인 것입니다.
결론
이제 본론으로 돌아와서 왜 인텔리제이가 프로젝트를 빌드하는 과정에서 문제가 생겼는지 생각해보자면,
빌드하는 과정에는 컴파일역시 포함되었다고 알아보았었다.
따라서 기존에 Gradle로 자바 프로젝트를 빌드 하다가, 위에서 언급한대로 김영한님의 인프런 강의를 수강하는 과정에서 빌드 툴을 Gradle에서 IntelliJ 자체 빌드 방법으로 설정을 변경했고 이 과정에서 증분 빌드방식이 사용되었기때문에 캐시메모리에 인텔리제이가 자체적으로 기존에있던 파일들을 정상적으로 불러오지 못한듯하였고,
그로인해 새로운 프로젝트를 빌드하는 과정에서 캐시메모리에 담긴 소스파일과 클래스파일이 일치하지 않아서 캐시 메모리가 손상되는 문제가 발생한 듯 하였다.
때문에 인텔리제이의 툴에서 캐시를 Restart함으로써 문제를 해결할 수 있었다.
앞으로 더 필요하다고 생각한 지식
1. 빌드 과정과 각 빌드 툴들에 대한 특징
2. JVM을 통해 컴파일함으로써 얻는 장점
혹시라도 잘못된 내용이 있다면 저의 부족함을 다시 반성하기위해 댓글로 남겨주시면 감사드리겠습니다..!!
참고한 포스팅, 자료
https://pamyferret.tistory.com/62 - 빌드, Gradle, IntelliJ
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!