2014-04-17 13 views
5

Questa particolare domanda è stata posta alcune volte, ma non del tutto soddisfacente. Non sono molto interessato ai workaround proposti, ma come fare ciò che voglio realmente fare.Impostazione ANT CLASSPATH in build.xml

Vorrei una spiegazione soddisfacente del motivo per cui questo non è possibile se non lo è, e dal momento che proporrei di presentare una correzione per questo me stesso mi piacerebbe capire perché qualcosa che sembra così semplice non ha stato tentato.

Attualmente, al fine di garantire che una serie di vasi sono a disposizione di formica, deve essere applicato uno dei seguenti approcci:

  • aggiungi al CLASSPATH variabile d'ambiente - "non raccomandato" nella documentazione
  • aggiungi a $ANT_HOME/lib o ~/.ant/lib - richiede la configurazione in ambiente di generazione
  • impostato -lib parametro ant invocazione

L'opzione finale è quella che ho scelto come preferita, ma richiede comunque un intervento da parte della persona che invoca la build (che ho catturato all'interno di uno script wrapper ant nel mio repository di sviluppo).

In particolare sto cercando di richiamare il compito Schematron Ant che dovrebbe essere istituito in base alla the documentation in questo modo:

<taskdef name="schematron" 
classname="com.schematron.ant.SchematronTask" 
classpath="lib/ant-schematron.jar"/> 

tuttavia questo ha una dipendenza transitiva su saxon, quindi senza un saxon.jar disponibili sul CLASSPATH, la compilazione fallisce:

java.lang.NoClassDefFoundError: net/sf/saxon/TransformerFactoryImpl 

la ant documentation itself continua a suggerire che dovrebbe essere la stessa che prende taskdef questi ulteriore CLASSPATH voci, ma ho provato questo con il formica di schematron senza alcun risultato.

Le domande chiave sono se deve essere un'operazione schematron ant che dovrebbe supportare questo, o dovrebbe essere possibile che form.xml di ant abbia il suo classpath globale configurato all'interno di se stesso?

sembra come se questo è qualcosa che la gente vorrebbe fare molto spesso, e dal momento che la documentazione formica si consiglia non utilizza CLASSPATH stessi Mi sorprende che non c'è alternativa all'interno build.xml sé!

risposta

1

Questo sembra essere un bug nel task Schematron. Il modo in cui l'attività Ant carica il processore XSLT Saxon richiederebbe Saxon sul classpath di sistema anche se l'attività stessa è su un classloader sussidiario.

A prima vista this code in ValidatorFactory sembra abbastanza ragionevole:

private TransformerFactory _factory = TransformerFactoryImpl.newInstance(); 

(dove TransformerFactoryImpl è la realizzazione di sassone di TransformerFactory), ma in realtà TransformerFactoryImpl non definisce un metodo di newInstance() propria quindi questo è il ereditato newInstance da TransformerFactory, che cercherà uno stabilimento appropriato in base al valore della proprietà di sistema javax.xml.transform.TransformerFactory.Il compito Ant does set this system property:

System.setProperty("javax.xml.transform.TransformerFactory", 
     "net.sf.saxon.TransformerFactoryImpl"); 

ma TransformerFactory.newInstance() cercherà questa classe sul sistema di caricamento classe, non necessariamente il programma di caricamento classe che ha caricato il compito Schematron.

La correzione sarebbe quello di cambiare ValidatorFactory linea 120 semplicemente

private TransformerFactory _factory = new TransformerFactoryImpl(); 

che bypassare tutta la ricerca dinamica e istanziare direttamente la classe corretta. Con questa correzione sul posto

<taskdef name="schematron" 
classname="com.schematron.ant.SchematronTask" 
classpath="lib/ant-schematron.jar:lib/saxon9he.jar"/> 

funzionava correttamente.

Ti suggerisco di segnalare il bug agli sviluppatori, ma il progetto non sembra particolarmente attivo, quindi potresti semplicemente dover costruire il tuo fork locale invece ...

Problemi correlati