TestJarLoader.java 5.8 KB
package com.zhaoonline.support.gateway.apijar;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import org.junit.Assert;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

import com.zhaoonline.support.gateway.utils.Utils;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.NotFoundException;

public class TestJarLoader {
	public static String classParentDir = "D://test/";

	@Before
	public void before() throws IOException {

	}

	/**
	 * Method name: createAndloadJarDynamic <BR>
	 * Description: parenet classLoader是无法loaderClass的 <BR>
	 * Remark: <BR>
	 * @throws NotFoundException
	 * @throws CannotCompileException
	 * @throws IOException  void<BR>
	 */
	String jarDir=classParentDir + "testJar.jar"; 
	
	
	@Test
	public void createAndloadJarDynamic() throws NotFoundException, CannotCompileException, IOException {
		Utils.deleteDirectory(Paths.get(classParentDir));
		Set<PosixFilePermission> perms=new HashSet<PosixFilePermission>();
		perms.add(PosixFilePermission.GROUP_EXECUTE);
		perms.add(PosixFilePermission.GROUP_READ);
		perms.add(PosixFilePermission.GROUP_WRITE);
		Files.createDirectories(Paths.get(classParentDir));
		
		Map<String, Class<?>> properties = new HashMap<String, Class<?>>();
		properties.put("name", java.lang.String.class);
		properties.put("id", java.lang.String.class);
		createDynamicJarWithSimplePojo(properties, "com.test.User",  jarDir);
//		ClassLoader parenclassLoader=Thread.currentThread().getContextClassLoader();
		ClassLoader parenclassLoader=getClass().getClassLoader();
//		ClassLoader parenclassLoader=new ClassLoader() {
//		};
		//新增加的com.test.User是由getClass().getClassLoader()创建的,所以能够class存在的
		Class<?> userClassBeforeLoad=null;
		try {
			userClassBeforeLoad = parenclassLoader.loadClass("com.test.User");
			Assert.assertNotNull(userClassBeforeLoad);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			Assert.assertNull(userClassBeforeLoad);
		}
		
		
		
		URLClassLoader urlClassLoader=JarLoader.loadFromJar(Thread.currentThread().getContextClassLoader(),jarDir);
		Class<?> userClassAfterLoad;
		try {
			userClassAfterLoad = urlClassLoader.loadClass("com.test.User");
			Assert.assertNotNull(userClassAfterLoad);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			fail();
		}
		urlClassLoader.close();
		
		
		Class<?> userClassAfterLoadAndClosed;
		try {
			userClassAfterLoadAndClosed = urlClassLoader.loadClass("com.test.User");
			Assert.assertNotNull(userClassAfterLoadAndClosed);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			fail();
		}
		
		
		
		Class<?> userClassBeforeLoad2=null;
		try {
			userClassBeforeLoad2 = parenclassLoader.loadClass("com.test.User");
			Assert.assertNotNull(userClassBeforeLoad2);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
	}
	
	
	@Test
	public void  loadJarDynamicFromExistedFile() throws NotFoundException, CannotCompileException, IOException {
//		ClassLoader parenclassLoader=Thread.currentThread().getContextClassLoader();
		ClassLoader parenclassLoader=getClass().getClassLoader();
		
		Class<?> userClassBeforeLoad=null;
		try {
			userClassBeforeLoad = parenclassLoader.loadClass("com.test.User");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			Assert.assertNull(userClassBeforeLoad);
		}
		
		
		
		URLClassLoader urlClassLoader=JarLoader.loadFromJar(Thread.currentThread().getContextClassLoader(),jarDir);
		Class<?> userClassAfterLoad;
		try {
			userClassAfterLoad = urlClassLoader.loadClass("com.test.User");
			Assert.assertNotNull(userClassAfterLoad);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			fail();
		}
		urlClassLoader.close();
		
		
		
		//在urlClassLoader关闭之后就不能继续加入新的jar了。但是已经Load的class还是可以进行再次装载的
		Class<?> userClassAfterLoadAndClosed;
		try {
			userClassAfterLoadAndClosed = urlClassLoader.loadClass("com.test.User");
			Assert.assertNotNull(userClassAfterLoadAndClosed);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			fail();
		}
		
		
		
		Class<?> userClassBeforeLoad2=null;
		try {
			userClassBeforeLoad2 = parenclassLoader.loadClass("com.test.User");
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			Assert.assertNull(userClassBeforeLoad2);
		}
		
	}
	
	
	

	public static void createDynamicJarWithSimplePojo(Map<String, Class<?>> properties, String classname, String jarSavaDir)
			throws NotFoundException, CannotCompileException, IOException {

		File tempJarFile = new File(jarSavaDir);
		if(tempJarFile.exists()){
			return ;
		}
		CtClass classCreator = PojoGenerator.generate(classname, properties);
		Class claszz = classCreator.toClass();

		Manifest manifest = new Manifest();
		manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
		FileOutputStream tempJarFilestream = new FileOutputStream(tempJarFile);
		JarOutputStream outputStream = new JarOutputStream(tempJarFilestream, manifest);

		String packageName = classCreator.getPackageName();
		JarEntry jarPackage = new JarEntry(packageName.replace(".", "/") + "/");
		outputStream.putNextEntry(jarPackage);

		JarEntry jarAdd = new JarEntry(claszz.getName().replace(".", "/") + ".class");
		outputStream.putNextEntry(jarAdd);

		byte[] bytes = classCreator.toBytecode();

		outputStream.write(bytes);
		outputStream.close();
		tempJarFilestream.close();
	}


}