2009-10-15 13 views
12

Ho tre moduli nel mio progetto Maven (questo è un po 'semplificata):Perché una dipendenza con scope "fornita" nasconde le dipendenze transitive in Maven?

  • modello contiene JPA annotato classi di entità
  • persistenza un'istanza di un EntityManager e chiama i metodi su di esso
  • applicazione crea istanze delle classi nel modello , imposta alcuni valori e li passa a persistenza

modello e persistenza ovviamente dipendono javax.persistence, ma applicazione non dovrebbe, penso.

La dipendenza javax.persistence viene spostata nella sezione dependencyManagement di POM di primo livello perché si verifica in un numero di sottomoduli in cui faccio riferimento solo a tale voce.

Ciò che mi sorprende è che devo fare riferimento alla dipendenza in application quando imposto il suo ambito su provided, mentre non devo quando il suo ambito è compile.

con un ambito di provided, se non elenco nel dependencies per applicazione, la costruzione fallisce con un messaggio di errore da javac:

com.sun.tools.javac.code .Symbol $ CompletionFailure: file di classe per javax.persistence.InheritanceType non trovato

Cosa sta succedendo?

+0

Mi dispiace ma questo titolo è fuorviante. Non c'è niente di sbagliato con lo scope e le dipendenze transitive fornite, non infrange nulla. –

+0

@Pascal - No non c'è niente * sbagliato * con esso, ma usando 'provided' fa" break "(o meglio, spegni) la risoluzione transitiva, come tu e james avete indicato correttamente. –

+0

@ Hanno No, non è così. L'ambito influenza le dipendenze transitive ma non lo infrange. –

risposta

12

modello e la persistenza, ovviamente, dipendono javax.persistence, ma l'applicazione non dovrebbe , Credo.

È vero. Ma la risoluzione delle dipendenze transitive non ha nulla a che fare con il tuo problema (e in realtà, javax.persistence è provided a model e persistence su cui application dipende da un ambito compile quindi viene omesso come documentato in 3.4.4. Transitive Dependencies).

A mio parere, si sono vittima di questo bug: http://bugs.sun.com/view_bug.do?bug_id=6550655

ho gli stessi problemi con un EJB3 entità che utilizza l'annotazione Ereditarietà: @Inheritance(strategy=InheritanceType.SINGLE_TABLE)

Una classe client che utilizza questa entità non sarà compilare quando le annotazioni ejb3 sono non sul classpath, ma si bloccherà con il seguente messaggio: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.persistence.InheritanceType not found

[...]

Nota che è un caso speciale di bug 6365854 (che è stato segnalato essere risolto); il problema qui sembra essere che l'annotazione sta usando un enum come valore.

L'attuale soluzione consiste nell'aggiungere l'enum mancante al CLASSPATH.

Nel tuo caso, il modo "meno peggio" per farlo sarebbe quello di aggiungere javax.persistence come dipendenza provided al modulo application. Ma questa è una soluzione al bug della JVM, application non dovrebbe aver bisogno di quella dipendenza per compilare.

+0

Sei proprio sicuro che il mio problema non sia che non ho letto correttamente il manuale di Maven? Forse c'è un bug nel fatto che il messaggio di errore dovrebbe essere diverso, ma in ogni caso, i file di classe richiesti sono nascosti perché Maven * intenzionalmente * non li include nel percorso della classe. –

+1

Il mio punto è che non è necessario 'javax.persistence. *' Per compilare il modulo dell'applicazione e non dovrebbe avere un errore di compilazione. –

+0

Beh, sono confuso. :) Hai ragione nel fatto che non dovrei ottenere l'errore di compilazione, immagino. Almeno quello sarebbe il mio istinto. Ma dovrò pensare un po 'di più a come i miei scopi si influenzano a vicenda, e se davvero abbia fatto un bernardo al tavolo a cui ti sei collegato. –

1

La sezione dependencyManagement dichiara quali dipendenze sarà simile se li usate, non che si sarà usarli. Quindi è ancora necessario dichiarare una dichiarazione di dipendenza minima per applicare la configurazione nel progetto figlio. Vedi il dependency management section del libro Maven per i dettagli.

Il minimo richiesto è in genere il groupId e l'artefatto.

Se si desidera ereditare la configurazione senza dichiararlo a tutti, si dovrebbe definire nella sezione del genitore dependencies piuttosto che dependencyManagement

+0

Sì, lo so. Quello che mi chiedo è, perché l'unico modulo dipende da 'javax.persistence', quando in realtà è solo una dipendenza transitiva che dovrebbe essere risolta da Maven? Proverò a chiarire un po 'il mio post. –

+0

@ Hanno No, non dovrebbe. Vedi la mia risposta. –

2

umm, perché le dipendenze fornite non sono transitive? questo è un comportamento integrato per Maven.

+0

umm: hai ragione. duh. –

+1

Questo non è assolutamente esatto. Se 'project-a' contiene una dipendenza scope fornita su' project-b' che contiene una dipendenza scope fornita su 'project-c',' project-c' sarebbe una dipendenza transitiva fornita da 'project-a'. Di nuovo, vedi http://www.sonatype.com/books/maven-book/reference/pom-relationships-sect-transitive.html#pom-relationships-sect-transitive-scope –

+0

@Pascal - wow, impari qualcosa di nuovo ogni giorno! Non credo di aver mai incontrato quella piccola pepita in un vero progetto prima, però. – james

Problemi correlati