2009-10-15 24 views
12

tengo tres módulos en mi proyecto Maven (esto es ligeramente simplificado):¿Por qué una dependencia con alcance "provisto" oculta dependencias transitivas en Maven?

  • modelo contiene APP anotado clases de entidad
  • persistencia instancia un EntityManager y llama a los métodos en él
  • aplicación crea instancias de las clases en modelo, establece algunos valores y los pasa a persistencia

modelo y persistencia dependen obviamente en javax.persistence, pero de aplicación no debe, creo.

La dependencia javax.persistence se mueve a la sección dependencyManagement de un POM de nivel superior porque se produce en una serie de submódulos en los que solo hago referencia a esa entrada.

Lo que me sorprende es que tengo que hacer referencia a la dependencia en application cuando establezco su alcance en provided, mientras que no es necesario cuando su alcance es compile.

Con un alcance de provided, si no incluirla en la dependencies para la aplicación , la generación falla con un mensaje de error de javac:

com.sun.tools.javac.code .Symbol $ CompletionFailure: archivo de clase para javax.persistence.InheritanceType no encontrado

¿Qué está pasando?

+0

Lo sentimos pero este título es engañoso. No hay nada de malo en el alcance 'provisto' y las dependencias transitivas, no rompe nada. –

+0

@Pascal - No, no hay nada * incorrecto * con él, pero usar 'provided' hace que" se rompa "(o más bien, se apague) la resolución transitiva, como han señalado usted y james correctamente. –

+0

@Hanno No, no es así. El alcance afecta las dependencias transitivas pero no las rompe. –

Respuesta

12

modelo y persistencia, obviamente, depende de javax.persistence, pero la aplicación no debe , Creo.

Eso es cierto. Pero la resolución de dependencias transitivas no tiene nada que ver con su problema (y en realidad, javax.persistence es provided a model y persistence en el que application depende de un alcance compile por lo que se omite como se documentó en 3.4.4. Transitive Dependencies).

En mi opinión, que son víctimas de este error: http://bugs.sun.com/view_bug.do?bug_id=6550655

tengo los mismos problemas con un entidad EJB3 que utiliza la anotación Herencia: @Inheritance(strategy=InheritanceType.SINGLE_TABLE)

Una clase de cliente usando esta entidad no compilará cuando las annataciones ejb3 sean no en classpath, pero se bloquee con el siguiente mensaje: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.persistence.InheritanceType not found

[...]

Tenga en cuenta que se trata de un caso especial de error 6365854 (que se informa que se ha solucionado); el problema aquí parece ser que la anotación usa una enumeración como su valor.

La solución actual es agregar el enum faltante al CLASSPATH.

En su caso, la forma "menos peor" de hacer eso sería agregar javax.persistence como dependencia provided al módulo application. Pero eso es una solución al error de JVM, application no debería necesitar esa dependencia para compilarse.

+0

¿De verdad está seguro de que mi problema no es que no leí el manual de Maven correctamente? Tal vez hay un error en que el mensaje de error debe ser diferente, pero en cualquier caso, los archivos de clase requeridos están ocultos porque Maven * intencionalmente * no los incluye en la ruta de la clase. –

+1

Mi punto es que no necesita 'javax.persistence. *' Para compilar el módulo de la aplicación y no debería tener un error de compilación. –

+0

Bueno, estoy confundido. :) Tienes razón en que no debería obtener el error de compilación, supongo. Al menos eso sería mi instinto. Pero tendré que pensar un poco más acerca de cómo se afectan mis ámbitos entre sí, y si realmente asimilé la tabla a la que se vinculó. –

1

La sección dependencyManagement declara lo dependencias se verá como si los usa, no es que se usarlos. Por lo tanto, aún necesita declarar una declaración de dependencia mínima para aplicar la configuración en su proyecto hijo. Vea el dependency management section del libro de Maven para más detalles.

El mínimo requerido suele ser groupId y artifactId.

Si desea heredar la configuración sin declarar en absoluto, debe definirlo en la sección de los padres en lugar de dependenciesdependencyManagement

+0

Sí, lo sé. Lo que me pregunto es, ¿por qué el módulo depende de 'javax.persistence' en absoluto, cuando en realidad es solo una dependencia transitiva que debe ser resuelta por Maven? Trataré de aclarar mi publicación un poco. –

+0

@Hanno No, no debería. Ver mi respuesta –

2

umm, porque las dependencias proporcionadas no son transitivas? eso es comportamiento integrado para maven.

+0

umm - tienes razón. duh. –

+1

Eso no es del todo exacto. Si 'project-a' contiene una dependencia de ámbito proporcionada en' project-b' que contiene una dependencia de ámbito proporcionada en 'project-c',' project-c' sería una dependencia transitiva con alcance provisto de 'project-a'. Nuevamente, vea http://www.sonatype.com/books/maven-book/reference/pom-relationships-sect-transitive.html#pom-relationships-sect-transitive-scope –

+0

@Pascal - wow, aprende algo nuevo ¡cada día! Sin embargo, creo que nunca antes me he encontrado con esa pequeña pepita en un proyecto real. – james

Cuestiones relacionadas