2013-12-10 12 views
15

Mi chiedo come non sicuro l'uso è in realtà sun.misc.Unsafe. Voglio creare un proxy di un oggetto in cui intercetto la chiamata al metodo ogni (ma quella a Object.finalize per considerazioni sulle prestazioni). A tal fine, ho cercato su google un po 'litle e si avvicinò con il seguente frammento di codice:Quanto è pericoloso l'uso di sun.misc.Unsafe in realtà?

class MyClass { 
    private final String value; 
    MyClass() { 
    this.value = "called"; 
    } 
    public void print() { 
    System.out.println(value); 
    } 
} 

@org.junit.Test 
public void testConstructorTrespassing() throws Exception { 
    @SuppressWarnings("unchecked") 
    Constructor<MyClass> constructor = ReflectionFactory.getReflectionFactory() 
     .newConstructorForSerialization(MyClass.class, Object.class.getConstructor()); 
    constructor.setAccessible(true); 
    assertNull(constructor.newInstance().print()); 
} 

La mia considerazione è:

  • Anche se Java è pubblicizzato come Write once, run ovunque mia realtà come sviluppatore sembra un po 'come write once, run una volta in ambiente di runtime di un cliente controllabile
  • sun.misc.Unsafe è considered to become part of the public API in Java 9
  • Molte macchine virtuali non Oracle offrono anche sun.misc.Unsafe poiché - immagino - ci sono quite some libraries already use it. Questo rende anche improbabile che la classe scompaia
  • Non eseguirò mai l'applicazione su Android, quindi questo non ha importanza per me.
  • Quante persone utilizzano effettivamente VM non Oracle?

Mi chiedo ancora: ci sono altri motivi per cui non dovrei usare sun.misc.Unsafe a cui non avevo pensato? Se fai queste domande a Google, le persone preferiscono rispondere a un non specificato perché non è sicuro ma non credo che sia oltre alla possibilità (molto improbabile) che il metodo scompaia un giorno dalla Oracle VM.

In realtà ho bisogno di creare un oggetto senza chiamare un costruttore per superare il sistema di tipi di Java. Non sto considerando sun.misc.Unsafe per performance reasons.

Informazioni aggiuntive: Sto usando ReflectionFactory nell'esempio per convenienza che delega al Unsafe alla fine. Conosco librerie come objenesis ma guardando il codice ho scoperto che fondamentalmente fanno qualcosa di simile ma controlliamo altri modi quando uso le versioni di Java che comunque non funzionerebbero per me quindi suppongo che scrivere quattro righe valga la pena di salvare una dipendenza.

+0

Nota: se diventa un'API pubblica in Java 9, non sarà sicuramente nel pacchetto 'com.sun'. – Jesper

+0

Ricorda che non ti sarà consentito utilizzare Unsafe su sistemi in cui non disponi di un'autorizzazione sufficiente. –

+0

Entrambi sono vere. Ciao, tutti i diritti di cui hai bisogno sono il diritto di leggere i campi privati ​​per riflessione. Questo è un requisito abbastanza comune per molte librerie. –

risposta

7

Ci sono tre significativi (IMO) problemi:

  • I metodi della classe Unsafe hanno la capacità di violare la sicurezza di tipo runtime, e fare altre cose che possono portare alla vostra JVM "hard crash".

  • Praticamente qualsiasi cosa che si fa usando Unsafe potrebbe in teoria dipendere dai dettagli interni della JVM; cioè i dettagli di come la JVM fa le cose e rappresenta le cose. Questi possono essere dipendenti dalla piattaforma e possono cambiare da una versione di Java alla successiva.

  • I metodi in uso ... o anche il nome classe stesso ... potrebbero non essere gli stessi tra diverse versioni, piattaforme e fornitori.

IMO, questi costituiscono motivi validi per non farlo ... ma è una questione di opinione.

Ora se Unsafe diventa standardizzato/parte dell'API Java standard (ad esempio in Java 9), allora alcuni dei problemi precedenti sarebbero discutibili. Ma penso che il rischio di crash duri se commetti un errore rimarrà sempre.

3

Durante una sessione di JavaOne 2013 Mark Reinhold (l'architetto JDK) ha ricevuto una domanda: "quanto è sicuro utilizzare la classe Unsafe?". Ha risposto con una sorta di risposta sorprendente: "Credo che dovrebbe diventare un'API stabile. Ovviamente adeguatamente sorvegliato con controlli di sicurezza, ecc ..."

Quindi sembra che ci possa essere qualcosa come java.util.Unsafe per JDK9. Nel frattempo, l'uso della classe esistente è relativamente sicuro (sicuro come fare qualcosa di non sicuro può essere).

+0

Questo è più di una semplice diceria: http://openjdk.5641.n7.nabble.com/Turn-sun-misc-Unsafe-into-a-public-API-td158365.html –

Problemi correlati