Gradle: ¿Cuál es la diferencia entre classpath y compilar dependencias?

92

Al agregar dependencias a mi proyecto, nunca estoy seguro de qué prefijo debo darles, por ejemplo, "classpath"o"compile".

Por ejemplo, ¿mis dependencias a continuación deberían ser tiempo de compilación o classpath?

Además, ¿debería estar esto en mi aplicación build.gradle o en el módulo build.gradle específico?

Build.gradle actual (a nivel de aplicación):

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.hibernate:hibernate-core:5.0.5.Final'
    compile 'mysql:mysql-connector-java:5.1.38'
} 
java123999
fuente
1
No estoy seguro de entender. classpathno es un ámbito de dependencia válido.
Tunaki
Quizás me estoy confundiendo, ¿cuáles son los ámbitos de dependencia válidos?
java123999
Eche un vistazo a este documento: docs.gradle.org/current/userguide/…
Tunaki
Una cosa que noté es que las compileOnlydependencias van a project.configurations.compileClasspathpero no a project.configurations.compile, como se menciona aquí github.com/iboyko/gradle-plugins/issues/5
Vytenis Bivainis

Respuestas:

47

Supongo que estás haciendo referencia compiley classpathdentro del dependencies {}bloque. Si es así, esas son configuraciones de dependencia .

Una configuración es simplemente un conjunto de dependencias con nombre.

La compileconfiguración la crea el complemento de Java. La classpathconfiguración se ve comúnmente en el buildSrc {}bloque donde se necesita declarar dependencias para build.gradle, en sí mismo (para complementos, quizás).

Eric Wendelin
fuente
Gracias, así que para mi build.gradle principal no debería necesitar usar classpath?
java123999
@ java123999 No, a menos que utilice complementos personalizados
Eric Wendelin
@EricWendelin Cuando dices "dentro del bloque {} de dependencias", ¿quieres decir "dentro del bloque {dependencias {}} de buildscript"? (No estoy seguro, solo pregunto)
Paulo Merson
2
Un dependencies {}bloque puede declararse tanto dentro buildscript {}como fuera de él. Cuando está adentro, usa la classpathconfiguración de las dependencias necesarias para compilar el script de compilación.
Eric Wendelin
55

Si buildscript necesita algo para ejecutarse, use classpath .

Si su proyecto necesita algo para ejecutarse, use compile .

El buildscript{}bloque es para build.gradle en sí.

Para la construcción de varios proyectos, el archivo de construcción de nivel superior es para el proyecto raíz, el archivo de construcción específico es para el subproyecto (módulo).

Archivo de compilación de nivel superior donde puede agregar opciones de configuración comunes a todos los subproyectos / módulos.

No coloque las dependencias de su aplicación en el archivo de compilación de nivel superior, pertenecen a los archivos build.gradle del módulo individual

q ...
fuente
Para confirmar: ¿eso significa que proandroiddev.com/… debería usar a compiley no a classpath?
WillC
1
Pero, ¿por qué no colocar las dependencias de la aplicación en el archivo de nivel superior si el proyecto tiene solo un módulo, como las aplicaciones típicas de Android?
Harsha
18

Si lo entiendo correctamente, está confundiendo el Project.dependenciesbloque de secuencia de comandos con el Project.buildscript.dependenciesbloque de secuencia de comandos (como lo hice cuando llegué a esta pregunta).

Intentaré responder a esto con lo que encontré.

Creo que ya debería estar familiarizado con el Project.dependenciesbloque de script. En este bloque, declaramos las dependencias que requiere nuestro código fuente. Hay varias formas de declarar una dependencia que necesitamos para el proyecto. Consulte Tutorial de Gradle: tipos de dependencia . Solo mencionaré la parte que es más relevante para este problema:

compile 'org.hibernate:hibernate-core:5.0.5.Final'es una declaración de dependencia de módulo. La configuración de compilación (que ahora está desaprobada por la configuración de implementación) es simplemente una palabra clave para Implementation only dependencies.No es una palabra clave que describe qué tipo de dependencia es (por tipo aquí estoy siguiendo los tres tipos definidos en el tutorial, es decir, módulo, archivo y proyecto.)

En Gradle Tutorial: Organizing Build Logic dice:

Si su script de compilación necesita usar bibliotecas externas, puede agregarlas a la ruta de clases del script en el propio script de compilación. Usted hace esto usando el método buildscript (), pasando un cierre que declara el classpath del script de construcción.

Esta es la misma forma en que declara, por ejemplo, la ruta de clases de compilación de Java. Puede utilizar cualquiera de los tipos de dependencia descritos en Tipos de dependencia, excepto las dependencias del proyecto.

Habiendo declarado el classpath del script de construcción, puede usar las clases en su script de construcción como lo haría con cualquier otra clase en el classpath.

Espero que las cosas se le aclaren ahora.

Con classpath "com.android.tools.build:gradle:${Versions.android_gradle_plugin}"estamos configurando el classpathmétodo con el com.android.tools.build:gradle:${Versions.android_gradle_plugin}cual es una dependencia de módulo que es utilizada por el propio script de compilación en lugar de la fuente en su proyecto.

Por otro lado, compile 'org.hibernate:hibernate-core:5.0.5.Final'estamos declarando una dependencia de módulo requerida para su proyecto con la configuración de compilación .

tl; dr: El classpath, compiley implementationson todas las palabras clave que se pueden utilizar en contra de las dependencias en diferentes circunstancias. El primero se usa cuando desea pasar una dependencia al script de compilación, y el segundo es una de las configuraciones que puede querer declarar.

Teng-pao Yu
fuente
1
Buena respuesta. Debo agregar que no solo debemos mirar las palabras clave en sí mismas como lo que se explica muy bien anteriormente, sino que también debemos tomar en consideración el artefacto que se solicita porque las palabras clave por sí solas no definen el contexto completo. Por ejemplo, 'org.projectlombok:lombok:1.18.4'no tiene classpathasociación porque es un jar que solo se necesita durante el javactiempo de compilación, pero no durante el javatiempo de ejecución. Por lo tanto, el uso correcto es una interacción de las palabras clave definidas y el artefacto. Esto significa que se necesita un conocimiento a priori.
eigenfield