保命小诀窍:IDEA远程Debug技巧,你了解吗?
前言
昨天看到一个问题,“疫情结束后你最想吃什么?”
仔细想了一下,火锅?烤肉?
看了一下体重秤,怕是只能报个健身房了。
你以为你胖N斤的时间复杂度是O(2^N), 事实上它是O(1),嗖嗖的.
正文
回到正题
说到远程Debug这个功能,基本上大多IDE都会自带,但是一般情况下还真是很少用!
笔者切换到IDEA之后,还真再就没用过远程Debug,直到昨天发现了一个非常基础的错误
坑从何来
来自于我的开源小工具: https://gitee.com/vtDev/v-mock
笔者本意是打造一个,简单,轻巧,一键运行的接口模拟系统,用来方便等待他人接口的前端后端同学.
基于以上目的,我使用了嵌入式数据库sqlite,来配合Springboot,构造了无须配置,一行启动的小jar包. 目录结构如下,数据库直接扔在了Resource中:
开源后有使用的同学提了Bug,笔者也是正常操作,改完bug重新打版发行.
升级版本的同学,发现数据没了,笔者暂时给出了方案,嵌入式数据库嘛,把旧jar中的DB文件,覆盖到新Jar中就好了
(DB文件位于jar包中的位置)
说出这句话的时候,也不能完全赖瓦特了,毕竟Springboot+Sqlite这种奇葩组合也是为了工具的小巧性,偶尔尝试的产物.
事实上稍微想想,db文件和其他资源不一样,是要频繁改写的,当然改动的不是jar包中的原始文件.
直到收到了一个Issues,告诉了笔者DB文件复制到新jar中并没有生效.
笔者也迅速反应过来,怎么可能用的jar内的DB文件,真实文件不出意外是放在java.io.tmpdir下了.
java.io.tmpdir的路径,一般情况下,macos是在$TMPDIR,win则在%temp%.
笔者也切换到了对应的目录,终于看到了jar运行时真实使用的DB文件:
但是这个命名方式很奇怪啊,和原本的v-mock.sqlite并不沾边.
一路追随sqlite的jdbc驱动源码,找到了 org.sqlite.SQLiteConnection的extractResource方法,看到了命名代码:
其实看到这已经清晰了,源码中使用了sqlite-jdbc-tmp拼接了原始jar中DB文件的URL类的hashcode作为文件名.
之所以笔者开发的时候没注意到,看看这个方法第一个if判断就知道了。
笔者习惯用IDE中的Springboot或者Application模式直接启动项目,并不是打包后的启动方式
所以当Protocol是file而不是jar的情况,直接就使用了 target/classes/db/v-mock.sqlite文件,不用生成临时文件.
开发时,DB可视化工具也连接的是 target/classes/db/v-mock.sqlite,所以当时并没发现疑点.
事实上这是很正常的操作,很多地方的源码都有判断是普通web环境还是以jar运行的,如果有这方面的调试,要思考你的启动方式了.
那么想把断点打在第一个if之后,看到效果,选择之一就是可以使用远程Debug的方式.
IDEA的远程Debug
IDEA的远程Debug模块真的是设计十分贴心,傻瓜操作,命令都生成好了,不知道现在的eclipse版本有没有这么贴心.
从configuration中搜索remote模版,点击右上角的create configuration,就创建好了一个远程debug启动方式.
Debugger mode选择Attach to remote JVM即可,它还有一个选项是Listen to remote JVM,意如其名嘛,一个是主动附着到启动的程序,一个是被动监听程序。
ip和端口不用多说,笔者直接用的本地jar包,所以填了localhost,右边jdk版本如果使用其他版本的,需要调一下。
中间的文本框就是生成好的jvm参数了,非常人性化了,直接加入启动命令即可 java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 v-mock.jar
可以完全不用管命令什么意思,如果你想知道,笔者也大概解释一下:
- -agentlib:jdwp 最重要的参数,启动JDWP代理,JDWP全称就是Java Debug Wire Protocol,官方给的方便调试的工具.
- transport=dt_socket 通过socket方式传输数据,dt八成就是data transfer的缩写了.
- server=y 开启调试server端,注意,因为笔者上文选择的是Attach to remote JVM,所以这里才是y,等待有调试器Attach过来,如果你选了Listen模式,那么就是反过来的,调试器是server,这里就是n了.
- suspend=n 是否挂起,这里设置为n,也就是说程序正常跑,什么时候需要Attach就去Attach即可,如果设置为y,程序将会等待调试器Attach上才会继续执行,比如启动源码的调试场景.
- address=5005 调试端口设置为5005,当然其它端口也可以.
启动jar包,再以刚才创建的方式进行debug,期待的断点位置已经成功到达了.
结尾
找到原因后,笔者也顺着sqliteJDBC源码中命名的方式,开发了一种数据迁移的方式
即:自动或手动找到之前版本的数据库文件,复制一份,以新版本的hashcode命名即可.
Springboot+嵌入式数据库,是个非常“不正经”的组合,但是开发小工具还是蛮不错的,如果有遇到同样数据迁移问题的,不妨参考一下笔者的解决方案
相关文章
- Git、本地仓库、远程仓库、IDEA集成Git
- idea web项目 怎么配置 artifacts_springmvc配置视频
- IDEA循环MAP的快捷键和自己常用的循环MAP方式
- 【IDEA】idea设置默认maven配置, 避免每次设置maven「建议收藏」
- 手把手教你设置 IntelliJ IDEA 的彩色代码主题「建议收藏」
- 2022 IntelliJ IDEA 破解,最新idea破解教程(永久有效)
- idea配置Tomcat_tomcat docbase
- idea远程debug配置_debug调试教程
- idea构建springboot_jsp项目搭建过程
- idea格式化代码快捷键失效_idea格式化代码快捷键无效
- IDEa快捷键_idea进入方法快捷键
- IDEA注释详解_idea自定义注释模板
- 看了我常用的IDEA插件,同事也开始悄悄安装了...
- Java Doc简单使用(idea使用生成)
- 2022 IntelliJ IDEA 破解,最新idea破解教程(永久有效)
- 还在用 XShell - 试试 IntelliJ IDEA 的 SSH
- 【IDEA】打开项目model变成文件夹恢复方法
- IntelliJ IDEA使用spring Initializr快速构建SpringBoot项目
- IDEA 公司,又出新神器,一套代码适应多端!
- IDEA 插件上新! 生成接口文档就是这么快!
- 【错误记录】IntelliJ IDEA 编译 Groovy 项目报错 ( Groovy SDK is not configured for module )
- IntelliJ IDEA tomcat 远程Ddbug调试详解程序员
- 利用Idea连接MySQL数据库(idea连接mysql)
- a玩转Linux系统:使用IntelliJ IDEA(linux上的ide)
- Linux下如何安装IDEA?(linux安装idea)
- 使用IDEA实现MySQL数据库连接(idea链接mysql)
- 深入探索Idea运行Oracle的可能性(idea运行oracle)
- 快速掌握Idea 使用 Oracle数据库技巧(idea使用oracle)
- IDEA中集成兼容Redis缓存技术(redis集成idea)