Frage

Ich bin was sich auf die Frage auf classpath programmatisch ändern.

Ich habe gelesen und fand heraus, dass es eine Funktion unter ist System Klasse als GetProperties wo wir die Eigenschaften abrufen können und dann kann es auch eingestellt setProperties () verwenden.

Die Antworten aber ich bekam, war, dass es nicht funktionieren. Ich habe das selbst nicht ausprobiert, aber ich den Anruf nehme.

Nur um zu klären, warum dann diese setProperty () und getProperty () Methoden gibt es, wenn sie es während der Laufzeit nicht ändern können. Oder ist die spezifisch für die Classpath Eigenschaft nur?

Ich werde es begrüßen, wenn jemand ein Szenario vorstellen kann, wo sie wirklich hilfreich sind?

War es hilfreich?

Lösung

Sie können natürlich auch alle Systemeigenschaften festlegen Sie an jedem Punkt der Zeit wollen. Die Frage ist, wird es keine Wirkung? Im Fall von Classpath ist die Antwort NEIN. Das System Class Loader ist in einem sehr frühen Punkt in der Startreihenfolge initialisiert. Er kopiert den Classpath in seine eigenen Datenstrukturen und die Classpath Eigenschaft wieder nicht lesen. Ändern sie nichts im System beeinflussen.

Der Grund hierfür kann zweifach sein. Der geringere Grund ist die Leistung. Unter Umständen müssen Sie irgendeine Art von Datenstruktur für die schnelle Suche nach Ressourcen aufgebaut haben, und wieder Parsen Classpath jedes Mal ineffizient sein kann. Der wichtigere Grund ist die Sicherheit. Sie wollen nicht ein Schelm Klasse unter Ihnen die Classpath ändern und kompromittiert Version einer anderen Klasse laden.

Andere Tipps

Ändern Classpath

Auch wenn Sie nicht die Classpath über die Systemeigenschaften können (weil die JVM-Systemeigenschaften liest einmal: beim Start), können Sie immer noch die Classpath ändern, indem gewaltsam die addURL Methode des Klassenladeprogramm aufgerufen wird. Beachten Sie, dass die Lösung unter nicht in Betracht zieht den aktuellen Thread. Folglich ist es vielleicht nicht in allen Situationen korrekt sein.

Beispiel Lösung

Die ursprüngliche Quelle auf der Website von Sun für den folgenden Code entfernt wurde:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;                   

import java.io.File;
import java.io.IOException;

import java.net.URL;
import java.net.URLClassLoader;

/**
 * Allows programs to modify the classpath during runtime.              
 */                                                                     
public class ClassPathUpdater {                                         
  /** Used to find the method signature. */                             
  private static final Class[] PARAMETERS = new Class[]{ URL.class };   

  /** Class containing the private addURL method. */
  private static final Class<?> CLASS_LOADER = URLClassLoader.class;

  /**
   * Adds a new path to the classloader. If the given string points to a file,
   * then that file's parent file (i.e., directory) is used as the
   * directory to add to the classpath. If the given string represents a
   * directory, then the directory is directly added to the classpath.
   *
   * @param s The directory to add to the classpath (or a file, which
   * will relegate to its directory).
   */
  public static void add( String s )
    throws IOException, NoSuchMethodException, IllegalAccessException,
           InvocationTargetException {
    add( new File( s ) );
  }

  /**
   * Adds a new path to the classloader. If the given file object is
   * a file, then its parent file (i.e., directory) is used as the directory
   * to add to the classpath. If the given string represents a directory,
   * then the directory it represents is added.
   *
   * @param f The directory (or enclosing directory if a file) to add to the
   * classpath.
   */
  public static void add( File f )
    throws IOException, NoSuchMethodException, IllegalAccessException,
           InvocationTargetException {
    f = f.isDirectory() ? f : f.getParentFile();
    add( f.toURI().toURL() );
  }

  /**
   * Adds a new path to the classloader. The class must point to a directory,
   * not a file.
   *
   * @param url The path to include when searching the classpath.
   */
  public static void add( URL url )
    throws IOException, NoSuchMethodException, IllegalAccessException,
           InvocationTargetException {
    Method method = CLASS_LOADER.getDeclaredMethod( "addURL", PARAMETERS );
    method.setAccessible( true );
    method.invoke( getClassLoader(), new Object[]{ url } );
  }

  private static URLClassLoader getClassLoader() {
    return (URLClassLoader)ClassLoader.getSystemClassLoader();
  }
}

Der Link funktioniert nicht mehr: http://forums.sun.com/thread .jspa? threadID = 300557

Beispiel Verwendung

Das folgende Beispiel /home/user/dev/java/app/build/com/package zu dem Classpath zur Laufzeit hinzufügen wird:

try {
  ClassPathUpdater.add( "/home/user/dev/java/app/build/com/package/Filename.class" );
}
catch( Exception e ) {
  e.printStackTrace();
}

System.setProperty kann verwendet werden, eine gewisse Sicherheit oder Protokollhandler zu Beginn eines Programms einzustellen. Wie:

/*
Add the URL handler to the handler property. This informs 
IBMJSSE what URL handler to use to handle the safkeyring 
support. In this case IBMJCE.
*/
System.setProperty("java.protocol.handler.pkgs", "com.ibm.crypto.provider");

oder für mit SSL :

System.setProperty("javax.net.ssl.keyStore", context.getRealPath(KEYSTORE));
System.setProperty("javax.net.ssl.keyStorePassword", "password");
System.setProperty("javax.net.ssl.trustStore", context.getRealPath(TRUSTSTORE));
System.setProperty("javax.net.debug", "ssl");
HttpClient httpClient = new HttpClient();
GetMethod httpGet = new GetMethod("https://something.com");
httpClient.executeMethod(httpGet);
return new String(httpGet.getResponseBody());

Aber Vorsicht, weil es die Umgebung zur Laufzeit ändert sich für ALLE Anwendungen in der gleichen JVM läuft .
Wenn zum Beispiel eine Anwendung muss mit Saxon und das andere mit xalan und beide nutzen System.setProperty ausführen, um die TransformerFactory setzen, dann werden Sie in Schwierigkeiten geraten

Wie gesagt in Wachte System.setProperty Artikel,
System.setProperty () kann ein böser Anruf sein.

  • Es ist 100% fade feindlich
  • Sie enthält super-globale Variablen
  • Es ist extrem schwierig zu debuggen, wenn diese Variablen auf mysteriöse Weise während der Laufzeit ändern

In Bezug auf die Classpath-Eigenschaft, wie sagte ich in einem früheren Frage , kann sie nicht einfach als Laufzeit geändert werden.

Insbesondere Java-Systemeigenschaft java.class.path verwendet wird, eine verknüpfte Verbindung aufzubauen, wenn die JRE instanziert wird, dann nicht wieder lesen . Daher ändert Sie auf die Eigenschaft machen nicht wirklich auf die vorhandenen virtuellen Maschine nichts tun.

Es gibt auch eine Art und Weise java.library.path im laufenden Betrieb zu ändern, das zu tun, nur tun:

System.setProperty( "java.library.path", newPath);
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null); // that's the key.

Wenn dieses private static Feld in Classloader-Klasse wird auf null gesetzt, auf nächsten Versuch native Bibliothek Classloader zu laden wieder den neuen Wert in java.library.path mit initialisiert werden.

Die Grundidee ist, dass getProperty() Programme / Code kann von außerhalb der JVM konfiguriert werden, Eigenschaften auf der Befehlszeile Passieren der java -Dfoo=bar Syntax.

Wie Sie ein bestimmtes Verhalten in anderen Softwarekomponenten (wie eine Protokollierungskomponente) in Situationen konfigurieren möchten, wo Sie keine Kontrolle über die Befehlszeile haben - man denke in einem Servlet-Container eingesetzt werden - setProperty() kommt in als handlicher Art und Weise programmatisch Einstellungen zu verändern, zB vor Ihrem Logging-Dienstprogramm instanziieren.

Das Problem, das durch das classpath Problem ausgestellt wird, ist, dass die Programme werden in der Regel nur solche Systemeigenschaften genau einmal gelesen, wenn sie zuerst initialisiert werden. So um den Classpath ändern, nachdem JVM-Start ändert nichts für dich selbst App, weil die JVM bereits initialisiert ist, und änderte einige Protokollierung Konfiguration, nachdem Sie bereits eine Logger-Instanz erhalten hat (oder was auch immer), wird in der Regel keine Auswirkungen entweder .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top