glenn-syj / more-effective-java

이펙티브 자바를 읽으며 자바를 더 효율적으로 공부합니다
4 stars 5 forks source link

[MEJ-006] 톱레벨 클래스 중복 시 동작에 관해서 (eclipse 컴파일러) #138

Closed glenn-syj closed 5 months ago

glenn-syj commented 6 months ago

Based on : #125 by @FickleBoBo

톱레벨 클래스 중복 시 동작에 관해서 (eclipse 컴파일러)

들어가며

이번 이슈는 사실 정확한 원인은 모르지만, 최대한 현상을 실험하고 원인을 추측하는 것에 목적을 두었습니다. 우선, 해당 절에 서술된 대로 Utensil.java, Dessert.java, Main.java를 한 패키지에 두고 이용했습니다. (Java 버전은 JDK 17이며, ecilipse 버전은 2023-12 (4.30.0) 빌드는 20231201-2043입니다.)

자바 코드와 바이트코드

첫 번째 컴파일

image

image

image

두 번째 컴파일

image

image

image

세 번째 컴파일 이번에는 Utensil.java의 코드를 바꾸고 실행해보았습니다. 어떤 결과를 가져올까요?

image

네 번째 컴파일 이제 'Dessert.java'의 코드를 바꾸고 실행해보겠습니다.

image

이클립스 컴파일러

그렇다면 왜 이클립스 컴파일러에서는 오류가 나지 않을까요? 이는 바로 이클립스가 javac와 달리 자체적인 컴파일러를 이용하는 까닭입니다.

증분 컴파일러 이클립스 컴파일러는 프로그램의 모든 모듈을 클린 빌드하지 않고, 지난 컴파일에서 변경된 부분만을 다시 컴파일하는 증분 컴파일러(incremental compiler) 입니다.

추측

위 예시에서, 이클립스의 증분 컴파일에서 다음과 같은 작동이 일어날지도 모릅니다. 이는 단순 추측에 불과하며, 아직 큰 의미를 발견하지는 못했습니다.

  1. 첫 컴파일에서 두 파일의 정의가 모두 후보군에 올랐으며 Dessert.class 내 톱레벨 클래스가 우선 사용됨 (potpie)
  2. Dessert.java에 기반해 다시 컴파일되어 톱레벨 클래스 내 NAME 값이 정해졌으나 (jartart), 이는 기존 컴파일에서의 쓰이지 않은 후보(pancake)가 실은 기존값이기에 휘발됨
  3. Utensil.java가 다시 컴파일되었고(bottlejelly), 이는 프로그램 변경사항의 중점인 Dessert.java가 아니므로 톱레벨 클래스 정의를 읽어들이나 후보군에 오름
  4. Dessert.java에 기반해 다시 컴파되어 톱레벨 클래스 내 NAME 값이 정해졌으나 (siruddeok), 이는 기존 컴파일에서의 쓰이지 않은 후보(bottlejelly)가 실은 기존값이기에 휘발됨

실험에 추가적인 단계로 Utensil.java를 bagchocopie로 바꾸어 실행했을 때의 결과값은 여전히 bottlejelly였습니다. 이후 Dessert.java를 jeolpyeonddeok으로 바꾸고 실행했으나, 1~4의 단계와 마찬가지로 bagchocopie가 출력되었습니다. 자세한 작동과정은 접근할 수 없지만, 대략의 추측을 해보았습니다.

References

https://www.baeldung.com/javac-vs-eclipse-compiler https://en.wikipedia.org/wiki/Incremental_compiler

FickleBoBo commented 6 months ago

이클립스는 자체적인 컴파일러를 이용하는 줄은 전혀 모르고 있었는데, 앞으로 컴파일 과정에서 다른 결과가 나타난다면 테스트 과정이 동일했는지 확인하기 전에 어떤 환경(컴파일러)에서 컴파일 했는지를 먼저 확인해봐도 좋을 것 같다는 생각이 들었습니다.

증분 컴파일러라는 특징을 이해하고 첫 컴파일 과정과 이후 코드의 수정과정에서 컴파일되는 원리만 이해한다면 이번 아이템에 대해서도 좀 더 깊게 이해할 수 있을 것 같습니다. 저 역시 컴파일러별로 동작 과정에 대한 자세한 원리들에 대해서는 개념적인 참고자료를 찾지 못해서 그저 실험적으로 접근할 수 밖에 없었는데, 변수명을 바꿔가며 합리적인 추측과정을 찾아가주셔서 좀 더 원리를 추측해보는데 좋은 길잡이가 되었던 것 같습니다!!!