jar java classpath_Java ClassLoader和ClassPath

ClassLoader

0d06ecc781b7953cc8927f0d4453c8af.png

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包的解决方案:

  1. 配置-Xbootclasspath
  2. 把第三方jar包放置到%JRE_HOME%libext目录下或者配置-Djava.ext.dirs
  3. 配置MANIFEST.MF文件中的Class-Path属性来引用第三方jar包
  4. 使用自定义类加载器

Manifest扩展机制

  1. 将第三方jar包copy到启动jar所在的目录或子目录下
  2. 编辑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/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值