Class Loading ---(类装载机制,开发者不得不知道的故事) --中篇

ArcGIS Pro新手避坑:从OpenStreetMap导入路网到创建拓扑关系全流程 本文详细解析了ArcGIS Pro中从OpenStreetMap导入路网数据到创建拓扑关系的全流程,涵盖OSM数据特性、几何完整性检查、属性强化及拓扑关系构建等关键步骤。特别针对路网数据预处理、网络数据集配置和常见问题提供了实用解决方案,帮助GIS新手高效完成网络分析任务。 阅读详情
我们是否需要自定义的ClassLoader?
 
    理由之一: 如果我们自定义了ClassLoader,那我们便可以控制JVM的加载动作了。
  
   上面说一个class标识是由于package+classname组成得。 对于所有实现java.io.Serializable接口得类, 由serialVersionUID管理这些类得版本(RMI,JNDI,Security里都有这样一个ID) 。它用64位的Hash来表示 (由于classname,filed,method组成)。从技术上讲如果classname,field,mehtod所构成的Hash都一样,那就会认为是同一个版本。
  假设有这样一个情况,我们要写一个java 执行引擎(比如:用一个RMI 发布一个Server端程序,执行client的接口), 既然要能执行,那引擎肯定要实现有Client所特定任务的接口(这里为TaskIntf)。  一但任务提交给执行引擎,Server要做的第一件事情就是要装载所有要执行的代码。 假设不同的终端递交了不同的代码。而偏偏又都是同样的包名,和同样的类名。 那服务器能否会辨别到底是那个Client提交过来的执行请求?
 
  现在出个问题: 如果在服务器端一个执行程序执行两个客户端提交同一个版本得代码,如何才让客户端会得到预期的执行结果? 
  别以为这个很简单,下面我先建个RMI玩玩。看看结果会是怎样。
  答案就在本文得代码里(这时候我也想知道:)
 
  本地文件如下图。
 
 
图 2 程序目录结构 (本文中含代码)。
 
在samepath目录下, 有着两个version.Version.class,他们得包名类名都一样,唯一不同的是。
v1目录中的方法是:
    public void fx(){
        log("this = " + this + "; Version.fx(1).");
    }
v2目录中的方法是:
    public void fx(){
        log("this = " + this + "; Version.fx(2).");
    }
 
执行一下看看:
set CLASSPATH=.;%CURRENT_ROOT%/v1;%CURRENT_ROOT%/v2
%JAVA_HOME%/bin/java Test 结果如下图


图 3. classPath得目录设为v1

 
切换到
set CLASSPATH=.;%CURRENT_ROOT%/v2;%CURRENT_ROOT%/v1
%JAVA_HOME%/bin/java Test
结果如下图:


图 4. classpath目录设为v2

 

很明显,上面的例子中能从classpath中找到先后次序。如果我们把v1,v2的version.Version。都删调。而把他们打成一个myextension.jar包,放到java.ext.dirs目录下。。这时候就通过ExtClassLoader来装载了,而不是AppClassLoader.

 

那结果会是下面得:


图 5. AppClassLoader and ExtClassLoader

注意看 sun.misc.Launcher$ExtClassLoader@a9c85c 这下是有ExtClassLoader 加载了。

 

继续往下看,另外一个例子。 在differentversions 目录下的例子,里面包含了RMI的ServerImpl这样一个执行引擎。Client实现了common.TaskIntf接口。 两个 client.TaskImpl分别如下:

    static{
        log("client.TaskImpl.class.getClassLoader
        (v1) : " + TaskImpl.class.getClassLoader());
    }

    public void execute(){
        log("this = " + this + "; execute(1)");
    }

 另一个则是:

     static{
        log("client.TaskImpl.class.getClassLoader
        (v1) : " + TaskImpl.class.getClassLoader());
    }

    public void execute(){
        log("this = " + this + "; execute(2)");
    }

这样子来执行(顺序随便,这里把 %CURRENT_ROOT%/client2放在前面):

CLASSPATH=%CURRENT_ROOT%/common;%CURRENT_ROOT%/server;
    %CURRENT_ROOT%/client2;%CURRENT_ROOT%/client1
%JAVA_HOME%/bin/java server.Server

先启动Server..

  分别把两个client提交给服务器执行, (即便执行程序中得client1.bat 和 client2.bat server监控屏幕如图6所示。) 


图 6. Execution Engine Server console

 

在来看下面两个图(图7和图8),分别是client端得执行反映。


图 7. Execution Engine Client 1 console



图 8. Execution Engine Client 2 console

 

纵观上面三次执行结果,发现由于服务器启动得时候使用了AppClassLoader.所以无论怎么样都是载入得是client2(因为client2的classpath次序比较在前),

这里client1 很郁闷,它在自己那执行明明是  execute(1) 通过 RMI 发送给服务器端执行就成了 execute(2)..

值得注意的是: 在client1,client2分别发送给服务器执行之后,服务器端显示的记录是:
client.TaskImpl.class.getClassLoader(v2):sun.misc.lancuher@AppClassLoader@xxxx zhiz只执行了一次。而
this=client.TaskImpl@xxxxx execute(2);执行了两次

上面已经讲到过了,对于一个ClassLoader来讲 同样的page+className 只能定义一个 class,而不同的ClassLoader即便加载同一个page.className 也会定义不同的class

 

到这里,我才发现,解决上面提出得那个问题似乎并不容易。:(。

那如何解决呢?答案就是---使用自定义得classLoader ..

如果各位等不急的话, 先请看(目录中 differentversionspush 里面的代码)

很显然,我们很有必要写自定义的classloader.



图 8. Execution Engine Client 2 console

 

纵观上面三次执行结果,发现由于服务器启动得时候使用了AppClassLoader.所以无论怎么样都是载入得是client2(因为client2的classpath次序比较在前),

这里client1 很郁闷,它在自己那执行明明是  execute(1) 通过 RMI 发送给服务器端执行就成了 execute(2)..

值得注意的是: 在client1,client2分别发送给服务器执行之后,服务器端显示的记录是:
client.TaskImpl.class.getClassLoader(v2):sun.misc.lancuher@AppClassLoader@xxxx zhiz只执行了一次。而
this=client.TaskImpl@xxxxx execute(2);执行了两次

上面已经讲到过了,对于一个ClassLoader来讲 同样的page+className 只能定义一个 class,而不同的ClassLoader即便加载同一个page.className 也会定义不同的class

 

到这里,我才发现,解决上面提出得那个问题似乎并不容易。:(。

那如何解决呢?答案就是---使用自定义得classLoader ..

如果各位等不急的话, 先请看(目录中 differentversionspush 里面的代码)

很显然,我们很有必要写自定义的classloader.


图 7. Execution Engine Client 1 console



图 8. Execution Engine Client 2 console

 

纵观上面三次执行结果,发现由于服务器启动得时候使用了AppClassLoader.所以无论怎么样都是载入得是client2(因为client2的classpath次序比较在前),

这里client1 很郁闷,它在自己那执行明明是  execute(1) 通过 RMI 发送给服务器端执行就成了 execute(2)..

值得注意的是: 在client1,client2分别发送给服务器执行之后,服务器端显示的记录是:
client.TaskImpl.class.getClassLoader(v2):sun.misc.lancuher@AppClassLoader@xxxx zhiz只执行了一次。而
this=client.TaskImpl@xxxxx execute(2);执行了两次

上面已经讲到过了,对于一个ClassLoader来讲 同样的page+className 只能定义一个 class,而不同的ClassLoader即便加载同一个page.className 也会定义不同的class

 

到这里,我才发现,解决上面提出得那个问题似乎并不容易。:(。

那如何解决呢?答案就是---使用自定义得classLoader ..

如果各位等不急的话, 先请看(目录中 differentversionspush 里面的代码)

很显然,我们很有必要写自定义的classloader.



图 8. Execution Engine Client 2 console

 

纵观上面三次执行结果,发现由于服务器启动得时候使用了AppClassLoader.所以无论怎么样都是载入得是client2(因为client2的classpath次序比较在前),

这里client1 很郁闷,它在自己那执行明明是  execute(1) 通过 RMI 发送给服务器端执行就成了 execute(2)..

值得注意的是: 在client1,client2分别发送给服务器执行之后,服务器端显示的记录是:
client.TaskImpl.class.getClassLoader(v2):sun.misc.lancuher@AppClassLoader@xxxx zhiz只执行了一次。而
this=client.TaskImpl@xxxxx execute(2);执行了两次

上面已经讲到过了,对于一个ClassLoader来讲 同样的page+className 只能定义一个 class,而不同的ClassLoader即便加载同一个page.className 也会定义不同的class

 

到这里,我才发现,解决上面提出得那个问题似乎并不容易。:(。

那如何解决呢?答案就是---使用自定义得classLoader ..

如果各位等不急的话, 先请看(目录中 differentversionspush 里面的代码)

很显然,我们很有必要写自定义的classloader.

【学习系列】SAP RAP 7:行为定义-Draft 本文介绍了RAP框架中的草稿表(Draft)功能及其应用。草稿表允许用户临时保存数据,在激活前不影响业务逻辑,支持保存继续、暂存和设备切换功能。草稿分为独占草稿(仅限同一用户编辑)和协作草稿(允许多用户协同编辑)。启用草稿需在行为定义和投影中包含标准action,并创建包含TotalETag等管理字段的草稿表。TotalETag确保草稿转换时活动数据未被修改,而ETagmaster则防止并发修改。文章通过OData调用示例详细说明了ETag验证过程,强调草稿功能由RAP框架自动处理,开发者只需关注定义和配置 阅读详情

相关推荐

Markdown编辑器介绍

这篇文章介绍了Markdown编辑器的功能和使用方法。主要内容包括:Markdown的基本语法如标题、列表、链接插入等;新增功能如图片拖拽、数学公式支持、甘特图和UML图表绘制;常用快捷键说明;以及文本导出导入操作。文章详细说明了如何通过Markdown语法实现文本格式化、代码高亮、表格创建等功能,并提供了多种图表绘制的语法示例,帮助用户更好地利用Markdown编辑器进行写作和内容创作。

soso1968的博客 1181

自定义ClassLoader动态加载Class

1、自定义ClassLoader代码如下: package zmx.classloader.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;

零度的博客专栏 5282

深入理解DQN中的Q值:核心概念和应用

在强化学习中,Q值(或称为动作价值函数)是核心概念之一。Q值函数 ( Q(s, a) ) 表示在给定状态 ( s ) 下,采取动作 ( a ) 并遵循某策略后,智能体从当前状态到未来状态所能获得的预期总回报。简言之,Q值是评估特定状态和动作对的好坏的指标。

qlkaicx的博客 2978

保证 load class from system class loader first!

曾经看到这样一个 classloader  的设计: 系统公共 class loader 支持一个配置, 如果配置为 "true", 则其在load class 时, 先从公共classloader和 system classloader 中找这个类; 如果配置为 "false", 则先从系统各个子模块的classloader 中找, 找不到, 在从公共classloader和 system

L 的专栏 813

Cursor集成Claude 4.6免费版:本地IDE合规调用指南

大语言模型编程助手(LLM Copilot)已成为现代开发标配,其核心能力依赖于上下文理解、代码推理与结构化输出等关键技术原理。Anthropic官方提供的Claude系列模型,尤其Claude 4.6,凭借200K超长上下文、tool use函数调用和严格可控的API设计,在工程实践中展现出显著技术价值。该能力可无缝嵌入本地IDE环境,支撑代码解释、跨文件分析、单元测试生成等高频开发场景。本文聚焦Cursor这一开源可审计IDE,详解如何合规复用Anthropic免费tier接口(/v1/messages

weixin_34095889的博客 539

Android 12.0 framework系统修改安兔兔等显示的屏幕尺寸大小功能实现

在12.0的系统rom定制化开发中,在使用第三方app检测系统的一些信息中,比如安兔兔 设备信息等检测app中,有时候显示的屏幕尺寸大小和 产品规格书等信息不同,稍微有些差异,所以就需要看下系统framework层中,相关的设备信息是怎么读出来的,然后做些调整 接下来就来分析相关功能

安卓兼职framework和app工程师的博客 478

maven plugin classloader加载class问题

1. 写一个基于maven的插件 今天在写基于maven plugin的一个小程序,它的功能是在maven执行package 阶段将已经打好包,从这个包中抽取分布式服务中依赖的类,之后会将这些服务器端依赖的类打成一个包。也就是执行了mvn package之后会在工程的target中生成两个jar包,一个是服务器端部署包,一个是客户端依赖包。客户端依赖包是服务器端包的一个子集。 该插件就是负责抽

莫正华 3153

矢量网络分析仪校准:原理、方法与系统适配性

矢量网络分析仪(VNA)校准是射频测量的关键环节,通过误差建模(12项误差项)和标准件测量,可将系统不确定度从±5dB降至±0.1dB以下。主流校准方法包括SOLT(适用于同轴系统)和TRL(适用于波导系统),二者在标准件、误差重点及频率上限等方面存在显著差异。随着6G与量子通信的发展,动态实时校准将成为新趋势。工程师需根据传输结构、频率范围及精度需求选择合适方法,确保测量精度。

u014344410的博客 263

Class Loading ---(类装载机制,开发者不得不知道的故事) --上篇

 也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然后将将诉的内容都包含了最基本的原理,希望你能更加深入了解自己所使用得语言。  理解CLassLoader 如果你自己定义叻一个 org.test.Object 。你在程序中这样写:import ort.test.ObjectObject o = n

JESoft -- Garden 1710

论文阅读:Universal and Transferable Adversarial Attacks on Aligned Language Models. LLM Attacks

因为“即开即用”的大型语言模型能够生成大量令人反感的内容,近期的工作集中在对这些模型进行对齐,以防止不受欢迎的生成。尽管在规避这些措施方面取得了一些成功——即所谓的针对大型语言模型(LLMs)的“越狱”——这些攻击需要大量的人类智慧,并且在实践中很脆弱。自动对抗性提示生成的尝试也取得了有限的成功。在本文中,我们提出了一种简单有效的攻击方法,可以导致对齐的语言模型生成令人反感的行为。

CSPhD-winston的博客 1419

【AI Agent 记忆共享实战】【下篇】多 Agent 会话 Session 统一共享实战:全链路工程落地、采集归一、MCP 服务、私有化部署、源码级实战

中篇我们已经锁定最终最优架构方案: 非侵入式、外部旁路采集、只读归一、中心化存储、MCP 按需检索注入。摒弃「改 Agent 源码」「软链接互通」「原生 Session 互导」等不现实方案。本篇直接落地可上线、可简历复用、可个人私有化部署多 Agent 异构 Session专属采集器(Claude/CODex/DSH/OpenCode/Kimi/WorkBuddy/ 豆包)统一消息归一化解析层(解决所有 Schema 异构)增量同步、去重、时间戳对齐核心逻辑。

十年老程序猿,AI 疯狂研究专家,前沿硬核知识分享 485

Class Loading ---(类装载机制,开发者不得不知道的故事)

也许你认为Class Load是一个高级话题,不管怎样,作为开发者你还是要了解它。 本文基于最新得JDK5,然而将诉的内容却包含了最基本的原理,希望你能更加深入了解自己所使用得语言。  理解CLassLoader 如果你自己定义了一个 org.test.Object 。你在程序中这样写:import ort.test.ObjectObject o = new S

土豆仙成长之路 6529

元学习与Transformer的结合:Meta-Transformer架构解析

我们生活在一个信息爆炸的时代,每天都会产生海量的数据。在深度学习领域,如何让模型更高效地学习、更快地适应新的任务,一直是科学家们努力的方向。元学习和Transformer都是深度学习中的重要概念,它们各自有着独特的优势。本文的目的就是深入剖析将元学习和Transformer结合起来的Meta - Transformer架构,探讨它的原理、应用以及未来发展。我们会从基础概念讲起,逐步深入到架构的各个方面,让大家对Meta - Transformer有一个全面的了解。

AI智能探索者的博客 1054

Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇

如何构造使用自定义的ClassLoader既然自定义的ClassLoader,能解决上述问题,那接下去看看,我们如何来使用自定义的ClassLoader。结合本文种的原码---(在differentversionspush的目录里),有个FileSystemClassLoader,类图描述如下:图9. 看看他的方法 findClassBytes(String className);

土豆仙成长之路 2295

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

上一篇: Class Loading ---(类装载机制,开发者不得不知道的故事) --上篇
下一篇: Class Loading ---(类装载机制,开发者不得不知道的故事) --下篇
start_java
博客等级 码龄22年 5粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值