2011-09-29 17 views
9

Sono interessato all'utilizzo di alcune delle funzionalità NIO2 nell'SDK Java 7, se disponibile (in particolare, lo file system watchers), tuttavia non desidero compilare le mie classi per Java 7 ed escludere Java 6 runtimes. Principalmente perché voglio mantenere la compatibilità con Mac OS X, e anche perché non voglio costringere i miei utenti ad aggiornare.Utilizzo di Java 7 Funzioni di SDK in Java 6

È possibile? Qual'è il miglior modo di farlo? Qualche link o esempio?

Ecco alcuni modi che posso immaginare: compilare un file di classe con un compilatore diverso e caricarlo dinamicamente in base alla versione di Java? O forse usando la riflessione? O forse c'è solo un'impostazione del compilatore per Java 7 per generare classi compatibili con Java 6?

Sto cercando una soluzione che non si trasformi in un brutto pasticcio :), quindi idealmente posso scrivere due implementazioni di un'interfaccia, una utilizzando le nuove funzionalità e una senza, quindi selezionarne una dinamicamente invece di avere fare chiamate riflessive dappertutto.

+0

Dal momento che presumo che queste funzionalità inizino ad esistere in SE7, come pensi di essere in grado di compilare con una modalità di compatibilità SE6 e mantenerle? – KevinDTimm

+0

Quello che voglio fare è usarli solo quando il programma viene eseguito su un runtime di Java 7, e se non lo è. Si noti che sto parlando delle funzionalità di Java 7 SDK, non delle funzionalità del linguaggio. –

+0

Ci scusiamo, due basi di codice saranno necessarie (o, almeno, disporre di una base di gestione file separata per ogni ambiente e creare output separati per ogni versione in quanto il codice compilato nella versione X in genere non funziona in nessuna versione con numero inferiore) – KevinDTimm

risposta

9

Basta compilare con -target 1.6 e organizzare il codice in modo da poter individuare ClassNotFoundExceptions e NoClassDefFoundErrors in modo pulito attorno ai moduli che utilizzano 1.7. Magari caricarli con un caricatore di classi separato, ad esempio.

+0

Funziona, grazie! Ho configurato JDK 7 in Eclipse per occuparmi dell'evidenziazione della sintassi e l'ho creato con il target Java 6. Per le chiamate ai metodi che non esistono devi prendere l'errore NoSuchMethodError. –

+0

@Laurens @EJP. Non capisco, come potresti costruire il sorgente 1.7 con -target 1.6? Non ti darebbe questo: 'javac: source release 1.7 richiede target release 1.7' – Pacerier

+0

@Pacerier Il trucco è creare con source 1.6 invece di 1.7, e invoca semplicemente i metodi dall'SDK 1.7. Potrebbe essere necessaria qualche configurazione nel tuo editor per evitare che si lamenti e che il completamento del codice funzioni, ma altrimenti funziona. –

0

Per alcuni elementi aggiunti in Java 7, è possibile trovare jsr jar Java 6 che offrono la funzionalità. Non credo che questo sarà il caso per il File System Watcher comunque.

+0

Se in esecuzione su Java 6, non ho bisogno della funzionalità, è facoltativo per gli utenti che eseguono su Java 7. In questo caso particolare, probabilmente ripiega sul polling o sul comportamento di aggiornamento esplicito. –

+3

Considera JNotify –

0

In termini di osservatori di file system, prima di Java 7 ho utilizzato solo il polling delle proprietà di un file ogni pochi secondi circa per verificare che non fosse cambiato. Non è esattamente bello, ma praticamente non usa risorse apparenti e dal punto di vista di un utente finale sembra funzionare allo stesso modo.

Se cerchi una libreria più completa, controlla http://commons.apache.org/jci/commons-jci-fam/index.html - Credo che faccia qualcosa di simile, anche se non l'ho mai usato.

Specifica fonte 1.7 e 1.6 di destinazione sono abbastanza sicuro che non funziona, ho provato per un motivo diverso indietro un po 'e dalla memoria della JVM è lamentato bandiere incompatibili (la mia ipotesi è a causa della nuova invokedynamic in 7 .)

1

È possibile creare facilmente java 1.6 come indicato dal toolkit. Tuttavia, è necessario assicurarsi di non accedere accidentalmente a metodi che non esistono in java 6. Ciò causerà un'eccezione di runtime nel codice di produzione.

Se si utilizza Maven, è possibile utilizzare il plug-in maven-enforcer che si assicura che nessuna classe java 1.7 o le chiamate di metodo si introducano nel codice creato per 1.6.

Un esempio potrebbe essere il passaggio da Java 1.4 a 1.5. Stavo costruendo con 1.5 con un target di 1,4, e per sbaglio ho usato:

new BigDecimal(5); 

Questa compilato bene, e ha funzionato benissimo per me. Ma poiché il client stava ancora utilizzando 1.4, non è riuscito. Perché questo costruttore non esiste in 1.4. È stato introdotto nel 1.5.

Un'altra soluzione sarebbe quella di costruire un paio di giare, una con la nuova roba nio, una con le vecchie cose, e rilevare al momento dell'installazione se l'utente stava eseguendo o meno java 1.7. In tal caso, aggiungi il barattolo contenente l'implementazione appropriata.