2011-11-30 16 views
9

In Guava 10+, Google deprecato Files.deleteDirectoryContents(). JavaDoc dicePerché Files.deleteDirectoryContents() è deprecato in Guava?

Obsoleto. Questo metodo presenta uno scarso riconoscimento del collegamento simbolico e condizioni di gara . Questa funzionalità può essere supportata adeguatamente solo da eseguendo il shelling su un comando del sistema operativo come rm -rf o del/s. Questo metodo è previsto per essere rimosso da Guava Guava nel rilasciare 11,0

Sono confuso sul perché v'è una condizione di competizione. Penso che avere questo metodo sia effettivamente utile e trovare il bombardamento verso il sistema operativo come una soluzione scadente. Gli autori possono condividere perché ha preso questa decisione?

+0

Per essere più chiari, penso che avere un problema di condizioni di gara non sia un grosso problema. Molte librerie, come 'ArrayList', non sono thread safe o hanno condizioni di gara. Anche 'File.remove' ha lo stesso problema. Ma sono tutti documentati. Quindi speravo di sentire una risposta oltre a ciò che la documentazione già dice sul motivo per cui hanno scelto di renderlo deprecato. –

+1

La differenza tra questa condizione di competizione e le classi tipiche non thread-safe è che non esiste una "correzione" per questo. Al contrario, è possibile risolvere i problemi di sicurezza del thread Java con classi non thread-safe mediante la sincronizzazione su un oggetto lock. Un metodo che semplicemente non può fare ciò che le persone si aspettano che faccia è un metodo sbagliato. –

+0

Questo è un buon punto. Grazie. –

risposta

5

Sono confuso sul motivo per cui esiste una condizione di gara.

Per esempio, supponiamo che un thread chiama Files.deleteDirectoryContents() e un secondo thread (o un processo esterno) crea contemporaneamente un nuovo file nella directory.

Quando si ritorna dalla chiamata, si può fare affidamento sulla directory vuota? No!

Ad ogni modo, se trovi utile la funzionalità di questo metodo ... nonostante i suoi difetti ... sei libero di prendere una copia del codice, modificarlo e incorporarlo nella tua applicazione. (Basta controllare la licenza del codice sorgente di Guava e assicurarsi di essere conforme.)

Gli autori possono condividere perché ha preso questa decisione?

Penso che abbiano già; vedere l'avviso di ritiro. Se vuoi di più, prova a cercare il problema tracker e il gruppo di discussione di Guava. Potresti anche provare a chiedere educatamente al gruppo di discussione, anche se se il tuo programma è quello di cambiare idea, dubito che avrai successo.

+4

Lo stesso sarebbe vero per il bombardamento verso il sistema operativo, non sarebbe? – anders

+0

+1 Non sarebbe lo stesso essere il bombardamento del sistema operativo. Penso che se una libreria non è thread-safe allora dovrebbe essere documentata e fino allo sviluppatore per assicurarsi che lo usino correttamente. –

+0

@Stephen C, non sto cercando di cambiare la mente di nessun corpo. Sono sicuro che c'è una buona ragione per spiegare perché è deprecato. Ho solo pensato che forse c'era un problema oltre alle condizioni di gara che hanno costretto a farlo. Ma ci sono molte libs che hanno condizioni di gara. Ho pensato che forse ci sarebbe stata una ragione migliore. –

5

La condizione di competizione è potenzialmente peggiore di "la directory potrebbe non essere vuota" e ciò è in parte dovuto al rilevamento di collegamenti simbolici. Considerate questo frammento di codice:

// Symbolic links will have different canonical and absolute paths 
if (!directory.getCanonicalPath().equals(directory.getAbsolutePath())) { 
    return; 
} 
... delete its contents ... 

Se directory è una directory pianura durante il controllo, ma un link simbolico a / dopo, deleteDirectoryContents sarà lieto di cercare di cancellare l'intero file system.

Forse c'è una soluzione alternativa, ma non l'abbiamo trovata. E fare delle correzioni ad hoc per un potenziale bug di sicurezza è spaventoso.

1

Per ulteriori esempi di rilevamento di collegamenti simbolici interrotti, vedere these bugs filed by users.

In breve, è impossibile cancellare una directory a meno che non si fornisca il percorso canonico a quella directory. Se /tmp è un collegamento a /some/other/directory, deleteDirectoryContents non è possibile cancellare /tmp/mytempdirectory. Forse c'è anche una soluzione alternativa qui, ma abbiamo alzato le mani.

1

Sei serio? Si sta tentando di risolvere le operazioni di multithreading:

Ad esempio, si supponga che un thread richiami File.deleteDirectoryContents() e un secondo thread (o un processo esterno) crea contemporaneamente un nuovo file nella directory. Quando si ritorna dalla chiamata, si può fare affidamento sulla directory che è vuota? No!

E che dire di un altro processo nella directory ??? Non può essere risolto e non devi gestire le transazioni poiché semplicemente non è possibile. E l'argomento che qualcuno rende symlink per root in modo da cancellare tutto il filesystem - non dovrebbe accedere ai diritti del filesystem per gestirlo? E se stai eseguendo un'operazione come root, dovresti sapere cosa stai facendo. Che dire di disabilitare la cancellazione di file nel filesystem, è pericoloso !!! Userò una libreria diversa se gli autori di Guava risolvono questi problemi idioti.

Problemi correlati