我阅读并发现System类下有一些函数作为getproperties,我们可以在其中检索属性,然后也可以使用setProperties()进行设置.
我得到的答案是,它不会工作.我自己没试过,但是,我正在接听电话.
只是为了澄清一下,如果这些setProperty()和getProperty()方法在运行时无法改变它们,那么为什么会这样.或者这仅适用于classpath属性?
如果有人可以提供他们真正有用的场景,我将不胜感激?
小智 13
您当然可以在任何时间设置所需的任何系统属性.问题是,它会产生什么影响吗?在类路径的情况下,答案是否定的.系统类加载器在启动序列的早期点初始化.它将类路径复制到自己的数据结构中,并且不再读取classpath属性.更改它不会影响系统中的任何内容.
原因可能是双重的.性能较差的原因.您可能需要为快速查找资源而构建某种数据结构,并且每次重新解析类路径可能效率低下.更重要的原因是安全性.您不希望流氓类更改您下面的类路径并加载另一个类的受损版本.
Dav*_*vis 13
即使您无法使用系统属性设置类路径(因为JVM在启动时读取系统属性一次),您仍然可以通过强制调用addURL类加载器的方法来更改类路径.请注意,下面的解决方案不考虑当前线程.因此,它可能在所有情况下都不准确.
Sun网站上以下代码的原始来源已被删除:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
该链接不再有效:http://forums.sun.com/thread.jspa?threadID = 300557
以下示例将/home/user/dev/java/app/build/com/package在运行时添加到类路径:
try {
ClassPathUpdater.add( "/home/user/dev/java/app/build/com/package/Filename.class" );
}
catch( Exception e ) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
Von*_*onC 10
System.setProperty可用于在程序开头设置一些安全性或协议处理程序.喜欢:
/*
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");
Run Code Online (Sandbox Code Playgroud)
或者使用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());
Run Code Online (Sandbox Code Playgroud)
但请注意,因为它会在运行时为同一个jvm 中运行的所有应用程序更改环境.
例如,如果一个应用程序需要使用saxon运行而另一个应用程序需要使用xalan并且都使用System.setProperty来设置transformerFactory,那么您将遇到麻烦
正如Monitored System.setProperty文章中所述,
System.setProperty()可能是一个邪恶的调用.
关于classpath属性,正如我在上一个问题中所说的那样,它不能像运行时那样容易地改变.
特别是,java System属性java.class.path用于在实例化JRE时构建链接链接,然后不重新读取.因此,您对该属性所做的更改实际上并不对现有虚拟机执行任何操作.