它的核心方法就是checkPerssiom这个方法里又调用,

使用Rserve远程执行R脚本,rserver脚本

注1:关于Rserve网上有很多资料可以参考,详细情况可以参考博客下面的“参考资料”部分,本文只是简单介绍一下Rserve,主要目的是记录一下Java远程执行R脚本文件的方法。
注2:这里提到的远程执行R脚本文件的方式都是R脚本存在于Rserve服务端,如果R脚本文件存在客户端,可以使用RUtils工具包:

Rserve介绍

    Rserve是一个基于TCP/IP协议的,允许R语言与其他语言通信的C/S结构的程序,支持C/C++,Java,PHP,Python,Ruby,Nodejs等。 Rserve提供远程连接,认证,文件传输等功能。我们可以设计R做为后台服务,处理统计建模,数据分析,绘图等的任务。
    详细介绍请参照官方网站:https://rforge.net/Rserve/

Rserve安装

Linux系统下建议使用root权限安装。下面的内容是依据Windows7系统中安装过程进行描述的。

进入R语言解释器:R

安装命令:install.packages(“Rserve”)

然后安装程序会提示我们选择下载镜像,提示如下:

— Please select a CRAN mirror for use in this session —

等我们选择了镜像后(测试时选择的是China(xxx)),安装程序便进行下载安装,最终会输出如下的信息(Linux下的输出信息或有不同):

说明Rserve安装成功,安装路径为:%R_HOME%libraryRserve目录。

启动Rserve服务

在Windows命令窗口进入R_HOMElibraryRservelibsi386目录中执行如下命令(我的Windows7是32位的,如果是64位系统对应目录为R_HOMElibraryRservelibsx64):

[plain] view plain copy
R CMD Rserve

R将作出如下应答:

说明Rserve启动成功(端口6311),可以进行连接测试了。

上面的启动命令使用的本地模式,如果想远程连接需要增加参数 –RS-enable-remote

即启动命令为:

[plain] view plain copy
R CMD Rserve –RS-enable-remote

Java远程连接Rserve

下载依赖jar包,地址:
共两个jar包,下载完成后将它们加入到项目的classpath中即可:
 REngine.jar
 RserveEngine.jar
也可以到Rserve安装目录中寻找,比如:R_HOME libraryRservejava目录中就有相关jar包,名字略有不同,经测试可以使用:

简单的测试代码:

[java] view plain copy
package com.zyh.up.general.rjava;

import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;

public class RserveBegin {
public static void main(String[] args) {
try {
callRserve();
} catch (RserveException e) {
e.printStackTrace();
} catch (REXPMismatchException e) {
e.printStackTrace();
}
}

static void callRserve() throws RserveException, REXPMismatchException {  
    RConnection rConnection = new RConnection("192.168.101.122");  

    String rv = rConnection.eval("R.version.string").asString();  
    System.out.println(rv);  

    double [] arr = rConnection.eval("rnorm(10)").asDoubles();  
    for(double d : arr) {  
        System.out.println(d);  
    }  
}  

}

测试可以通过,程序将输出R语言版本信息及10个Double类型的数字。

Java远程执行R脚本

上面的示例只是执行R命令,但如果我们在服务器上放置R脚本又该如何执行该脚本或调用其中的函数呢?

有两种方法可以完成上面的问题。

假如我们定义了一个R脚本area.R,其中定义了一个方法area,该方法接收一个半径值然后计算对应面积并返回,脚本内容非常简单:

[plain] view plain copy
area<-function(r){pi*r^2}

下面描述一下如何调用这个脚本中的area函数,并获取其返回值。
第一种方法就是直接用source函数将area.R脚本加载上来,然后就可以像调用R语言内置命令/函数一样调用脚本中的area方法了。这样做有一个缺点就是每建立一次Java与R之间的连接就需要调用source函数一次。
示例代码:

[java] view plain copy
package com.zyh.up.general.rjava;

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;

public class RserveBegin {
public static void main(String[] args) {
try {
callRScript();
} catch (Exception e) {
e.printStackTrace();
}
}

static void callRScript() throws RserveException, REXPMismatchException {  
    RConnection rc = new RConnection("192.168.101.122");  
    // source函数需要给出R脚本路径, 注意传入转义的引号  
    rc.eval("source("/home/hadoop/wangfeng/javaR/area.R")");  

    REXP rexp = rc.eval("area(10)");  
    System.out.println("Area of 10 is " + rexp.asDouble());  
}  

}

代码测试通过。
另一种调用R脚本的方法是通过Rserv.conf配置文件,该文件路径为/etc/Rserv.conf,如果文件不存在则创建一个新的,然后在文件中添加如下的代码:

[plain] view plain copy
source /home/hadoop/wangfeng/javaR/area.R

然后重新启动Rserve服务即可。
使用这种方式Java测试代码需要去掉source语句这一行,即:

[plain] view plain copy
rc.eval(“source(”/home/hadoop/wangfeng/javaR/area.R”)”);

其它不变,经测试成功。

注1:第二种方式只在Linux下采用,Win平台对应的方法没有找到。
另外:有些人说配置文件为Rserve.conf,但我在122的/etc下找到的是Rserv.conf,不管是哪一个文件(甚至两者都不是,随便命名一个),只要执行下面命令告诉Rserve配置文件是哪一个即可(需要重启Rserve):

[plain] view plain copy
R CMD Rserve –RS-conf Rserv.conf

参考资料




查看评论

注1:关于Rserve网上有很多资料可以参考,详细情况可以参考博客下面的“参考资料”部分,本文只是简...

拓展内容

import java.io.BufferedReader;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
import java.io.InputStream;  
import java.lang.reflect.AnnotatedType;  
import java.lang.reflect.Field;  
import java.sql.Date;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Iterator;  
import java.util.List;  
import java.util.Properties;  
import java.util.Scanner;  

import javax.xml.parsers.DocumentBuilder;  
import javax.xml.parsers.DocumentBuilderFactory;  
import javax.xml.parsers.ParserConfigurationException;  

import org.jdom.Document;  
import org.jdom.Element;  
import org.jdom.JDOMException;  
import org.jdom.input.SAXBuilder;  
import org.w3c.dom.Node;  
import org.w3c.dom.NodeList;  
import org.xml.sax.SAXException;  

import com.google.common.io.Files;  

public class RecoverObject<O> {  
    private String propertiesFile;  
    private String objectXmlFile;  
    private String recoverObjextXmlFile;  
    private String clazzName;  
    private Properties properties;  
    public RecoverObject(String propertiesFile, String objectXmlFile){  
        this.propertiesFile = propertiesFile;  
        this.objectXmlFile = objectXmlFile;  
        this.recoverObjextXmlFile = this.objectXmlFile+".recover";  

        this.properties = new Properties();  
        initObject();  
    }  
    private void processXmlFile(String context){  
        int pre = -1, s = -1, e = -1;  
        StringBuffer buffer = new StringBuffer();  
        while((s = context.indexOf("${", pre+1))!=-1){  
            e = context.indexOf("}", s + 2);  
            buffer.append(context.substring(pre+1, s));  
            String attr = context.substring(s+2, e);  
            buffer.append(this.properties.get(attr));  
            pre = e;  
        }  
        buffer.append(context.substring(pre+1));  
        try {  
            Files.write(buffer.toString().getBytes(), new File(this.recoverObjextXmlFile));  
        } catch (IOException e1) {  
            // TODO Auto-generated catch block  
            e1.printStackTrace();  
        }  

    }  
    private void initObject(){  
        FileInputStream in;  
        try {  
            in = new FileInputStream(new File(this.propertiesFile));  
            this.properties.load(in);  
            in.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }   
        StringBuffer buffer = new StringBuffer();  
        try {  
            Scanner scan = new Scanner(new FileInputStream(new File(this.objectXmlFile)));  
            while(scan.hasNextLine()){  
                buffer.append(scan.nextLine());  
                buffer.append("n");  
            }  
        } catch (FileNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        String context = buffer.toString();  
        this.processXmlFile(context);  

    }  

    public O get(){  
        SAXBuilder builder=new SAXBuilder(false);  
        Class<?> demo=null;  
        try {  
            Document doc=builder.build(this.recoverObjextXmlFile);  
            Element object=doc.getRootElement();  
            this.clazzName = object.getAttributeValue("class");  
            demo=Class.forName(this.clazzName);  
            O o = (O) demo.newInstance();  
            List propertiesList = object.getChildren("property");  
            for(Iterator iter = propertiesList.iterator(); iter.hasNext();){  
                Element attr = (Element) iter.next();  
                String attrName = attr.getAttributeValue("name");  
                String attrValue = attr.getChildText("value");  
                Field f= demo.getDeclaredField(attrName);  
                f.setAccessible(true);  
                Class<?> type = f.getType();  
                if(type.equals(String.class)){  
                    f.set(o, attrValue);  
                }else if(type.equals(int.class)){  
                    f.set(o, Integer.parseInt(attrValue));  
                }else if(type.equals(java.util.Date.class)){  
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
                    f.set(o, format.parse(attrValue));  
                }  

            }  
            return o;  
        } catch (JDOMException e) {  

            e.printStackTrace();  
        } catch (IOException e) {  

            e.printStackTrace();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (InstantiationException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (NoSuchFieldException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (SecurityException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalArgumentException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (ParseException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  

        return null;  
    }  
    public static void main(String [] args){  
        RecoverObject<Student> object = new RecoverObject<Student>("./source/object.properties2", "./source/object.xml");  
        Student s = object.get();  
        System.out.println(s);  
    }  
} 
  1. int getCount()   
  2. ViewPager里显示内容的条数.  
  1. package server;  
  2.   
  3. import java.rmi.RemoteException;  
  4. import java.rmi.server.UnicastRemoteObject;  
  5.   
  6. public class HelloImpl extends UnicastRemoteObject implements Hello {  
  7.     private static final long serialVersionUID = -271947229644133464L;  
  8.   
  9.     public HelloImpl() throws RemoteException{  
  10.         super();  
  11.     }  
  12.   
  13.     public String sayHello(String name) throws RemoteException {  
  14.         return "Hello,"+name;  
  15.     }  
  16. }  

 java之jvm学习笔记七(jar包的代码认证和签名)

代码实现:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <FrameLayout xmlns:android=""  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     >  
  6.       
  7.     <ImageView   
  8.         android:id="@+id/album_imgview"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="fill_parent"  
  11.         android:contentDescription="@string/app_name"  
  12.         android:scaleType="fitXY"  
  13.         />  
  14.       
  15.     <TextView  
  16.         android:id="@+id/album_name"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_height="wrap_content"  
  19.         android:layout_gravity="bottom|center_horizontal"   
  20.         android:textColor="#B2191919"  
  21.         />  
  22. </FrameLayout>  

 

[java] view plaincopy

 

[java] view plaincopy

PATH为java工具类路径(java,javac,rmic等)

  1. package com.yfq.test;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.IOException;  
  5.   
  6. public class TestMySecurityManager {  
  7.     public static void main(String[] args) {  
  8.         System.setSecurityManager(new MySecurityManager());  
  9.         try {  
  10.             FileInputStream fis = new FileInputStream("test");  
  11.             System.out.println(fis.read());  
  12.         } catch (IOException e) {  
  13.             e.printStackTrace();  
  14.         }  
  15.   
  16.     }  
  17. }  

 

下面就开始讲下ViewPager的用 法,ViewPager和ViewFlipper用法类似,但是更好用,左右滑动效果好,而且有类似于ListView的Adapter--- PagerAdapter基类,这样的话可以回收内存,复用等。PagerAdapter的几个方法里常用的有:

方式二:人工创建rmiregistry服务,需要在代码中添加:

                 前面我说过,看这篇文章是不需要你有密码学的知识的,是的,我骗你,至少基本的概念还是要理解过的。如果你完全不懂,不要慌,我举个简单的例子来帮你简单的理解一下一两个基本的概念。

  1. <object class="MyTest.MyTest.Week2.Student">  
  2.     <property name="name">  
  3.         <value>${name}</value>  
  4.     </property>  
  5.     <property name="age">  
  6.         <value>${age}</value>  
  7.     </property>  
  8.     <property name="birth">  
  9.         <value>${birth}</value>  
  10.     </property>  
  11. </object>  

[java] view plaincopy

 

  1.    public boolean setWritable(boolean writable, boolean ownerOnly) {  
  2. SecurityManager security = System.getSecurityManager();  
  3. if (security != null) {  
  4.     security.checkWrite(path);  
  5. }  
  6. return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);  
  7.    }  

 

  1. Object instantiateItem(View container, int position)  
  2. 始化ItemView.  

[plain] view plain copy

                 第一个概念对称加密,什么是对称加密?假设A想要说暗语,A想说5的时候就把5*3,然后把5*3的结果15告诉B,因为B知道A说暗语的规则,所以B就把15除以3,知道A要告诉自己5,这就是对称加密。

  1. import java.io.BufferedReader;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.lang.reflect.AnnotatedType;  
  8. import java.lang.reflect.Field;  
  9. import java.sql.Date;  
  10. import java.text.ParseException;  
  11. import java.text.SimpleDateFormat;  
  12. import java.util.Iterator;  
  13. import java.util.List;  
  14. import java.util.Properties;  
  15. import java.util.Scanner;  
  16.   
  17. import javax.xml.parsers.DocumentBuilder;  
  18. import javax.xml.parsers.DocumentBuilderFactory;  
  19. import javax.xml.parsers.ParserConfigurationException;  
  20.   
  21. import org.jdom.Document;  
  22. import org.jdom.Element;  
  23. import org.jdom.JDOMException;  
  24. import org.jdom.input.SAXBuilder;  
  25. import org.w3c.dom.Node;  
  26. import org.w3c.dom.NodeList;  
  27. import org.xml.sax.SAXException;  
  28.   
  29. import com.google.common.io.Files;  
  30.   
  31. public class RecoverObject<O> {  
  32.     private String propertiesFile;  
  33.     private String objectXmlFile;  
  34.     private String recoverObjextXmlFile;  
  35.     private String clazzName;  
  36.     private Properties properties;  
  37.     public RecoverObject(String propertiesFile, String objectXmlFile){  
  38.         this.propertiesFile = propertiesFile;  
  39.         this.objectXmlFile = objectXmlFile;  
  40.         this.recoverObjextXmlFile = this.objectXmlFile+".recover";  
  41.           
  42.         this.properties = new Properties();  
  43.         initObject();  
  44.     }  
  45.     private void processXmlFile(String context){  
  46.         int pre = -1, s = -1, e = -1;  
  47.         StringBuffer buffer = new StringBuffer();  
  48.         while((s = context.indexOf("${", pre+1))!=-1){  
  49.             e = context.indexOf("}", s + 2);  
  50.             buffer.append(context.substring(pre+1, s));  
  51.             String attr = context.substring(s+2, e);  
  52.             buffer.append(this.properties.get(attr));  
  53.             pre = e;  
  54.         }  
  55.         buffer.append(context.substring(pre+1));  
  56.         try {  
  57.             Files.write(buffer.toString().getBytes(), new File(this.recoverObjextXmlFile));  
  58.         } catch (IOException e1) {  
  59.             // TODO Auto-generated catch block  
  60.             e1.printStackTrace();  
  61.         }  
  62.           
  63.     }  
  64.     private void initObject(){  
  65.         FileInputStream in;  
  66.         try {  
  67.             in = new FileInputStream(new File(this.propertiesFile));  
  68.             this.properties.load(in);  
  69.             in.close();  
  70.         } catch (FileNotFoundException e) {  
  71.             e.printStackTrace();  
  72.         } catch (IOException e) {  
  73.             e.printStackTrace();  
  74.         }   
  75.         StringBuffer buffer = new StringBuffer();  
  76.         try {  
  77.             Scanner scan = new Scanner(new FileInputStream(new File(this.objectXmlFile)));  
  78.             while(scan.hasNextLine()){  
  79.                 buffer.append(scan.nextLine());  
  80.                 buffer.append("n");  
  81.             }  
  82.         } catch (FileNotFoundException e) {  
  83.             // TODO Auto-generated catch block  
  84.             e.printStackTrace();  
  85.         }  
  86.         String context = buffer.toString();  
  87.         this.processXmlFile(context);  
  88.           
  89.     }  
  90.       
  91.     public O get(){  
  92.         SAXBuilder builder=new SAXBuilder(false);  
  93.         Class<?> demo=null;  
  94.         try {  
  95.             Document doc=builder.build(this.recoverObjextXmlFile);  
  96.             Element object=doc.getRootElement();  
  97.             this.clazzName = object.getAttributeValue("class");  
  98.             demo=Class.forName(this.clazzName);  
  99.             O o = (O) demo.newInstance();  
  100.             List propertiesList = object.getChildren("property");  
  101.             for(Iterator iter = propertiesList.iterator(); iter.hasNext();){  
  102.                 Element attr = (Element) iter.next();  
  103.                 String attrName = attr.getAttributeValue("name");  
  104.                 String attrValue = attr.getChildText("value");  
  105.                 Field f= demo.getDeclaredField(attrName);  
  106.                 f.setAccessible(true);  
  107.                 Class<?> type = f.getType();  
  108.                 if(type.equals(String.class)){  
  109.                     f.set(o, attrValue);  
  110.                 }else if(type.equals(int.class)){  
  111.                     f.set(o, Integer.parseInt(attrValue));  
  112.                 }else if(type.equals(java.util.Date.class)){  
  113.                     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
  114.                     f.set(o, format.parse(attrValue));  
  115.                 }  
  116.                   
  117.             }  
  118.             return o;  
  119.         } catch (JDOMException e) {  
  120.               
  121.             e.printStackTrace();  
  122.         } catch (IOException e) {  
  123.               
  124.             e.printStackTrace();  
  125.         } catch (ClassNotFoundException e) {  
  126.             // TODO Auto-generated catch block  
  127.             e.printStackTrace();  
  128.         } catch (InstantiationException e) {  
  129.             // TODO Auto-generated catch block  
  130.             e.printStackTrace();  
  131.         } catch (IllegalAccessException e) {  
  132.             // TODO Auto-generated catch block  
  133.             e.printStackTrace();  
  134.         } catch (NoSuchFieldException e) {  
  135.             // TODO Auto-generated catch block  
  136.             e.printStackTrace();  
  137.         } catch (SecurityException e) {  
  138.             // TODO Auto-generated catch block  
  139.             e.printStackTrace();  
  140.         } catch (IllegalArgumentException e) {  
  141.             // TODO Auto-generated catch block  
  142.             e.printStackTrace();  
  143.         } catch (ParseException e) {  
  144.             // TODO Auto-generated catch block  
  145.             e.printStackTrace();  
  146.         }  
  147.           
  148.         return null;  
  149.     }  
  150.     public static void main(String [] args){  
  151.         RecoverObject<Student> object = new RecoverObject<Student>("./source/object.properties2", "./source/object.xml");  
  152.         Student s = object.get();  
  153.         System.out.println(s);  
  154.     }  
  155. }   
  1. package com.tutor.viewpager;  
  2.   
  3. import org.json.JSONException;  
  4. import org.json.JSONObject;  
  5.   
  6. import android.content.Context;  
  7. import android.graphics.Bitmap;  
  8. import android.util.AttributeSet;  
  9. import android.view.LayoutInflater;  
  10. import android.view.View;  
  11. import android.widget.FrameLayout;  
  12. import android.widget.ImageView;  
  13. import android.widget.TextView;  
  14.   
  15. /** 
  16.  * @author frankiewei 
  17.  * 相册的ItemView,自定义View.方便复用. 
  18.  */  
  19. public class ViewPagerItemView extends FrameLayout {  
  20.   
  21.     /** 
  22.      * 图片的ImageView. 
  23.      */  
  24.     private ImageView mAlbumImageView;  
  25.       
  26.     /** 
  27.      * 图片名字的TextView. 
  28.      */  
  29.     private TextView mALbumNameTextView;  
  30.       
  31.     /** 
  32.      * 图片的Bitmap. 
  33.      */  
  34.     private Bitmap mBitmap;  
  35.       
  36.     /** 
  37.      * 要显示图片的JSONOBject类. 
  38.      */  
  39.     private JSONObject mObject;  
  40.       
  41.       
  42.     public ViewPagerItemView(Context context){  
  43.         super(context);  
  44.         setupViews();  
  45.     }  
  46.       
  47.     public ViewPagerItemView(Context context, AttributeSet attrs) {  
  48.         super(context, attrs);  
  49.         setupViews();  
  50.     }  
  51.       
  52.     //初始化View.  
  53.     private void setupViews(){  
  54.         LayoutInflater inflater = LayoutInflater.from(getContext());  
  55.         View view = inflater.inflate(R.layout.viewpager_itemview, null);  
  56.           
  57.         mAlbumImageView = (ImageView)view.findViewById(R.id.album_imgview);  
  58.         mALbumNameTextView = (TextView)view.findViewById(R.id.album_name);   
  59.         addView(view);  
  60.     }  
  61.   
  62.     /** 
  63.      * 填充数据,共外部调用. 
  64.      * @param object 
  65.      */  
  66.     public void setData(JSONObject object){  
  67.         this.mObject = object;  
  68.         try {  
  69.             int resId = object.getInt("resid");  
  70.             String name = object.getString("name");  
  71.             //实战中如果图片耗时应该令其一个线程去拉图片异步,不然把UI线程卡死.  
  72.             mAlbumImageView.setImageResource(resId);  
  73.             mALbumNameTextView.setText(name);  
  74.         } catch (JSONException e) {  
  75.             e.printStackTrace();  
  76.         }  
  77.           
  78.     }  
  79.           
  80.     /** 
  81.      * 这里内存回收.外部调用. 
  82.      */  
  83.     public void recycle(){  
  84.         mAlbumImageView.setImageBitmap(null);  
  85.         if ((this.mBitmap == null) || (this.mBitmap.isRecycled()))  
  86.             return;  
  87.         this.mBitmap.recycle();  
  88.         this.mBitmap = null;  
  89.     }  
  90.       
  91.       
  92.     /** 
  93.      * 重新加载.外部调用. 
  94.      */  
  95.     public void reload(){  
  96.         try {  
  97.             int resId = mObject.getInt("resid");  
  98.             //实战中如果图片耗时应该令其一个线程去拉图片异步,不然把UI线程卡死.  
  99.             mAlbumImageView.setImageResource(resId);  
  100.         }catch (JSONException e) {  
  101.             e.printStackTrace();  
  102.         }  
  103.     }  
  104.       
  105. }  

2,创建远程方法接口实现类:

                 第二个概念非对称加密, 假设A要把一句话告诉B,A就把这句话放到一个有两 个完全不同的锁(lock1,lock2)的箱子里,然后锁上,A有lock1的钥匙,把箱子交给B,而B拥有lock2的钥匙,B通过打开lock2也 能看到箱子里的字条,这就是非对称加密。而A拥用的那把钥匙叫私要,B拥有的那把钥匙复制多份之后分给他们组员,就成了公钥。

import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 * User: liuzz
 * Date: 13-11-2
 * Time: 下午11:53
 */
public class Student {

    private String name;

    private int age;

    private Date birth;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }
    public String toString(){
        return "[ name = " + name +" , age = "+age+" , birth = " + birth+"]";
    }
}
  1. void destroyItem(View container, int position, Object object)   
  2.   
  3. 这里是左右滑动的时候,回收较早前的itemView.  

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。

好了,我们的安全管理器是怎么被执行的呢?如果你有兴趣可以继续往下看一下,也可以跳过,这里只是简单的介绍一下,也是本人习惯的学习思路

<object class="MyTest.MyTest.Week2.Student">  
    <property name="name">  
        <value>${name}</value>  
    </property>  
    <property name="age">  
        <value>${age}</value>  
    </property>  
    <property name="birth">  
        <value>${birth}</value>  
    </property>  
</object>  

第二步:新建一个ViewPagerItemView.java这里是相册的ItemView,代码如下:

- - - - Hello.class

java之jvm学习笔记八(实践对jar包的代码签名)

                          课程源码:

                          这一节,以实践为主,在跟着我做相应的操作之前,我希望你已经能够理解笔记七所提到的概念,至少你应该对于笔记七的那个大图有所了解。

                           好了!对于习惯用ecplise的朋友今天不得不逼迫你把jdk的环境搭建出来!下面让我们动手来实践一下对jar进行签名吧!

                           第一步,首先配置jdk的环境变量,如果你的电脑已经配置了,那直接跳过这一步

[java] view plaincopy

  1. path=%JAVA_HOME%/bin  
  2. JAVA_HOME=C:/Java/jdk1.6.0_01  
  3. CLASSPATH=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar      

配置要这几个jdk的环境参数,好了,配完了,试着在cmd里跑一下java,javac,看看命令是否生效,如果配置成功执行第二步。

                          第二步,来写几个简单的类,简单的才是大家的。你完全可以直接copy我的代码,部分看不懂,忽略它,做实验而已,对那个jar文件签名不是签,这个例子的代码逻辑是后面才用到的,不用读

                           第一个类Doer

[java] view plaincopy

  1. package com.yfq.test;  
  2.   
  3. public abstract interface Doer {  
  4.     void doYourThing();  
  5. }  

                            第二个类

                          

[java] view plaincopy

  1. package com.yfq.test.friend;  
  2.   
  3. import java.security.AccessController;  
  4. import java.security.PrivilegedAction;  
  5.   
  6. import com.yfq.test.Doer;  
  7.   
  8. public class Friend implements Doer{  
  9.     private Doer next;  
  10.     private boolean direct;  
  11.       
  12.     public Friend(Doer next,boolean direct){  
  13.         this.next=next;  
  14.         this.direct=direct;  
  15.     }  
  16.       
  17.     @Override  
  18.     public void doYourThing() {  
  19.         System.out.println("Im a Friend");  
  20.   
  21.         if (direct) {  
  22.             next.doYourThing();  
  23.         } else {  
  24.             AccessController.doPrivileged(new PrivilegedAction() {  
  25.   
  26.                 @Override  
  27.                 public Object run() {  
  28.                     next.doYourThing();  
  29.                     return null;  
  30.                 }  
  31.   
  32.             });  
  33.   
  34.         }  
  35.     }  
  36.   
  37. }  

                        第三个类

                        

[java] view plaincopy

  1. package com.yfq.test.stranger;  
  2.   
  3. import java.security.AccessController;  
  4. import java.security.PrivilegedAction;  
  5.   
  6. import com.yfq.test.Doer;  
  7.   
  8. public class Stranger implements Doer {  
  9.   
  10.     private Doer next;  
  11.     private boolean direct;  
  12.   
  13.     public Stranger(Doer next, boolean direct) {  
  14.         this.next = next;  
  15.         this.direct = direct;  
  16.     }  
  17.   
  18.     @Override  
  19.     public void doYourThing() {  
  20.         System.out.println("Im a Stranger");  
  21.   
  22.         if (direct) {  
  23.             next.doYourThing();  
  24.         } else {  
  25.             AccessController.doPrivileged(new PrivilegedAction() {  
  26.   
  27.                 @Override  
  28.                 public Object run() {  
  29.                     next.doYourThing();  
  30.                     return null;  
  31.                 }  
  32.   
  33.             });  
  34.   
  35.         }  
  36.     }  
  37.   
  38. }  

好了,编译一下,用强大的ecplise来编译,项目-右键-Build Project(工具是拿来用的,不要浪费这些强大的功能!)

                          第三步,打jar包,用ecplise就可以了就有导出jar包的功能,我还是那句老话,有工具不用,不是牛,是蠢。

                           步骤一,项目-右键-Export-java-JAR file-next

                           步骤二,展开目录清单-分别对com.yfq.tes.friend和 com.yfq.test.stranger打包(friend.jar,stranger.jar),放到哪里就随便你了,只要你记得就好,我这里假设 是放在d盘的根目录下

                           第四步,用java的keytool生成密钥对,用java的jarsigner做签名(记得笔记七我们说过对hash摘要的加密是非对称加密的吗?这里就需要两把不同的钥匙啦),一步步跟我来。

                           步骤一,cmd窗口,进入到存放friend.jar和stranger.jar的目录下,假设我的jar文件放在d盘下,直接输入盘符d:就可以了。

                          步骤二,在cmd窗口中输入keytool -genkey -keystore ijvmkeys.keystore -keyalg RSA -validity 10000 -alias friend.keystore

                                         生成第一个密钥对,这个密钥对的别名是 friend.keystore,采用的加密算法为RSA,密钥对的过期时间是10000天,密钥对存储的文件名ijvmkeys.keystore,而 查看ijvmkeys.keystore的密码和friend.keystore密钥对的查看密码我们设置为123456

                                         图片 1

注意:这里在设置名字和姓氏的时候要特别的注意,不要随便的乱写,否则将导致后面的签名失败,一般我们写完网络域名的形式如:www.keycoding.com这样。

                            步骤三,在cmd窗口输入,keytool -genkey -keystore ijvmkeys.keystore -keyalg RSA -validity 10000 -alias stranger.keystore

                                           按照步骤2的截图,一步一步输入吧,这个步骤是生成别名为stranger.keystore的密钥对。

                                            好了密钥对生成结束,看看你的jar文件目录下有没有多出一个文件ijvmkeys.keystore,是滴,这里生成了一个用于存放密钥对的文件。

                            步骤四,查看生成的密钥文件,在cmd窗口输入keytool -list -v -keystore ijvmkeys.keystore

                                           图片 2

                                 步骤五,对jar进行摘要并对hash摘要进行加密生成签名,放置到jar文件结构的尾部

                                           在cmd窗口输入 
                                           jarsigner -verbose -keystore ijvmkeys.keystore friend.jar friend.keystore
                                           jarsigner -verbose -keystore ijvmkeys.keystore stranger.jar stranger.keystore

                                          图片 3

                            步骤六,右键frend.jar和stranger.jar用rar解压器看看它们在META-INF目录下是否生成了两个附加的文件

                                          图片 4

而关于这两个附加文件的用处,我这里也简单的说明一下,首先从名字上来讲他是八个字符,他默认取我们的密钥对的名字的前八个字符做名字而因为我们的 密钥对名字是friend.keystore所以生成的名字将点替换为下滑线。如果你想要自己指定名字在keytool后面加上-sigFile XXXX这个参数

另外FRIEND_K.SF这个文件我们简单的展开                            

[html] view plaincopy

  1. Signature-Version: 1.0  
  2. SHA1-Digest-Manifest-Main-Attributes: QHukAYw2MtCop4vlrhjJDDro1fQ=  
  3. Created-By: 1.6.0_12 (Sun Microsystems Inc.)  
  4. SHA1-Digest-Manifest: YePdyFc1+FVdY1PIcj6WVuTJAFE=  
  5.   
  6. Name: com/yfq/test/friend/Friend$1.class  
  7. SHA1-Digest: mj79V3+YKsRAzxGHpyFGhOdY4dU=  
  8.   
  9. Name: com/yfq/test/friend/Friend.class  
  10. SHA1-Digest: tqPfF2lz4Ol8eJ3tQ2IBvvtduj0=  

它包含了签名的版本,签名者,还有被签名的类名,以及这个类的hash摘要,第四行是整个本文件的摘要,用于jar包的校验
FRIEND_K.DSA 文件,SF 文件被签名且签名被放入 .DSA 文件。.DSA 文件还包含来自密钥仓库的证书或证书链(被编码到其中),它们鉴别与用于签名的私钥对应的公钥。

                            步骤七,校验jar包在cmd中输入jarsigner -verify friend.jar和jarsigner -verify stranger.jar

                                           图片 5

                               到这里jar签名的实验已经完毕!!!!!

查看上面步骤四截图,我们来验证一下在笔记七里说过的话。

1.我们说过hash摘要是一个128的值,对不对呢,看证书指纹那一行,md5:....

你数一数总共有几个十六进制数,32个,一个十六进制数用4个位可以表示完,那么总共是几位,32*4=128,但是后面还有一个sha1的,怎么 回事他貌似不止128位,是滴,散列函数多种多样,到底用那个散列函数,md5还是sha1这个就看你喜欢,而要使用哪个散列函数是可以指定 的,keytool的参数-keyalg "DSA",这个参数就是用来指定用什么散列算法的,默认的就是DSA,普通的128位散列数已经是安全的了。

2.在 笔记七中,记不记得最下面那个图,有一个认证机构会对解密签名(被加密的hash摘要)的公钥做认证(也就是加密公钥),并发布证书,我们这里没有认证机构,你有没有这个疑问?

keytool程序在生成密钥时,总是会生成一个自签名证书(自签名是指:如果附近没有认证机构,可以用私钥对公钥签名,生成一个自签名证书)

总结:

         通过本章我们学习对一个jar进行签名,一个jar可以同时被多个机构或作者签名,看起来实验很复杂其实很简单。如果你还想了解更多关于jar包签名的知识,本人在这里推荐一篇文章(),本人自己在学习jar包签名的时候也从这篇文章中收益匪浅,希望它对你有帮助。

 

代码实现:

  1. package com.tutor.viewpager;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import org.json.JSONArray;  
  6. import org.json.JSONException;  
  7. import org.json.JSONObject;  
  8.   
  9. import android.content.Context;  
  10. import android.os.Parcelable;  
  11. import android.support.v4.view.PagerAdapter;  
  12. import android.support.v4.view.ViewPager;  
  13. import android.view.View;  
  14.   
  15. /** 
  16.  * @author frankiewei 
  17.  * 相册的适配器. 
  18.  */  
  19. public class ViewPagerAdapter extends PagerAdapter {  
  20.   
  21.     /** 
  22.      * 上下文 
  23.      */  
  24.     private Context mContext;  
  25.       
  26.     /** 
  27.      * 数据源,这里是JSONARRAY 
  28.      */  
  29.     private JSONArray mJsonArray;  
  30.       
  31.     /** 
  32.      * Hashmap保存相片的位置以及ItemView. 
  33.      */  
  34.     private HashMap<Integer, ViewPagerItemView> mHashMap;  
  35.       
  36.     public ViewPagerAdapter(Context context,JSONArray arrays) {  
  37.         this.mContext = context;  
  38.         this.mJsonArray = arrays;  
  39.         mHashMap = new HashMap<Integer, ViewPagerItemView>();  
  40.     }  
  41.       
  42.     //这里进行回收,当我们左右滑动的时候,会把早期的图片回收掉.  
  43.     @Override  
  44.     public void destroyItem(View container, int position, Object object) {  
  45.         ViewPagerItemView itemView = (ViewPagerItemView)object;  
  46.         itemView.recycle();  
  47.     }  
  48.       
  49.     @Override  
  50.     public void finishUpdate(View view) {  
  51.   
  52.     }  
  53.   
  54.     //这里返回相册有多少条,和BaseAdapter一样.  
  55.     @Override  
  56.     public int getCount() {  
  57.         return mJsonArray.length();  
  58.     }  
  59.   
  60.     //这里就是初始化ViewPagerItemView.如果ViewPagerItemView已经存在,  
  61.     //重新reload,不存在new一个并且填充数据.  
  62.     @Override  
  63.     public Object instantiateItem(View container, int position) {     
  64.         ViewPagerItemView itemView;  
  65.         if(mHashMap.containsKey(position)){  
  66.             itemView = mHashMap.get(position);  
  67.             itemView.reload();  
  68.         }else{  
  69.             itemView = new ViewPagerItemView(mContext);  
  70.             try {  
  71.                 JSONObject dataObj = (JSONObject) mJsonArray.get(position);  
  72.                 itemView.setData(dataObj);  
  73.             } catch (JSONException e) {  
  74.                 e.printStackTrace();  
  75.             }  
  76.             mHashMap.put(position, itemView);  
  77.             ((ViewPager) container).addView(itemView);  
  78.         }  
  79.           
  80.         return itemView;  
  81.     }  
  82.   
  83.     @Override  
  84.     public boolean isViewFromObject(View view, Object object) {  
  85.         return view == object;  
  86.     }  
  87.   
  88.     @Override  
  89.     public void restoreState(Parcelable arg0, ClassLoader arg1) {  
  90.           
  91.     }  
  92.   
  93.     @Override  
  94.     public Parcelable saveState() {  
  95.         return null;  
  96.     }  
  97.   
  98.     @Override  
  99.     public void startUpdate(View view) {  
  100.   
  101.     }  
  102. }  

图片 6

[java] view plaincopy

 

为 了让大家容易掌握,我写了一个简单的例子,简单实现相册横向滑动功能,首先自定义了ViewPager的itemView---- ViewPagerItemView,这里做了初始化View的定义,以及回收内存重新加载等,数据源是JSONObject.其次是实现了 PagerAdapter的适配器ViewPagerAdater,这里的数据源是JSONArray.然后ViewPager在名为 ViewPagerDemoActivity.java的Activity里显示。下面是具体实现步骤:

            System.out.println(">>>>>INFO:远程IHello对象绑定成功!"); 
        } catch (RemoteException e) { 
            System.out.println("创建远程对象发生异常!"); 
            e.printStackTrace(); 
        } catch (AlreadyBoundException e) { 
            System.out.println("发生重复绑定对象异常!"); 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            System.out.println("发生URL畸形异常!"); 
            e.printStackTrace(); 
        } 
    } 
}

  1. public FileInputStream(File file) throws FileNotFoundException {  
  2. String name = (file != null ? file.getPath() : null);  
  3. SecurityManager security = System.getSecurityManager();  
  4. if (security != null) {  
  5.     security.checkRead(name);  
  6. }  
  7.        if (name == null) {  
  8.            throw new NullPointerException();  
  9.        }  
  10. fd = new FileDescriptor();  
  11. open(name);  
  12.    }  

 

第一步:新建一个Android工程ViewPagerDemoActivity,目录结构如下图所示:

  1. package client;  
  2.   
  3. import java.net.MalformedURLException;  
  4. import java.rmi.Naming;  
  5. import java.rmi.NotBoundException;  
  6. import java.rmi.RemoteException;  
  7.   
  8. import server.Hello;  
  9.   
  10. public class HelloClient {  
  11.     public static void main(String[] args) {  
  12.         try {  
  13.             Hello h = (Hello)Naming.lookup("rmi://192.168.58.164:12312/Hello");  
  14.             System.out.println(h.sayHello("zx"));  
  15.         } catch (MalformedURLException e) {  
  16.             System.out.println("url格式异常");  
  17.         } catch (RemoteException e) {  
  18.             System.out.println("创建对象异常");  
  19.             e.printStackTrace();  
  20.         } catch (NotBoundException e) {  
  21.             System.out.println("对象未绑定");  
  22.         }  
  23.     }  
  24. }  

Exception in thread "main" java.lang.SecurityException: 你没有读取的本文件的权限
 at com.yfq.test.MySecurityManager.checkRead(MySecurityManager.java:9)
 at java.io.FileInputStream.<init>(FileInputStream.java:100)
 at java.io.FileInputStream.<init>(FileInputStream.java:66)
 at com.yfq.test.TestMySecurityManager.main(TestMySecurityManager.java:10)

 

[java] view plaincopy

[plain] view plain copy

[java] view plaincopy

 

  1. package com.tutor.viewpager;  
  2.   
  3. import org.json.JSONArray;  
  4. import org.json.JSONException;  
  5. import org.json.JSONObject;  
  6.   
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.support.v4.view.ViewPager;  
  10.   
  11. /** 
  12.  * @author frankiewei 
  13.  * ViewPager控件使用的Demo. 
  14.  */  
  15. public class ViewPagerDemoActivity extends Activity {  
  16.       
  17.     /** 
  18.      * 这里定义了相册的总数100条. 
  19.      */  
  20.     private static final int ALBUM_COUNT = 100;  
  21.       
  22.     /** 
  23.      * 相册的资源,实战开发中都是网络数据或者本地相册. 
  24.      */  
  25.     private static final int ALBUM_RES[] = {  
  26.         R.drawable.test1,R.drawable.test2,R.drawable.test3,  
  27.         R.drawable.test4,R.drawable.test5,R.drawable.test6  
  28.     };  
  29.       
  30.     private ViewPager mViewPager;  
  31.       
  32.     /** 
  33.      * 适配器. 
  34.      */  
  35.     private ViewPagerAdapter mViewPagerAdapter;  
  36.       
  37.     /** 
  38.      * 数据源. 
  39.      */  
  40.     private JSONArray mJsonArray;  
  41.       
  42.       
  43.     @Override  
  44.     public void onCreate(Bundle savedInstanceState) {  
  45.         super.onCreate(savedInstanceState);  
  46.         setContentView(R.layout.main);  
  47.           
  48.         setupViews();  
  49.     }  
  50.       
  51.     private void setupViews(){      
  52.         //初始化JSonArray,给ViewPageAdapter提供数据源用.  
  53.         mJsonArray = new JSONArray();  
  54.         for(int i = 0;i<ALBUM_COUNT; i++){  
  55.             JSONObject object = new JSONObject();  
  56.             try {  
  57.                 object.put("resid", ALBUM_RES[i % ALBUM_RES.length]);  
  58.                 object.put("name", "Album " + i);  
  59.                 mJsonArray.put(object);  
  60.             } catch (JSONException e) {  
  61.                 e.printStackTrace();  
  62.             }  
  63.               
  64.         }         
  65.         mViewPager = (ViewPager)findViewById(R.id.viewpager);  
  66.         mViewPagerAdapter = new ViewPagerAdapter(this, mJsonArray);  
  67.         mViewPager.setAdapter(mViewPagerAdapter);  
  68.     }  
  69. }  

CLASSPATH为java .class文件的存放路径,使用java命令运行.class文件时即会在该参数配置的路径下寻找相应文件

 

例子见附件,注意:
1)对象是任意对象,不是例子中的Student,对象中的property都是Java中的原生类型
2)xml和properties在使用的时候都是根据对象配置好的
3) xml的scheme是固定的,就是附件中的scheme

图片 7

                   图片 8

object.properties2文件

第四步:修改主Activity类ViewPagerDemoActivity.java代码如下:

  1. LocateRegistry.createRegistry(12312);  

                 那么什么是jar包的签名和认证?

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android=""  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <android.support.v4.view.ViewPager  
  8.         android:id="@+id/viewpager"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="fill_parent"  
  11.          />  
  12.   
  13. </LinearLayout> 

方式一:后台启动rmiregistry服务

                   上面的一堆废话,其实也是为了描述下面这个图的整个过程,如果你一眼就看明白下面这个图,那就忽略上面的描述吧

[java] view plain copy

[java] view plaincopy

如果不带具体端口号,则默认为1099

 

 

其中main.xml布局代码如下:

- - - - Hello.class

                第二步,定义一个有main函数的public类来验证自己的安全管理器是不是器作用了。

[html] view plain copy

第三步:新建一个ViewPagerAdapter.java继承与PagerAdapter,代码如下:

 

 

 

[java] view plaincopy

方式二:

 

  1. import java.util.Date;  
  2.   
  3. /** 
  4.  * Created by IntelliJ IDEA. 
  5.  * User: liuzz 
  6.  * Date: 13-11-2 
  7.  * Time: 下午11:53 
  8.  */  
  9. public class Student {  
  10.   
  11.     private String name;  
  12.   
  13.     private int age;  
  14.   
  15.     private Date birth;  
  16.   
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.   
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.   
  25.     public int getAge() {  
  26.         return age;  
  27.     }  
  28.   
  29.     public void setAge(int age) {  
  30.         this.age = age;  
  31.     }  
  32.   
  33.     public Date getBirth() {  
  34.         return birth;  
  35.     }  
  36.   
  37.     public void setBirth(Date birth) {  
  38.         this.birth = birth;  
  39.     }  
  40.     public String toString(){  
  41.         return "[ name = " + name +" , age = "+age+" , birth = " + birth+"]";  
  42.     }  
  43. }  

其中ViewPagerItemView使用的xml文件viewpager_itemView.xml代码如下:

    /** 
     * 一个简单的业务方法,根据传入的人名返回相应的问候语 
     * @param someBodyName  人名 
     * @return 返回相应的问候语 
     * @throws java.rmi.RemoteException 
     */ 
    public String sayHelloToSomeBody(String someBodyName) throws RemoteException; 
}

                 方案二。对jar包的部分内容进行加密,这个思路好像效率高点,但是对哪一部分进行加密?如果没有加密的那一部分被修改了怎么确认?这又一个问题。

  1. name=a  
  2. age=10  
  3. birth=2003-11-04  

[java] view plaincopy

6,客户端辅助对象将返回值解包,返回给客户对象

                    前言:

object.xml文件

[java] view plaincopy

 

 

object.xml文件

相信大家用的ListView控件一定很多的,是竖向滑动的,复用convertView,我们可以加载成千上万的数据,但有时候我们会有这个需求 比如相册,我们想横向滑动,并且数据有好多,这时候ViewPager控件就派上用场了,ViewPager使用时候我们需要导入第三方包 android-support-v4.jar包,这是谷歌提供的,这个包里有Fragment ViewPager等控件,用户导入这个包,在3.0以前就可以使用Fragment控件了~

  1. [name@name jdk]$ jdk1.5.0_15/bin/rmiregistry 12312 &  
  2. [1] 22720  
  3. [name@name jdk]$ ps -ef|grep rmiregistry  
  4. name    22720 13763  0 16:43 pts/3    00:00:00 jdk1.5.0_15/bin/rmiregistry 12312  
  5. name    22737 13763  0 16:43 pts/3    00:00:00 grep rmiregistry  

直接跳到FileInputStream的构造函数里,下面贴出代码,简单阅读一下

 

[java] view plaincopy

2,RMI依赖于Java远程消息交换协议JRMP(java Remote Messaging Protocol),该协议为java定制,要求服务端与客户端都为java编写

 

                           本节源码:

                           这一节,我们会简单的描述一下jvm访问控制器的栈校验机制。

                           这节课,我们还是以实践为主,什么是栈校验机制,讲一百遍不如你自己实际的代码一下然后验证一下,下面我们下把环境搭起来。

                           第一步,配置系统环境。(copy吧,少年)

[java] view plaincopy

  1. path=%JAVA_HOME%/bin  
  2. JAVA_HOME=C:/Java/jdk1.6.0_01  
  3. CLASSPATH=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar      

                           第二步,配置一个策略文件的运行环境。

第一个类Doer:

[java] view plaincopy

  1. package com.yfq.test;  
  2.   
  3. public abstract interface Doer {  
  4.     void doYourThing();  
  5. }  

第二个类Friend:

 

[java] view plaincopy

  1. package com.yfq.test.friend;  
  2.   
  3. import java.security.AccessController;  
  4. import java.security.PrivilegedAction;  
  5.   
  6. import com.yfq.test.Doer;  
  7.   
  8. public class Friend implements Doer{  
  9.     private Doer next;  
  10.     private boolean direct;  
  11.       
  12.     public Friend(Doer next,boolean direct){  
  13.         this.next=next;  
  14.         this.direct=direct;  
  15.     }  
  16.       
  17.     @Override  
  18.     public void doYourThing() {  
  19.         System.out.println("Im a Friend");  
  20.   
  21.         if (direct) {  
  22.             next.doYourThing();  
  23.         } else {  
  24.             AccessController.doPrivileged(new PrivilegedAction() {  
  25.   
  26.                 @Override  
  27.                 public Object run() {  
  28.                     next.doYourThing();  
  29.                     return null;  
  30.                 }  
  31.   
  32.             });  
  33.   
  34.         }  
  35.     }  
  36. }  

第三个类Stranger:

  

[java] view plaincopy

  1. package com.yfq.test.stranger;  
  2.   
  3. import java.security.AccessController;  
  4. import java.security.PrivilegedAction;  
  5.   
  6. import com.yfq.test.Doer;  
  7.   
  8. public class Stranger implements Doer {  
  9.   
  10.     private Doer next;  
  11.     private boolean direct;  
  12.   
  13.     public Stranger(Doer next, boolean direct) {  
  14.         this.next = next;  
  15.         this.direct = direct;  
  16.     }  
  17.   
  18.     @Override  
  19.     public void doYourThing() {  
  20.         System.out.println("Im a Stranger");  
  21.   
  22.         if (direct) {  
  23.             next.doYourThing();  
  24.         } else {  
  25.             AccessController.doPrivileged(new PrivilegedAction() {  
  26.   
  27.                 @Override  
  28.                 public Object run() {  
  29.                     next.doYourThing();  
  30.                     return null;  
  31.                 }  
  32.   
  33.             });  
  34.   
  35.         }  
  36.     }  
  37.   
  38.   
  39. }  

第四个类TextFileDisplayer:

[java] view plaincopy

  1. import java.io.CharArrayWriter;  
  2. import java.io.FileNotFoundException;  
  3. import java.io.FileReader;  
  4. import java.io.IOException;  
  5.   
  6. import com.yfq.test.Doer;  
  7.   
  8.   
  9. public class TextFileDisplayer implements Doer{  
  10.     String fileName;  
  11.     public TextFileDisplayer(String fileName){  
  12.         this.fileName=fileName;  
  13.     }  
  14.     @Override  
  15.     public void doYourThing() {  
  16.         try {  
  17.             FileReader fr = new FileReader(fileName);  
  18.             try {  
  19.             CharArrayWriter caw = new CharArrayWriter();  
  20.             int c;  
  21.                 while((c=fr.read())!=-1){  
  22.                     caw.write(c);  
  23.                 }  
  24.                 System.out.println(caw.toString());  
  25.             } catch (IOException e) {  
  26.                 e.printStackTrace();  
  27.             }finally{  
  28.                 if(fr!=null){  
  29.                     try {  
  30.                         fr.close();  
  31.                         fr=null;  
  32.                     } catch (IOException e) {  
  33.                         e.printStackTrace();  
  34.                     }  
  35.                       
  36.                 }  
  37.             }  
  38.         } catch (FileNotFoundException e) {  
  39.             e.printStackTrace();  
  40.         }  
  41.           
  42.     }  
  43.   
  44. }  

 

                                第三步,参考笔记,把Friend和Stranger打包并签名,并放到ecplise编译目录bin/jars下,把生成的密钥存储文件放在与bin同级的目录下。(你也可以先用我上传的源码里的jar包,不过还是建议你动手练一练)

                                 第四步,配置策略文件

[java] view plaincopy

  1. keystore "ijvmkeys.keystore";  
  2.   
  3. grant signedby "friend.keystore" {     
  4.     permission java.io.FilePermission "d:/answer.txt", "read";   
  5.     permission java.io.FilePermission "d:/question.txt", "read";    
  6. };   
  7.   
  8. grant signedby "stranger.keystore" {     
  9.        permission java.io.FilePermission "d:/question.txt", "read";   
  10. };   
  11.    
  12.   
  13. grant codeBase "file:D:/workspace/MyAccessControlerStack/bin/*" {     
  14.     permission java.io.FilePermission "d:/answer.txt", "read";   
  15.     permission java.io.FilePermission "d:/question.txt", "read";   
  16. };   

                                    第五步,新建一个类,这个类里有个主函数,用于校验类Friend,Stranger,TextFileDisplayer对于question.txt的读取权限

[java] view plaincopy

  1. import com.yfq.test.friend.Friend;  
  2. import com.yfq.test.stranger.Stranger;  
  3.   
  4.   
  5. public class Example2 {  
  6.     public static void main(String[] args) {  
  7.         TextFileDisplayer tfd=new TextFileDisplayer("d:/question.txt");  
  8.         Friend friend = new Friend(tfd,true);  
  9.         Stranger stranger = new Stranger(tfd,true);  
  10.         stranger.doYourThing();  
  11.     }  
  12. }  

                                 第六步运行,cmd窗口输入:
java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example2

 图片 9  

说明:

从这里,我们并不能很直观的发现访问控制器的栈校验机制,看Example2的main函数,我们知道当stranger执行doYourThing的时候,会经过这么一个过程,

Example2--------->被ApplClassLoader装入到ProtectionDomian_Example2中---------------->执行main函数

TextFilDisplayer------->ApplClassLoader判断当前的线程有没有装载类TextFilDisplayer的权限---------->装载到ProtectionDomian_TextFileDisplayer中

Friend------->ApplClassLoader判断当前的线程有没有装载类TextFilDisplayer的权限-------->装载到ProtectionDomian_Friendr中()

Stranger------->ApplClassLoader判断当前的线程有没有装载类TextFilDisplayer的权限----------->装载到ProtectionDomian_Stranger中

Stranger的实例对象stranger执行doYourThing方法---->直接调用Friend的实力引用执行 doYourThing方法----->Friend的实例引用直接调用TextFileDisplayer的doYourThing方法

输出question.txt的文本内容。

这个过程中,AccessControler到底是在什么时候执行的,怎么执行的呢,来看下面这个图

 图片 10

上面的这个图是一个AccessControlerContext,也就是访问控制器上 下文,它大概了描述了,各个函数被调用的时候的保护域的压栈过程,直到栈顶结束压栈之后,它会按照先进后出的规则,AccessControler调用自 己的checkPermission方法,检验每一层的权限(上面的保护域数组中,名为BOOTSTRAP保护域是系统保护域,它的权限是 SecurityConstants.ALL_PERMISSION,这就意味着他什么都能够做)。AccessControler的保护域数组成员则会 调用自己的implies方法,ProtectionDomain的implies方法会先查看是否有配置了策略文件,如果有的话就将当前保护域传递给 Policy这个单例,由他从配置文件中取出PermissionCollection然后再调用每个Permission检验它的implies方法, 如果没有设定特定的配置文件,则直接调用当前保护域中的PermissionCollecion成员的implies,再由它调用Permission的 implies方法。

由于Examples2所读取的是question.txt文本,又由于我们的策略文件中,让Friend,Stranger,TextFileDisplayer都拥有它的读取权限,所以顺利的执行了。

                                      第七步:为了验证我们的猜想是正确的,我们现在修改Example2如下

                                      

[java] view plaincopy

  1. import com.yfq.test.friend.Friend;  
  2. import com.yfq.test.stranger.Stranger;  
  3.   
  4.   
  5. public class Example {  
  6.     public static void main(String[] args) {  
  7.         TextFileDisplayer tfd=new TextFileDisplayer("d:/answer.txt");  
  8.         Friend friend = new Friend(tfd,true);  
  9.         Stranger stranger = new Stranger(tfd,true);  
  10.         stranger.doYourThing();  
  11.     }  
  12. }  

这里我们仅仅是将question.txt换成了answer.txt,而关于这个文件我们知道Stranger是没有读取的权限的,下面我们来运行它看看

                                        第八步,cmd窗口输入 java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example
     图片 11

我们再来看AccessControlerContext的图

图片 12

前面的安全检查都通过了,但是到了STRANGER保护域的时候,由于Stranger'没有读取answer.txt的权限,所以implies方法抛出了一个AccessControlException。

那么AccessControler的栈校验机制能够带来什么好处呢??

答案很显然,就好像我们第七步一样,我们试图让一个没有权限的类来调用一个具有高级权限的类别,以达到“破坏”的目的,由于栈校验机制的存在,让我 们的这种幻想变得不容易实现,但是不容易实现并不代表不能够实现,下面我们将来学习一个方法,这个方法叫doPrivileged(),这个方法可以帮助 我们达到第七步的目的。

                                   第九步,修改我们上面的Example类如下

[java] view plaincopy

  1. import com.yfq.test.friend.Friend;  
  2. import com.yfq.test.stranger.Stranger;  
  3.   
  4.   
  5. public class Example3 {  
  6.     public static void main(String[] args) {  
  7.         TextFileDisplayer tfd=new TextFileDisplayer("d:/answer.txt");  
  8.         Friend friend = new Friend(tfd,false);  
  9.         Stranger stranger = new Stranger(friend,true);  
  10.         stranger.doYourThing();  
  11.     }  
  12. }  

我们只是将friend的初始化参数做了稍微的调整,new Friend(tfd,true)改为了new Friend(tfd,false);这个调整使得friend的doYourThing方法不是直接的执行next.doYourThing()而是通 过给AccessController.doPrivileged()方法传入一个匿名内部类并重写它的run方法,在run方法里调用了 next.doYourThing()。

                                      第十步,然后我们在cmd窗口 输入:java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example3

图片 13
查看输出:既然成功由没有权限查看answer.txt的Strange完成了查看answer.txt的操作。这是怎么回事??我们再来看刚才表示AccessControlContext的图

图片 14

由于我们在Friend中安装了doPrivileged(),所以doPrivileged()这个方法被压入栈而且是在Stranger的前 面,doPrivileged()执行的时候会调用我的匿名内部类Friend$1并执行它的run方法,而run方法里执行完 next.doYourThing之后,AccessControlContext将继续执行判断到doPrivileged(),它发现这是一个 BootStrap的调用,那么AccessControlContext会继续执行另外一个判断,判断是谁安装了这个doPrivileged()方 法,所以执行到了Freind的doYourThing(),判定它有打开answer.txt的权限,那么最后才直接把run方法的return返回出 去。

就是通过这样的方式,使得我们没有权限的Stranger能够“越权"操作。

但是越权还是有条件的,如第九步,我们执行”越权“方法run的方法栈帧是嵌套在Friend的doYourThing的线程栈帧中的,由于Friend有读取answer.txt的权限,这才使得run方法有了”越狱“的机会。

                                   第十一步,我们修改一下Example3来验证一下自己的观点

[java] view plaincopy

  1. import com.yfq.test.friend.Friend;  
  2. import com.yfq.test.stranger.Stranger;  
  3.   
  4.   
  5. public class Example4 {  
  6.     public static void main(String[] args) {  
  7.         TextFileDisplayer tfd=new TextFileDisplayer("d:/answer.txt");  
  8.         Stranger stranger = new Stranger(tfd,false);  
  9.         Friend friend = new Friend(stranger,true);  
  10.         stranger.doYourThing();  
  11.     }  
  12. }  

                                      第十二步,cmd窗口输入 java -classpath .;jars/friend.jar;jars/stranger.jar -Djava.security.manager -Djava.security.policy=D:/workspace/MyAccessControlerStack/src/myPolicy.txt Example4

图片 15

报出异常了,这个异常就是由于stranger$1这个内部类的方法栈帧是嵌套在 stranger的doYourThing的方法栈帧中,而stranger的保护域规定了stranger这个类的对象是没有权限读取 answer.txt这个文件,所以run这个方法也就没办法”越狱“。

总结:

            这一节,我们学习了访问控制器校验保护域权限的过程,它采取的是栈的校验机制(先进后出),而它的每个方法调用总是线程栈 帧相关的,如果我们必须要”越狱“,那预约的条件要求调用doPrivileged()方法的栈帧的至少要有执行越狱操作的权限。

 

name=a  
age=10  
birth=2003-11-04 

运行RMI客户端程序:

                   好吧,这一节的内容全是概念,概念只需要你看而不是要你背,在某个时候你会焕然大悟的,而这个时间应该会是在下一节java之jvm学习笔记八(实践对jar包进行签名)

 

1,从代码中也可以看到,代码依赖于ip与端口

好了今天的文件安全管理器demo就到这里。意在浅显易懂!

要求写一个解析器:
1)将xml中的占位符,替换为properties文件中的value
2) 将xml解析成对象,调用getter方法的时候可以获得值
3)用面向对象的思想,使该解析器有扩展性

7,编写客户端代码

  1. package com.yfq.test;  
  2.   
  3. public class MySecurityManager extends SecurityManager {  
  4.   
  5.     @Override  
  6.     public void checkRead(String file) {  
  7.         //super.checkRead(file, context);  
  8.         if (file.endsWith("test"))    
  9.         throw new SecurityException("你没有读取的本文件的权限");    
  10.     }  
  11.       
  12. }  

 

[java] view plain copy

本文由必威发布于必威-运维,转载请注明出处:它的核心方法就是checkPerssiom这个方法里又调用,

相关阅读