Skip to content

luojun0513/classloader-playground

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Land

Build Status Coverage Status GitHub issues License

👉 一个简单的基于ClassLoader用于依赖隔离的容器实现。
# 在Java中依赖主要是Jar

依赖容器自然涉及下面的问题:

  • 可以从多处加载类,并分配不同的ClassLoader
  • ClassLoader之间有继承关系
    ClassLoader的继承关系会是一个树
  • 类加载会在上下级ClassLoader之间有委托关系,如:
    • 是否允许在上级ClassLoader中查找类。
      即是否 委托
    • 允许在上级ClassLoader查找哪些类/包。
      即可以配置 委托 的粒度。
    • 只允许在某级ClassLoader查找哪些类/包,会忽略这级ClassLoader的下级ClassLoader中这些类/包,不允许子ClassLoader
      即必须 委托

🔧 功能

1. ClassLoader委托关系的完备配置

完备委托关系可以先分析只有父子2层ClassLoader间委托关系的情况。

某个类的加载在两层父子ClassLoader间委托关系,按是否加载排列组合一共有4种情况:

  • 父不加载,子不加载【00】
    可以用来显式禁止某些类的加载。
    实际应用中应该 很少会用到。
  • 父不加载,子加载【01】
    子自理,父里即使包含了相同的类也不会污染子。实际场景:
    • 用来Tomcat容器自用Lib,不会影响到的Web应用。
  • 父加载,子不加载【10】
    一定使用的父的类。实际场景:
    • Tomcat容器的Servlet API,不允许被Web应用改写。
  • 父加载,子加载【11】
    两者可以加载的情况下,按谁优先分成2个Case:
    • 父优先。【Parent-Child】
      即是Java缺省的委托策略,代理模式(Delegation Mode)。
      这个委托策略可以保证Java核心库的类型优先加载,Java核心库的类的加载工作由引导类加载器来统一完成,保证了Java应用所使用的都是同一个版本的Java核心库的类,是互相兼容的。
    • 子优先。【Child-Parent】
      这种委托关系比较复杂,有引起类版本混乱的风险!:bomb:
      实际应用中应该 避免这种委托关系。 🙅

ℹ️
关于子优先【Child-Parent】类版本混乱的风险的细节原因看了后面参考资料就清楚了,这里只说一个简单例子:
子里有类Wheel;父里有类CarWheel;类Car引用了类Wheel
子加载类Car里通过实际是父来加载(子中没有这个类),返回的Car所引用Wheel是用CarClassLoader即父来加载。
子中直接使用Wheel时,由子来加载(子里有Wheel类)。
结果Car引用的类Wheel和子直接使用的类WheelClassLoader不同,即类型不兼容,看起来正确的赋值会抛出的ClassCastException

上面【11】的情况分成2个子Case,合起来一共有5种情况。

委托关系可以统一描述成:

  1. None
  2. Child-Only
  3. Parent-Only
  4. Parent-Child
  5. Child-Parent

按上面说明的2层委托关系约定,嵌套推广即可得到 包含 任意层ClassLoader的完备委托关系。:sparkles:

举个3层ClassLoader包含上面组合的例子说明一下:

TODO

2. 常用类加载方式

  • 加载本地类目录或Jar文件
  • 加载本地有类目录或Jar文件的目录
  • 加载网络上的类
    这个功能应该很少使用 😜 ,为了功能完整而说明。
  • 加密类工具/加载加密的类
    这个功能应该很少使用 😝 ,为了功能完整而说明。

🎨 使用场景

  1. 在一个JVM中部署多个应用,但应用依赖不互相影响。
    这样是提高 系统利用率的一种方式。
  2. 把平台级的二方库从应用中隔离出来,由架构部门统一升级。这样做的原因是:
    • 平台级二方库如果有Bug影响面广,有统一的升级的需求。
    • 平台级二方库升级使用面广,升级困难。

ℹ️
上面的部署方式中,依赖容器的引入对于应用的开发应该是 透明的。

🍺 目标

  • 给出类加载委托情况的完备说明
  • 给出类加载委托规则的规范描述
  • 给出类加载委托规则的规范描述的自己的一个描述格式
    对于这个项目会优先使用Properties来描述,简单够用。
  • 说明JavaClassLoader的用途和限制
  • 给出ClassLoader使用和实现的原则
  • ClassLoader使用和实现容易出错的地方
  • 整理出使用了ClassLoader的常见框架
  • 说明这些框架中ClassLoader的实现方法及其使用契约
  • 给出ClassLoader实现方法及其使用契约的最佳实践

📢 进阶目标

  • Web容器集成
  • 实现OSGi规范
    这个也可以用来验证实现是否面向编程友好

📚 相关资料

🔬 官方资料

ClassLoader

Permission

🔖 二手资料

ClassLoader

ClassLoader实际应用

安全

ClassLoader Memory Leak

About

a simple java dependency-isolation container via class loader.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 95.3%
  • Shell 4.7%