ClassLoader
sun.misc.Launcher:初始化默认的3个ClassLoader
路径分隔符:unix使用:号,windows使用;号
JAVA_HOME:D:Program FilesJavajdk1.8.0_241
JRE_HOME:%JAVA_HOME%jre
Bootstrap ClassLoader
核心类加载器,默认加载路径%JRE_HOME%lib。启动JVM时通过设置-Xbootclasspath可改变加载路径
-Xbootclasspath::完全取代默认的加载路径
-Xbootclasspath/a::拼接到默认的加载路径后面(常用)
-Xbootclasspath/p::拼接到默认的加载路径前面
例如:java -Xbootclasspath/a:"D:Program FilesJavajdk1.8.0_241libools.jar" -jar xxx.jar
Extention ClassLoader
扩展类加载器,默认加载路径%JRE_HOME%libext。启动JVM时通过设置-Djava.ext.dirs可改变加载路径(覆盖默认的加载路径)
App ClassLoader
应用类加载器,加载classpath下的所有类
自定义类加载
双亲委派机制,也可继承java.net.URLClassLoader
package com.wyj.agent;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;public class MyClassLoader extends ClassLoader { public String filePath; public MyClassLoader(ClassLoader parent, String filePath) { super(parent); this.filePath = filePath; } @Override public Class findClass(String name) { name = name.replaceAll(".", "/"); byte[] data = loadClassData(name); return defineClass(null, data, 0, data.length); } private byte[] loadClassData(String name) { FileInputStream fis = null; byte[] data = null; try { File file = new File(filePath + File.separator + name + ".class"); System.out.println(file.getAbsolutePath()); fis = new FileInputStream(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int ch = 0; while ((ch = fis.read()) != -1) { baos.write(ch); } data = baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } return data; }}
类卸载
- 类的所有实例已被GC
- 加载该类的ClassLoader已被GC
- 该类的Class对象没有在任何地方被引用
- JVM自带的三种类加载器加载的类不会被卸载
ClassPath
.号代表的是当前目录
缺省值
当前目录
java className
CLASSPATH
系统环境变量,设置后会覆盖缺省值
java className
-classpath
若设置该参数,则会覆盖缺省值以及CLASSPATH
java -classpath "." className
-jar
CLASSPATH以及-classpath设置无效,只会以启动jar包为搜索范围(这也是为什么应用程序打包成可执行的jar包后,不管你怎么设置classpath都不能引用到第三方jar包的东西了),并且jar包里面的jar也无法被搜索
java -jar xxx.jar
引用第三方jar包的解决方案:
- 配置-Xbootclasspath
- 把第三方jar包放置到%JRE_HOME%libext目录下或者配置-Djava.ext.dirs
- 配置MANIFEST.MF文件中的Class-Path属性来引用第三方jar包
- 使用自定义类加载器
Manifest扩展机制
- 将第三方jar包copy到启动jar所在的目录或子目录下
- 编辑MANIFEST.MF文件中的Class-Path,例如:Class-Path: xxx1.jar lib/xxx2.jar
maven配置Class-Path
org.apache.maven.plugins maven-jar-plugin 2.5com.wyj.agent.MyAgent true lib/