모듈을 쓰는 Java 프로젝트는 의존성을 두 번 적습니다. 빌드 스크립트는 어떤 아티팩트를 받아서 어느 경로에 둘지 말하고, module-info.java는 이 모듈이 어떤 모듈을 requires 하는지 말합니다. 두 목록이 일치하도록 강제하는 것은 없고, 실제로 어긋납니다.
실패 양상은 대칭이 아닙니다. requires에 적었는데 빌드가 공급하지 않는 모듈은 컴파일 시점에 분명한 메시지로 실패합니다. 빌드가 공급했는데 어떤 requires에도 없는 JAR는 그냥 내 모듈에서 읽을 수 없고, 컴파일러도 그렇게 알려 줍니다. 헷갈리는 쪽은 module-info.class가 없는 의존성입니다. 모듈 경로에 두면 자동 모듈이 되는데, 매니페스트에 Automatic-Module-Name 항목이 있으면 그 이름을, 없으면 JAR 파일 이름에서 유도한 이름을 씁니다. 파일 이름을 바꾸면 requires 줄이 가리키는 이름이 바뀔 수 있습니다.
같은 JAR를 클래스 경로에 두면 이름 없는 모듈로 들어가고, 이름 있는 모듈은 그것을 아예 의존 대상으로 선언할 수 없습니다.
그래서 저는 빌드 스크립트를 무엇이 존재하는지에 대한 기준으로 두고, module-info.java는 제가 손댈 수 있는 범위에 대한 선언으로 봅니다. 하는 일이 다릅니다. 플러그인 없이 둘을 서로 대조해 보는 분이 계십니까?
영어에서 번역·원문 보기A modular Java project describes its dependencies twice. The build script says which artifacts to download and put on a path. module-info.java says which modules this one requires. Nothing forces the two lists to match, and they drift.
The failure modes are not symmetric. A module in requires that the build never supplies fails at compile time with a clear message. A JAR the build supplies that no requires mentions is simply not readable from your module, and the compiler says so. The confusing case is a dependency with no module-info.class. On the module path it becomes an automatic module, named from its Automatic-Module-Name manifest entry if it has one and derived from the JAR filename if it doesn't. Rename the file and the name your requires line points at can change.
Put the same JAR on the class path and it lands in the unnamed module, which a named module can't depend on at all.
So the build script is my source of truth for what exists, and module-info.java is a statement of what I'm allowed to touch. Different jobs. Does anyone actually check one against the other without a plugin?