自定義 java 加載器
阿新 • • 發佈:2018-09-16
new dmi ESS class a length turn ngs 加密 list 先寫個java類的:
allen.java
allen.java
import java.util.Date; import java.util.List; /** * 加載類 * @author Administrator */ public class allen extends Date{ // private static final long serialVersionUID = 8627644427315706176L; //打印數據 @Override public String toString(){ return "Hello ClassLoader!"; } public static void main(String[] args){ System.out.println("List類的加載器的名稱:"+List.class.getClassLoader()); } }
運行:
然後把編譯的.class文件放到 其它 目錄下
新建一個class_temp用於保存加密的class文件
防止沖突修改下名字
編寫自定義加載器:
//MyClassLoader.java
import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; /** * 自定義的類加載器 * @author Administrator */ public class MyClassLoader extends ClassLoader{ //需要加載類.class文件的目錄 private String classDir; //無參的構造方法,用於class.newInstance()構造對象使用 public MyClassLoader(){ } public MyClassLoader(String classDir){ this.classDir = classDir; } @SuppressWarnings("deprecation") @Override protected Class<?> findClass(String name) throws ClassNotFoundException { //class文件的路徑 String classPathFile = classDir + "/" + name + ".class"; try { //將class文件進行解密 FileInputStream fis = new FileInputStream(classPathFile); ByteArrayOutputStream bos = new ByteArrayOutputStream(); encodeAndDecode(fis,bos); byte[] classByte = bos.toByteArray(); //將字節流變成一個class return defineClass(classByte,0,classByte.length); } catch (Exception e) { e.printStackTrace(); } return super.findClass(name); } //測試,先將ClassLoaderAttachment.class文件加密寫到工程的class_temp目錄下 public static void main(String[] args) throws Exception{ //配置運行參數 //String srcPath = args[0];//ClassLoaderAttachment.class原路徑 String srcPath = "/Users/liuhailong/IdeaProjects/testjava/allen.class"; //String desPath = args[1];//ClassLoaderAttachment.class輸出的路徑 String desPath ="/Users/liuhailong/IdeaProjects/testjava/class_temp"; String desFileName = srcPath.substring(srcPath.lastIndexOf("/")+1); String desPathFile = desPath + "/" + desFileName; FileInputStream fis = new FileInputStream(srcPath); FileOutputStream fos = new FileOutputStream(desPathFile); //將class進行加密 encodeAndDecode(fis,fos); fis.close(); fos.close(); } /** * 加密和解密算法 * @param is * @param os * @throws Exception */ private static void encodeAndDecode(InputStream is,OutputStream os) throws Exception{ int bytes = -1; while((bytes = is.read())!= -1){ bytes = bytes ^ 0xff;//和0xff進行異或處理 os.write(bytes); } } }
添加倆個參數 也可以直接寫死
先運行自定義的加載器(因為有 main 函數 用於加密)
運行完後就多了個加密後的類
編寫測試類
//ClassLoaderTest.java
import java.util.Date; import java.util.List; /** * 測試類 * @author Administrator */ public class ClassLoaderTest { @SuppressWarnings("rawtypes") public static void main(String[] args){ //輸出ClassLoaderText的類加載器名稱 System.out.println("ClassLoaderText類的加載器的名稱:"+ClassLoaderTest.class.getClassLoader().getClass().getName()); System.out.println("System類的加載器的名稱:"+System.class.getClassLoader()); System.out.println("List類的加載器的名稱:"+List.class.getClassLoader()); System.out.println("默認的類加載器:"+ClassLoaderTest.class.getClassLoader().getSystemClassLoader()); ClassLoader cl = ClassLoaderTest.class.getClassLoader(); while(cl != null){ System.out.print(cl.getClass().getName()+"->"); cl = cl.getParent(); } System.out.println(cl); try { Class classDate = new MyClassLoader("/Users/liuhailong/IdeaProjects/testjava/class_temp").loadClass("allen"); Date date = (Date) classDate.newInstance(); //輸出ClassLoaderAttachment類的加載器名稱 System.out.println("ClassLoader:"+date.getClass().getClassLoader().getClass().getName()); System.out.println(date); } catch (Exception e1) { e1.printStackTrace(); } } }
ClassLoaderText類的加載器的名稱:sun.misc.Launcher$AppClassLoader
System類的加載器的名稱:null
List類的加載器的名稱:null
默認的類加載器:sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader->sun.misc.Launcher$ExtClassLoader->null
ClassLoader:MyClassLoader
Hello ClassLoader!
運行
發現 main 沒運行 這是很定的!!!!
結論是可以自行加載加密的 class 文件
自定義 java 加載器