app 수준의 build.gradle 하단에 다음 명령어를 추가해주면 에러가 발생하지 않음
// prepareKotlinBuildScriptModel라는 이름의 empty task 등록
tasks.register("prepareKotlinBuildScriptModel"){}
하지만 나는 왜 이 empty task를 추가해주어야 하는지 이해할 수가 없었다. 구글링 및 gradle 문서를 찾아봐도 이 오류를 해결하려면 저 코드를 추가하세요 라는 답만 보일 뿐 prepareKotlinBuildScriptModel이 무엇을 의미하는지 찾을 수 없었다.
계속 구글링 한 결과, 이 오류에 대한 대답에 가장 가까운 답변을 찾을 수 있었다.
Gradle issue #14889 : prepareKotlinBuildScriptModel Task fails in a Java project
I now open the root project instead of the child project. We use gradle subprojects. It seems that how Intellij handles subprojects have changed slightly. Previously I was forced to open the subprojects separately to get stuff to work. Now I have to open the parent project. If I open the subproject I still get this error.
일단 내가 클론했던 프로젝트는 일반 안드로이드 프로젝트와 다를 것 없이 root 프로젝트 하위에 app 모듈이 있는 구조이다. 여기서 나는 root 프로젝트를 오픈하지 않고 app 모듈을 오픈한 후 프로젝트를 실행하려 했다. 위 댓글에서 언급한 대로, app 모듈 말고 root 프로젝트를 오픈하니 해당 오류는 발생하지 않았다.
It seems that how Intellij handles subprojects have changed slightly. Previously I was forced to open the subprojects separately to get stuff to work.
root 프로젝트를 열어야 빌드가 제대로 되게끔 설정한 것 같은데.. 궁금해서 Gradle Github를 한번 뒤적거려봤다.
https://github.com/gradle/gradle
찾아보니 prepareKotlinBuildScriptModel
에 대해서는 다음과 같이 정의가 되어 있고, 이 작업을 어떤 클래스에서 실행해주는지는 파악하지 못했다(나는 gradle 전문가도 아니고, 해당 깃허브 프로젝트의 규모가 상당하기 때문에..😅 일단 단순 검색으로는 찾을 수 없었다).
+ prepareKotlinBuildScriptModel
| Type: org.gradle.api.DefaultTask
| Value: task ':prepareKotlinBuildScriptModel'
| Creator: Project.<init>.tasks.prepareKotlinBuildScriptModel()
| Rules:
⤷ copyToTaskContainer
그리고 KotlinDslScriptsModel.java에서 다음과 같이 특정 구문이 주석처리되어 있는 것을 발견할 수 있었다.
/**
* Editor model for a set of Kotlin DSL scripts.
*
* Can only be requested on the root project, the builder will throw otherwise.
*
* Requires the <code>prepareKotlinBuildScriptModel</code> task to be executed before building the model.
* See {@link KotlinDslModelsParameters#PREPARATION_TASK_NAME}
*
*/
public interface KotlinDslScriptsModel {
/**
* Gradle property name for the set of scripts to be queried for.
*/
String SCRIPTS_GRADLE_PROPERTY_NAME = "org.gradle.tooling.model.kotlin.dsl.scripts";
/**
* Script models by file.
*/
Map<File, KotlinDslScriptModel> getScriptModels();
}
Can only be requested on the root project, the builder will throw otherwise. Requires the
prepareKotlinBuildScriptModel
task to be executed before building the model.
해당 모델은 루트 프로젝트에서만 요구되며, 그렇지 않으면 exception이 발생합니다. 이 모델이 빌드되기 전에, prepareKotlinBuildScriptModel이 실행되어야 합니다.
위 주석 내용에 따라, prepareKotlinBuildScriptModel라는 작업이 루트 프로젝트에서 무조건 실행되도록 Gradle 측에서 정의한 것이 아닐까 싶다. 확실하지 않지만, 이 부분을 고려해서 생각해보면 이 오류의 원인을 어느정도 파악할 수 있을 것 같다.