1、织入入口,配置
1.1、织入入口
kilim.tools.Weaver是织入的主类,通过程序参数设置要织入的代码路径,可以是class文件、jar包、其他(是什么)、目录(目录中可以是jar包、class文件)。
如果传入的是class文件,会直接织入;调用kilim.tools.Weaver.weaveFile(String, InputStream, Detector)织入
如果是jar包,会解析jar文件,for循环时候,jdk会把for编译成iterator接口实现,对于jar文件,实际提取文件内容的是kilim.analysis.JarIterator,从java.util.jar.JarFile中直接获取所有entries,for循环中返回的每一项(class文件或者目录)都是FileLister.Entry的子类JEntry,可以获取文件名、文件流和文件大小。然后循环jar文件中每一项,如果是class文件就织入,调用接口同传入class文件一样。
如果是目录,则会递归目录,但是也只会处理目录下的class文件,不会处理目录下的jar包。处理方式类似jar包,会调用迭代器DirIterator处理,迭代器没有用递归实现,而是自己放入了个Stack。迭代时候每次返回FileLister.Entry的子类DirEntry。jar包验证,处理.
1.2、ant配置
<java classname="kilim.tools.Weaver" fork ="yes"> <classpath refid="kilim.classpath"/> <assertions> <enable/> </assertions> <arg value="-x" /> <!-- Skip classes that match ExInvalid. These are negative tests for the weaver. Also skip tests for this pass--> <arg value="ExInvalid|test" /> <arg value="-d" /> <arg value="./classes" /> <arg line="./classes" /> </java>
2、可织入分析 && 织入文件
2.1、织入接口kilim.tools.Weaver.weaveFile(String, InputStream, Detector)
在1中的织入入口会调用到,包括织入代码,把织入后的代码写到磁盘:
static void weaveFile(String name, InputStream is, Detector detector) throws IOException { try { ClassWeaver cw = new ClassWeaver(is, detector); cw.weave();//织入 writeClasses(cw);//把织入后的代码字节数据从ClassInfo写入到class文件 } catch (KilimException ke) { System.err.println("***** Error weaving " + name + ". " + ke.getMessage()); // ke.printStackTrace(); err = 1; } catch (RuntimeException re) { System.err.println("***** Error weaving " + name + ". " + re.getMessage()); re.printStackTrace(); err = 1; } catch (IOException ioe) { err = 1; System.err.println("***** Unable to find/process '" + name + "'\n" + ioe.getMessage()); } }
创建ClassWeaver的时候,传入的decetor是Detector.DEFAULT,一个默认的实现,这个类主要用来判断类是否需要织入、织入状态灯。
ClassWeaver封装了ClassFlow,ClassFlow是继承了ClassNode的,ClassNode是asm拿着类文件中所有内容构造的一棵树。在构造ClassWeaver的时候,就会构造一个ClassFlow对象:
public ClassWeaver(InputStream is, Detector detector) throws IOException { classFlow = new ClassFlow(is, detector); }cw.weave()[kilim.analysis.ClassWeaver.weave()]是织入的地方,包括对字节码的分析、通过ClassWriter织入、把植入后的字节码转换成ClassInfo对象:
public void weave() throws KilimException { classFlow.analyze(false);//分析 if (needsWeaving() && classFlow.isPausable()) { ClassWriter cw = new ClassWriter(false); accept(cw);//对需要进行织入的方法进行织入 addClassInfo(new ClassInfo(classFlow.getClassName(), cw.toByteArray()));//把需要植入后的字节码从ClassWriter放入到ClassInfo } }
ClassFlow.analyze(false),对一个方法是否需要织入的分析,方法isPausable为true的就是可织入的:
public ArrayList<MethodFlow> analyze(boolean forceAnalysis) throws KilimException { Detector save = Detector.setDetector(detector); try { cr.accept(this, false);//把当前ClassFlow实例传入到ClassReader中,会把当前类信息填充到ClassFlow中 for (Object o : this.fields) { FieldNode fn = (FieldNode) o; if (fn.name.equals(Constants.WOVEN_FIELD)) {//织入的时候会写入的一个变量,如果已经有了,则表明已经织入过 isWoven = true; break; } } if (isWoven && !forceAnalysis) return new ArrayList<MethodFlow>(); // This is a hack. 如果织入过并且不强制织入,就返回。强制呢? cr = null; // We don't need this any more. classDesc = TypeDesc.getInterned("L" + name + ';');//类型描述符 ArrayList<MethodFlow> flows = new ArrayList<MethodFlow>(methods.size()); String msg = ""; for (Object o : methods) { try { MethodFlow mf = (MethodFlow) o; if (mf.isBridge()) {//方法access_flag包含bridge的方法,方法由编译器产生 MethodFlow mmf = getOrigWithSameSig(mf);//获取bridge方法对应的原始方法 if (mmf != null) mf.setPausable(mmf.isPausable());//把birdge方法的pausable属性设置给原始方法 } mf.verifyPausables();//验证可织入性,如果已经织入或者不需要织入是直接返回了的 if (mf.isPausable()) isPausable = true; if ((mf.isPausable() || forceAnalysis) && (!mf.isAbstract())) { mf.analyze(); } flows.add(mf); } catch (KilimException ke) { msg = msg + ke.getMessage() + "\n-------------------------------------------------\n"; } } if (msg.length() > 0) { throw new KilimException(msg); } methodFlows = flows; return flows; } finally { Detector.setDetector(save); } }
相关推荐
在kilim-0.6这个压缩包中,包含了kilim库的源码、文档和其他相关资源。使用者可以通过阅读源码了解其内部实现机制,或者直接将其导入到项目中使用。kilim的核心特性包括: 1. **异步消息传递**:每个Actor都有自己...
协程Coroutine和Kilim是两个与并发编程相关的概念,主要在Java开发环境中被讨论。在现代软件系统中,多线程和并发处理是提升性能和响应能力的关键技术。协程提供了一种轻量级的并发模型,它比传统的线程更高效,内存...
Kilim 是一种 Java 消息传递框架,提供了超轻量级的线程,推动了线程之间迅速、安全、无需复制的消息传递的实现。 Kilim 使用 Java 编写,融入了角色模型的概念。在 Kilim 中,“角色” 是使用 Kilim 的 Task 类型...
JAVA版本他的系统源码Kilim :JVM 的延续、纤维、Actor 和消息传递 Kilim 由 2 个主要组件组成: Kilim weaver 修改已编译的 java 类的字节码,启用一种方法来保存它的状态并放弃对其线程的控制,即协同多任务 Kilim...
该项目是一款基于Kilim、Promise JDeferred、Zookeeper和Spring Boot技术的协程驱动分布式调用聚合框架。源码包含223个文件,涵盖143个Java源文件、33个XML配置文件、13个GIF图片、7个JAR包、5个批处理脚本、4个属性...
《kilim-motifs:基于Lindenmayer系统的程序化Kilim图案生成》 ...同时,"kilim-motifs"也提供了一个实例,说明了开源软件如何促进创新,让全球的开发者都能参与到艺术和技术的融合之中,推动生成艺术的发展。
### vivo X9 主板原理图及 PCB 板图解析 #### 概述 本文将针对“vivo X9 主板原理图及 PCB 板图”进行深入解析,旨在为相关技术人员提供维修参考与技术支持。vivo X9 作为一款广受欢迎的智能手机型号,其主板设计...
通过以上介绍,我们可以看到Jungle Server Core提供了强大的灵活性和可扩展性,无论是从协议支持还是处理器设计,都能满足复杂的服务场景需求。开发者可以根据自身业务特点,充分利用这些特性来构建高效稳定的服务器...
Coroutine是基于Kilim/Promise JDeferred的协程式驱动框架,基于Apache Zookeeper的分布式规则存储和动态规则变更通知。 主要特性: 1. 基于微服务框架理念设计 2. 支持同步/异步调用 3. 支持串行/并行调用 4....
在Java中,虽然语言本身并不直接支持协程,但在Sun JDK 7发布之前,开发者可以借助其他工具或语言,如Scala和Kilim,来实现协程的概念。 Scala是一种基于JVM的多范式编程语言,它不仅支持面向对象编程,还支持函数...