Domanda

Sembra che ognuno ha avuto una spazzola di sgradevole con la rel Java Service Provider , che cosa si può fare con un file denominato come META-INF / services / com.example.Interface, ma che nessuno usi tranne che per cercare di caricare il destro parser XML. Sto cercando di lavorare con una libreria che utilizza l'API Service Provider, e trucco in modo che posso fornire alcune classi di runtime-estesa (utilizzando cglib) che in realtà non implementano l'interfaccia, ma può essere fatto per farlo facilmente.

In sostanza, credo che i passi che devo svolgere sono:

  1. Crea un caricatore di classe personalizzata che risponda alle getResources (...) e restituire un URL
  2. "extra"
  3. hanno inoltre che getResourceAsStream gancio class loader (...) per restituire un elenco delle classi che sto per manipolare con cglib, quando gli viene chiesto per la risorsa "extra"
  4. Infine, ha quel carico class loader quelle classi quando richiesto

Ma qui è dove mi perdo. Ad esempio, quando i tentativi di libreria per determinare quali esecutori sono là fuori, si chiama getResources (...), che restituisce un gruppo di URL. Ma getResourceAsStream (...) non prende gli URL, ci vuole "nomi". I nomi che sembrano essere classpath-relativa, e quindi la stessa ovunque. Così META-INF / services / com.example.Interface in ha lo stesso "nome" come META-INF / services / com.example.Interface nella loro JAR, giusto? Tranne in qualche modo questo funziona con quelli sabbiata parser XML ...

Naturalmente, tutto questo presuppone che erano intelligenti / così gentile da chiamare ClassLoader.getSystemClassLoader () piuttosto che utilizzare ClassLoader.getSystemResources (...), ClassLoader.getSystemResourceAsStream (...), ecc, come nel quest'ultimo caso non c'è modo per agganciare il ClassLoader e fornire il file contraffatto.

Credo che in quel caso potrei usare BCEL per manipolare i file di classe quando il mio codice è stato confezionato da Maven, piuttosto che aspettare fino al runtime di farlo con cglib?

È stato utile?

Soluzione

L'idea che ho descritto era lungo la strada giusta. L'errore che ho fatto è stato nel pensare che l'uso ClassLoader.getResourceAsStream(..) per accedere ai contenuti delle URL. Invece, si dovrebbe solo URL.openStream().

Se avessi trovato prima di pubblicare, java.util.ServiceLoader (@SINCE 1.6) fornisce alcune informazioni sul come fare le cose correttamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top