ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

记一次gradle 插件开发 分析 android studio Unable to delete file 异常

2021-08-18 02:03:16  阅读:272  来源: 互联网

标签:插件 jar gradle 编译 Unable 进程 守护 加载


代码传送门

 

在用javassist 开发gradle插件时

可能很多人碰到这个问题  第一个想到的重启idea 网上比较多的办法就是   

1. 重启android studio

2.任务管理器里面杀掉java进程

 

但是 每次重新编译的时候都会出现这个问题,总不能每次冷编译都重启 android studio把,很多人都说是as的bug,但感觉不应该,不然谷歌应该早修复了

 

对照任务管理器   发现插件编译的时候多了好几个java进程,应该是删不掉的文件被这几个进程占用了。

Gradle 守护进程(有时也称为构建守护进程) 的目的是改善 Gradle 的启动和执行时间。 那么会不会是gradle 守护进程的原因呢

于是尝试用gradle  stop 来杀掉 守护进程  然后重新gradle clean  发现文件能删掉了  守护进程默认能存活4小时  总不能编译一次等4小时把 我还不如重启

 

于是又想到  能不能在gradle 编译结束的时候启动一个task直接杀掉守护进程    gradle本身可以直接用groove语言  可以直接在需要监听的task 加上doLast的监听

问题又来了  并行开发肯定不只是在wins  mac上如果也碰到类似问题呢

 

继续定位问题   一个个文件来排查   一开始以为是kotlin的问题   

单java  单kotlin 多类 一次次编译     分析  发现 如果是类继承了系统类的话 就是造成这个错误

 

总结下来 应该时 某个类如果引用到了  第三方jar库中的包     编译执行完   进程会继续持有该jar包  导致文件被占用而无法删除    定位到问题了 那么目标就是怎么让进程释放对jar的持有

于是问题变成了 javassist 类加载器 怎么释放 对jar的引用

Jar 在Java中是用URLClassloader来加载的   现在项目中是用javassist默认的加载器   没法直接拿到加载jar的类加载器

                    mClassPool.appendClassPath(new JarClassPath(jarInput.getFile().getAbsolutePath()));

 

那么是否可以自定义 类加载器来加载jar呢    通过分析javassist源码   找到了

VisitableURLClassLoader   他是实现Urlclassloader的一个类加载器

自定义类加载器
                urls = new URL[input.getJarInputs().size()];
                int len = input.getJarInputs().size();
                ClassLoader parent;
                for (int i=0;i<len;i++) {
                    JarInput jarInput = input.getJarInputs().get(i);
                    jarSet.add(jarInput)
                    urls[i] = jarInput.getFile().toURI().toURL()
                }
                parent = mClassPool.getClassLoader().getParent()
                jarLoader= new VisitableURLClassLoader("third jar",urls,parent);
                mClassPool.appendClassPath(new LoaderClassPath(jarLoader))

  

所有操作处理完后  释放jar

            ClassLoaderUtils.tryClose(jarLoader)

  

编译后文件完美删除   

 

标签:插件,jar,gradle,编译,Unable,进程,守护,加载
来源: https://www.cnblogs.com/dikeboy/p/15154941.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有