2009-10-15 9 views
12

Ich habe drei Module in meinem Maven-Projekt (das etwas vereinfacht):Warum versteckt eine Abhängigkeit mit dem Geltungsbereich "bereitgestellt" transitive Abhängigkeiten in Maven?

  • Modell enthält JPA Entitätsklassen kommentierten
  • Persistenz instanziiert ein EntityManager und ruft Methoden auf sie
  • Anwendung erstellt Instanzen der Klassen in Modell, setzt einige Werte und übergibt sie an Persistenz

Modell und Persistenz offensichtlich auf javax.persistence ab, sondern Anwendung nicht, glaube ich.

Die -Abhängigkeit wird in den Abschnitt dependencyManagement der obersten Ebene von POM verschoben, weil sie in einer Reihe von Submodulen auftritt, in denen ich nur diesen Eintrag referenziere.

Was mir überraschend ist, dass ich die Abhängigkeit in application verweisen, wenn ich ihren Anwendungsbereich auf provided gesetzt, während ich nicht haben, wenn ihr Umfang compile.

Mit einem Umfang von provided, wenn ich es nicht Liste der dependencies für Anwendung, schlägt die Build mit einer Fehlermeldung von javac:

com.sun.tools.javac.code .Symbol $ CompletionFailure: Klassendatei für javax.persistence.InheritanceType nicht gefunden

Was ist los?

+0

Es tut mir leid, aber dieser Titel ist irreführend. Es ist nichts falsch mit dem "bereitgestellten" Umfang und den transitiven Abhängigkeiten, es macht nichts kaputt. –

+0

@Pascal - Nein, es gibt nichts * Falsches * damit, aber mit 'zur Verfügung gestellt' wird die transitive Auflösung "gebrochen" (oder besser, ausgeschaltet), wie Sie und James richtig hingewiesen haben. –

+0

@Hanno Nein, tut es nicht. Scope beeinflusst transitive Abhängigkeiten, bricht sie jedoch nicht. –

Antwort

12

Modell und Ausdauer offensichtlich auf javax.persistence ab, sondern Anwendung sollte nicht , Ich denke.

Das stimmt. Aber transitive Abhängigkeiten Auflösung hat nichts mit Ihrem Problem zu tun (und tatsächlich ist provided zu model und persistence auf dem application hängt mit einem compile Bereich, so dass es weggelassen wird, wie in 3.4.4. Transitive Dependencies dokumentiert).

Meiner Meinung nach, Sie sind Opfer dieser Fehler: http://bugs.sun.com/view_bug.do?bug_id=6550655

Ich habe die gleichen Probleme mit einer EJB3 Entität, die die Vererbung Anmerkung verwendet: @Inheritance(strategy=InheritanceType.SINGLE_TABLE)

Eine Client-Klasse dieser Einheit mit wird nicht kompilieren, wenn die ejb3 Annatationen sind nicht auf dem Klassenpfad, sondern stürzt mit die folgende Meldung: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.persistence.InheritanceType not found

[...]

Beachten Sie, dass es sich um einen Spezialfall des Bugs 6365854 handelt (der behoben wurde); Das Problem scheint hier zu sein, dass die Anmerkung eine enum als Wert verwendet.

Die aktuelle Problemumgehung besteht darin, die fehlende Enum dem CLASSPATH hinzuzufügen.

In Ihrem Fall wäre die "weniger schlechte" Art zu tun, als provided Abhängigkeit zum application Modul hinzuzufügen. Aber das ist eine Problemumgehung für den JVM-Fehler, application sollte diese Abhängigkeit nicht zum Kompilieren benötigen.

+0

Sind Sie wirklich sicher, dass mein Problem nicht darin besteht, dass ich das Maven Handbuch nicht richtig gelesen habe? Vielleicht gibt es einen Fehler darin, dass die Fehlermeldung anders sein sollte, aber in jedem Fall sind die erforderlichen Klassendateien verborgen, weil Maven sie * absichtlich * nicht in den Klassenpfad aufnimmt. –

+1

Mein Punkt ist, dass Sie 'javax.persistence. *' Nicht benötigen, um das Anwendungsmodul zu kompilieren, und keinen Kompilierungsfehler haben sollte. –

+0

Nun, ich bin verwirrt. :) Du hast Recht, dass ich den Kompilierfehler nicht bekommen sollte, denke ich. Zumindest wäre das mein Bauchgefühl. Aber ich muss ein wenig mehr darüber nachdenken, wie meine Bereiche sich gegenseitig beeinflussen, und ob ich den Tisch, mit dem Sie verbunden sind, wirklich gemeistert habe. –

1

Der dependencyManagement Abschnitt erklärt, was Abhängigkeiten wie aussehen wird, wenn Sie sie verwenden, nicht, dass Sie wird sie verwenden. Daher müssen Sie noch eine minimale Abhängigkeitsdeklaration deklarieren, damit die Konfiguration in Ihrem untergeordneten Projekt angewendet wird. Siehe das dependency management section des Maven-Buches für Details.

Das erforderliche Minimum ist normalerweise die GroupId und die ArtifactId.

Wenn Sie die Konfiguration erben wollen, ohne es überhaupt zu erklären, sollten Sie es in den dependencies Abschnitt der Eltern definieren, anstatt dependencyManagement

+0

Ja, das weiß ich. Ich frage mich, warum ist das eine Modul überhaupt von 'javax.persistence 'abhängig, wenn es wirklich nur eine transitive Abhängigkeit ist, die von Maven gelöst werden sollte? Ich werde versuchen, meinen Beitrag ein wenig zu klären. –

+0

@Hanno Nein, sollte es nicht. Siehe meine Antwort. –

2

um, weil die angegebenen Abhängigkeiten nicht transitiv sind? das ist ein eingebautes Verhalten für Maven.

+0

umm - du hast Recht. Duh. –

+1

Das ist nicht absolut genau. Wenn "project-a" eine gegebene Bereichsabhängigkeit von "project-b" enthält, die eine gegebene Bereichsabhängigkeit von "project-c" enthält, wäre "project-c" eine transitorische Abhängigkeit von "project-a" im bereitgestellten Bereich. Siehe auch http://www.sonatype.com/books/maven-book/reference/pom-relations-sect-transitive.html#pom-relationship-sect-transitive-scope –

+0

@Pascal - wow, du lernst etwas Neues jeden Tag! Ich glaube nicht, dass ich jemals in einem konkreten Projekt auf dieses kleine Nugget gestoßen bin. – james

Verwandte Themen