下面这张图指出了Java应用程序的真实的执行过程。
Java的强制性规则有:
(1)private, protected, default, public 。这个都知道,是关系到可见性,是对应用程序中内存资源的保护。
(2)final的变量初始化后不能被改变
(3)变量要先初始化后使用
以及一些其他的规则,通过这些规则验证后,就生成class file,也就是常说的字节码文件。
类加载器也是一道坎,不是说你让它加载,它就加载的,它也是要进行验证的。
假如骇客写了一些java文件编译后放到classpath目录下,或者是将jdk中自带某些核心API反编译后进行某些修改,覆盖原有文件,这样对程序的危害可以极大的。所以类加载时,也是有必要进行检查的。
从这张图片可以看出在类加载器定义类的过程也会对字节码进行检查的,下面可以看一下ClassLoader中defineClass的过程:
protected final Class<?> defineClass(String name, byte[] b, int off, int len,
ProtectionDomain protectionDomain)
throws ClassFormatError
{
// 检查类加载器是否初始化
check();
// 形成为该类生成protectionDomain和codesource
protectionDomain = preDefineClass(name, protectionDomain);
Class c = null;
String source = defineClassSourceLocation(protectionDomain);
// 真实的定义Class的过程,这个方法是native的,字节码检查的过程也是这里进行的,这里是看不到的,也是不能让我们看到的,如果我们可见,就可以自定义,这样检查就形同虚设。
try {
c = defineClass1(name, b, off, len, protectionDomain, source);
} catch (ClassFormatError cfe) {
c = defineTransformedClass(name, b, off, len, protectionDomain, cfe, source);
}
// 完善证书等信息
postDefineClass(c, protectionDomain);
return c;
}
3.1 SecurityManager#checkPermission()
Java提供了安全模型,我们在程序中如何使用呢?
一般来说都是通过SecurityManager来完成的,使用方式为:
SecurityManager sm = getSecurityManager();
if (sm != null) {
// sm.checkPermission();
}
3.2 AccessController.doPrivileged()
有时我们还会在代码中看到使用AccessController.doPrivileged()方法的,这个又是做什么呢?
假设有下列一个应用场景:有一个ProtectionDomain的CodeSource是com目录,在它下面有三个目录:core,moduleA,web,在这个 ProtectionDomain中,对所有的文件都有read权限,只有web目录下的resource目录下的文件,可以有write权限。现在有一需求,要在core目录下的某个文件有write权限。
/com
|--core
|--moduleA
|--web
|--bean
|--service
|--dao
|--resource
我们的程序中肯定会这样写:new FileOutputStream(File file)。上面已经粘出来FileInputStream(File file)实现过程。也就是说检查对该文件有无读权限。那么对应的FileOutputStream中肯定也会有检查是否有写权限的过程。上面的描述中已经知道,对于core下没有写权限的,所以我们的需求是无法满足的。那怎么办呢?
AccessController.doPrivileged()就可以帮肋完成上述任务。
FileOutputStream fos=null;
String filepath=”./com/core/xx”;
fos=AccessController.doPrivileged(new PriviliegedAction(){
public FileOutputStream run(){
return new FileOutputStream(filepath);
}
});
if(fos!=null){
// xxxxxxxx
}
以上就是大多数的Java应用程序的执行过程,我们学习Java开发需要知其然的同时,知其所以然。动力节点在线正是这样一个致力于Java在线学习的免费学习网站,帮助我们奠定坚实的Java学习基础,弄懂Java中的各个原理,真正意义上成为一名合格的Java开发者。
提枪策马乘胜追击04-21 20:01
代码小兵92504-17 16:07
代码小兵98804-25 13:57
杨晶珍05-11 14:54