| | |
| | | package com.iailab.module.model.mpk.common.utils; |
| | | |
| | | import com.iailab.module.model.mpk.common.MdkConstant; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import sun.misc.URLClassPath; |
| | | |
| | | import java.io.File; |
| | | import java.lang.reflect.Field; |
| | | import java.lang.reflect.Method; |
| | | import java.net.URL; |
| | | import java.net.URLClassLoader; |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | import java.util.Vector; |
| | | |
| | | @Slf4j |
| | | public class DllUtils { |
| | | |
| | | private static HashMap<String, URLClassLoader> classLoaderCache = new HashMap<>(); |
| | | |
| | | /** |
| | | * @description: 加载dll到指定class下 |
| | |
| | | **/ |
| | | public static void loadDll(Class<?> clazz, String dllPath) { |
| | | try { |
| | | Method method = Runtime.class.getDeclaredMethod("load0", Class.class,String.class); |
| | | Method method = Runtime.class.getDeclaredMethod("load0", Class.class, String.class); |
| | | boolean accessible = method.isAccessible(); |
| | | method.setAccessible(true); |
| | | method.invoke(Runtime.getRuntime(), clazz,dllPath); |
| | | method.invoke(Runtime.getRuntime(), clazz, dllPath); |
| | | method.setAccessible(accessible); |
| | | log.info("成功加载dll:"+ dllPath); |
| | | log.info("成功加载dll:" + dllPath); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("加载dll异常",e); |
| | | throw new RuntimeException("加载dll异常", e); |
| | | } |
| | | } |
| | | |
| | |
| | | * @author: dzd |
| | | * @date: 2024/9/30 14:31 |
| | | **/ |
| | | public static synchronized void uploadDll(URLClassLoader classLoader) { |
| | | public static synchronized void unloadDll(URLClassLoader classLoader) { |
| | | try { |
| | | Field field = ClassLoader.class.getDeclaredField("nativeLibraries"); |
| | | field.setAccessible(true); |
| | |
| | | log.info("成功卸载dll:" + name); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("卸载dll异常",e); |
| | | throw new RuntimeException("卸载dll异常", e); |
| | | } |
| | | } |
| | | |
| | |
| | | * @author: dzd |
| | | * @date: 2024/9/30 14:52 |
| | | **/ |
| | | public static synchronized void uploadDllName(URLClassLoader classLoader,String dllName) { |
| | | public static synchronized void unloadDllName(URLClassLoader classLoader, String dllName) { |
| | | try { |
| | | Field field = ClassLoader.class.getDeclaredField("nativeLibraries"); |
| | | field.setAccessible(true); |
| | |
| | | log.info("成功卸载dll:" + name); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("卸载dll异常",e); |
| | | throw new RuntimeException("卸载dll异常", e); |
| | | } |
| | | } |
| | | |
| | |
| | | public static synchronized URLClassLoader loadJar(String jarPath) { |
| | | File jarFile = new File(jarPath); |
| | | if (!jarFile.exists()) { |
| | | throw new RuntimeException("jar沒有找到!"); |
| | | throw new RuntimeException("jar沒有找到!"+jarPath); |
| | | } else { |
| | | try { |
| | | URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()}); |
| | | log.info("成功加载jar包:"+ jarFile.getAbsolutePath()); |
| | | // 设置classloader的patent为null,限制使用双亲委派,防止其他classloader找到class,导致dll加载到其他classloader |
| | | URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()},null,null); |
| | | log.info("成功加载jar包:" + jarFile.getAbsolutePath()); |
| | | return urlClassLoader; |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("加载jar异常",e); |
| | | throw new RuntimeException("加载jar异常", e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static synchronized void uploadJar(URLClassLoader urlClassLoader) { |
| | | public static synchronized void unloadJar(URLClassLoader urlClassLoader) { |
| | | try { |
| | | urlClassLoader.close(); |
| | | log.info("成功卸载jar包。"); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("卸载jar异常",e); |
| | | throw new RuntimeException("卸载jar异常", e); |
| | | } |
| | | } |
| | | |
| | | public static synchronized void addClassLoaderCache(String projectId, URLClassLoader urlClassLoader) { |
| | | classLoaderCache.put(projectId, urlClassLoader); |
| | | } |
| | | |
| | | public static synchronized URLClassLoader getClassLoader(String projectId) { |
| | | return classLoaderCache.get(projectId); |
| | | } |
| | | |
| | | public static synchronized void removeClassLoaderCache(String projectId) { |
| | | if (classLoaderCache.containsKey(projectId)) { |
| | | URLClassLoader urlClassLoader = classLoaderCache.get(projectId); |
| | | unloadDll(urlClassLoader); |
| | | unloadJar(urlClassLoader); |
| | | classLoaderCache.remove(projectId); |
| | | } |
| | | } |
| | | |
| | | public static void removeOldFile(String bakPath,String projectId) { |
| | | File dir = new File(bakPath); |
| | | if (dir.exists() && dir.isDirectory()) { |
| | | File[] files = dir.listFiles(); |
| | | if (null != files && files.length > 0) { |
| | | for (File file : files) { |
| | | if (file.getName().startsWith(projectId)) { |
| | | file.delete(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description: 项目启动加载已发布的dll和jar |
| | | * @author: dzd |
| | | * @date: 2024/10/10 11:58 |
| | | **/ |
| | | public static void loadProjectPublish(String bakPath) { |
| | | File dir = new File(bakPath); |
| | | if (dir.exists() && dir.isDirectory()) { |
| | | File[] files = dir.listFiles(); |
| | | if (null != files && files.length > 0) { |
| | | for (File file : files) { |
| | | String fileName = file.getName(); |
| | | if (fileName.endsWith(".jar")) { |
| | | String[] split = fileName.substring(0,fileName.length() - 4).split(MdkConstant.SPLIT); |
| | | String projectId = split[0]; |
| | | String historyId = split[1]; |
| | | |
| | | String jarFilePath = bakPath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar"; |
| | | String dllFilePath = bakPath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll"; |
| | | |
| | | URLClassLoader urlClassLoader = null; |
| | | try { |
| | | // 加载新的jar |
| | | urlClassLoader = DllUtils.loadJar(jarFilePath); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("加载jar异常",e); |
| | | } |
| | | |
| | | try { |
| | | // 加载新的dll |
| | | DllUtils.loadDll(urlClassLoader.loadClass("iail.mdk.model.common.Environment"),dllFilePath); |
| | | } catch (Exception e) { |
| | | DllUtils.unloadJar(urlClassLoader); |
| | | throw new RuntimeException("加载dll异常",e); |
| | | } |
| | | // 都加载成功后加入缓存 |
| | | DllUtils.addClassLoaderCache(projectId,urlClassLoader); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |