2011-02-10 11 views
12

ho utilizzato un sacco diGetPropertyAction vs System.getProperty nell'ottenere variabili di sistema

System.getProperty("property") 

al fine di ottenere informazioni ambientali. Tuttavia, mi sembra che Sun preferisce il seguente:

(String) java.security.AccessController.doPrivileged(
       new sun.security.action.GetPropertyAction("property")); 

La cosa strana è che questo codice comporta un cast e di conseguenza dovrebbe essere leggermente più lento rispetto l'attuazione

System.getProperty

, che utilizza solo un gestore della sicurezza e quindi preleva istantaneamente la proprietà dagli oggetti della variabile di istanza. La mia domanda è perché Sun ha scelto di utilizzare il secondo metodo per ottenere la maggior parte delle variabili ambientali nel loro codice interno, mentre

System.getProperty

sembra il modo più veloce per andare?

risposta

1

Si consiglia di attenersi a System.getProperty() poiché sun.security.action.GetPropertyAction sembra essere proprietario di SUN e non funzionerà su tutte le implementazioni VM Java. Anche il compilatore avverte su di esso come:

avvertimento: sun.security.action.GetPropertyAction è Sun API proprietarie e può essere rimosso in una versione futura

Per capire che cosa significa effettivamente vedere this answer.

+1

so cosa significa e so che non è consigliabile usarlo, soprattutto perché si tratta di un cast e la creazione di un nuovo oggetto. Tuttavia, quello che mi sono chiesto è perché Sun lo usi nelle loro implementazioni, invece che circonda System.getProperty in una chiamata privilegiata. –

8

Entrambi i metodi hanno un significato diverso e quindi è necessario utilizzare quello giusto in base a ciò che il codice corrente deve fare.

Il codice System.getProperty("property") dice "Dammi il valore della proprietà, se il contesto di sicurezza corrente mi consente di leggerlo."

Il codice che utilizza doPrivileged dice "Dammi il valore della proprietà, se la classe corrente (in cui è presente questa riga di codice) è autorizzata a leggerlo."

La differenza entra in gioco quando il dominio di protezione della classe corrente è diverso dal contesto di sicurezza attualmente attivo.

Ad esempio, si consideri un framework che esegue il codice di un plug-in, che non è affidabile. Quindi il framework utilizza un SecurityManager per limitare le azioni del codice del plugin non attendibile. Ma ovviamente il plugin può chiamare alcuni metodi del framework e supporre che uno di questi metodi abbia bisogno di leggere una proprietà. Ora, poiché il metodo è chiamato da codice limitato non attendibile, è esso stesso limitato e quindi la lettura della proprietà fallirebbe. Ma naturalmente il framework si fida di sé e vuole essere in grado di leggere quella proprietà, anche nel caso in cui da qualche parte nello stack di chiamate sia un codice non attendibile. Questo è quando è necessario utilizzare doPrivileged. In pratica dice "non importa cosa c'è lassù nello stack delle chiamate, sono un pezzo di codice framework e sono autorizzato a fare tutto ciò che il codice framework è autorizzato a fare". Quindi la lettura della proprietà utilizzando il secondo metodo ha esito positivo.

Ovviamente si deve fare attenzione quando si utilizza doPrivileged per non lasciare che il codice di chiamata (non affidabile) faccia troppo.Se, ad esempio, il codice del framework offre il seguente metodo per il plugin:

public String getProp(String key) { 
    return (String) java.security.AccessController.doPrivileged(
      new sun.security.action.GetPropertyAction(key)); 
} 

questo sarebbe totalmente invalida la politica che il codice non attendibile non è permesso di leggere le proprietà del sistema, perché può semplicemente utilizzare il metodo.

Quindi, utilizzare questo metodo solo quando si sa che è sicuro farlo e solo quando è necessario (ovvero, quando si desidera che il codice sia in grado di eseguire più di qualche altro codice dovrebbe essere in grado di eseguire direttamente). All'interno di una normale applicazione (che solitamente viene eseguita senza SecurityManager o lo stesso contesto di sicurezza per tutto il codice), non c'è alcuna differenza e il primo metodo dovrebbe essere usato.

-1

Il motivo per utilizzare una classe come sun.security.action.GetPropertyAction è di evitare il caricamento di classi diverse, fondamentalmente identiche.

se hai scritto:

(String) java.security.AccessController.doPrivileged(
    new java.security.PrivilegedAction<java.lang.String>() { 
     String run() { 
     System.getProperty("property"); 
     } 
    } 
); 

Ogni volta che si voleva ottenere una proprietà di sistema, si potrebbe caricare una nuova classe per ogni chiamata getProperty. Ogni classe prende risorse di sistema e vive finché contiene ClassLoader (per sempre per il bootclassloader).

Partenza l'uscita javap per maggiori dettagli:

javap -c -v -p sun.security.action.GetPropertyAction 
Problemi correlati