GithubHelp home page GithubHelp logo

any-door's Introduction

AnyDoor 任意门

目标:执行Spring项目任意对象的任意方法

执行项目的任意方法提出者:Lin ZiHao

适合场景

  • xxlJob
  • rpc入口
  • mq入口
  • 改动的测试

Tips:配合热加载可以做到随时修改即可测试

功能展示

功能展示

快速开始(结合插件)

总结:安装插件 -> 启动项目 -> 右键方法 -> 填写参数 -> Run

1 安装插件

1.1安装,方便快捷,但需要自由上网(推荐

1.2安装,提供了国内下载地址,但需要手动导入

1.1 直接插件市场下载(推荐)

插件市场直接搜索 anydoor

img.png

1.2 下载提供的压缩包

下载完成后导入到idea 国内下载地址 img.png

2 启动项目

平常方式启动java的main函数

Tips:一般情况下会主动填充运行进程的进程id(可在配置页面修改)

3 执行调用

  1. 找到想要执行的方法,右键弹出选择打开任意门(有对应的快捷键 control/command+shift+D)

img.png

  1. 填写要调用的参数,并点击 ok 按钮

img.png

  1. 你将会发现当前方法被执行了!(可进行断点查看)

插件属性说明

img.png img_1.png

核心包支持功能

  • 对象相关:
    • 对于是Spring注册的Bean,会通过上下文拿到对象(若有代理既是代理对象),执行当前方法
    • 对于非Spring注册的Bean,会通过反射创建对象,执行当前方法
  • 方法相关:
    • 支持同步或异步执行当前方法,默认异步
    • 支持私有方法
    • 打印响应结果
  • 参数相关:
    • 对给的参数进行序列化,支持json格式
    • 函数的参数支持lambda表达式入参,例如:Function的可以 A -> A
    • 时间支持:LocalDateTime传yyyy-MM-dd'T'HH:mm:ss、yyyy-MM-dd HH:mm:ss、yyyy-MM-dd

插件支持功能

  • 执行参数将会缓存
  • 可在任意地方重复上一次的调用
  • 配置页面可打印Idea插件的路径
  • 保留通过Http进行调用

地址

AnyDoorPlugin-idea插件中心

后续支持

详情见issues

发布版本

注意发布版本的时候记得要把依赖打进去

2.2.0 功能扩展版本

  • 支持提前执行任意代码(方便设置上下文)
  • 支持 Json 带有注释的内容

2.1.4

  • 支持高版本代码,调整默认支持未来所有版本
  • [fix]24.1版本报错问题

2.1.3 修复版本

  • 支持IDEA的24.1版本
  • 返回值是Optional类型直接打印内容
  • [fix]增加jsonKey判断逻辑

2.1.2 修复版本

  • 支持23.3版本
  • [fix]jsonKey的判断
  • [fix]批量情况接口的参数传递

2.1.1 代码提示和导航+批量参数+修复

  • 增加参数窗口填写Key的时候代码完成提示
  • 增加参数窗口Key的导航跳转
  • 支持批量参数批量的调用(数组格式)
  • [fix]打开参数窗口遇到文件失效
  • [fix]在黑色主题下窗口背景颜色不正确

2.0.2 修复版本

  • [fix]修复获取不到bean的情况

2.0.1 修复版本

  • [fix]修复私有方法丢失依赖

2.0.0 团队参数共享

  • 团队协助,共享调用参数 @zhouhao91
  • ui页面优化 @zhouhao91
  • [fix]无提供spring项目的调用
  • [fix]懒加载情况下会有无法实例化类情况
  • [fix]参数传递中文路径
  • [fix]重载方法参数有基本数据类型时报错问题 @jinghong

1.4.0 类加载隔离

  • 类加载隔离,和运行项目不做耦合,无依赖冲突问题
  • 支持没有 Spring 依赖的 Java 项目,插件运行无需使用方提供 Spring 依赖
  • 一个类多实例将会随机取一个实例
  • [fix]无参方法无记录上一次调用

项目说明

  • any-door-common:解决 attach 模块和 core 模块的共同依赖对象,减少重复代码
  • any-door-attach:Java 动态织入入口,插件进程调度到 Java 进程的入口
    • 重要入口 AnyDoorAttach#agentmain (执行到这个方法,说明成功对 Java 进程侵入了)
  • any-door-core:真正执行反射调用所在模块,以及支持各种扩展功能
    • 重要入口 AnyDoorService#run (一个是动态织入的入口,一个是非默认的 mvc 入口)
  • any-door-plugin: IDEA 插件 UI 相关实现所在模块
    • 重要入口 AnyDoorOpenAction#actionPerformed AnyDoorPerformed#invoke

如何参与开发

  • 启动 plugin 模块,将会打开一个新的沙盒 IDEA 进行调试
    • 更改 build.gradle.kts 文件下的 todo
    • 模块启动入口在 Gradle 的 Tasks -> intellij -> runlde
  • 对上面说到的重要入口进行打断点,然后再沙盒环境下操作即可

如何调试 agent 以及进程报错如何调试

导入attach 和 core 两个模块包到你自己的项目,在上面说明的重要入口打断点即可调试

<dependencies>
  <dependency>
    <groupId>io.github.lgp547</groupId>
    <artifactId>any-door-attach</artifactId>
    <version>${填写当前插件版本}</version>
  </dependency>
  <dependency>
    <groupId>io.github.lgp547</groupId>
    <artifactId>any-door-core</artifactId>
    <version>${填写当前插件版本}</version>
  </dependency>
</dependencies>

感谢

Tips:若觉得不错,可以点个Star(✨✨)或者评价

Tips:若觉得很不错或支持项目,可以❤️❤️❤️赞赏❤️❤️❤️

感谢以下项目支持

any-door's People

Contributors

code142857 avatar hyiki avatar lgp547 avatar meimingle avatar zhouhao91 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

any-door's Issues

可以适配 Kotlin 吗?

我的项目是 Java 和 Kotlin 混合的项目,我发现只能在 Java 代码上执行 any door,无法在 Kotlin 的代码上执行。

期望可以设置上下文信息

代码中通常有XXXContext.getUserId(),正常来说这些信息是从网关解析放入上下文的。
但是any-door触发的调试没有上下文信息。
期望any-door在每次执行前可以固定的执行一段代码块,主动的设置一些必要的上下文信息

idea升级到2024.1后插件报错

IntelliJ IDEA 2024.1 (Ultimate Edition)
Build #IU-241.14494.240, built on March 28, 2024
Runtime version: 17.0.10+8-b1207.12 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 11.0
GC: ZGC Cycles, ZGC Pauses
Memory: 4096M
Cores: 16
Registry:
ide.experimental.ui=true
terminal.new.ui=true
Non-Bundled Plugins:
io.github.lgp547.any-door-plugin (2.1.3)
Kotlin: 241.14494.240-IJ

com.intellij.diagnostic.PluginException: `ActionUpdateThread.OLD_EDT` is deprecated and going to be removed soon. 'io.github.lgp547.anydoorplugin.action.AnyDoorOpenAction' must override `getActionUpdateThread` and chose EDT or BGT. See ActionUpdateThread javadoc. [Plugin: io.github.lgp547.any-door-plugin]
	at com.intellij.diagnostic.PluginProblemReporterImpl.createPluginExceptionByClass(PluginProblemReporterImpl.java:23)
	at com.intellij.diagnostic.PluginException.createByClass(PluginException.java:90)
	at com.intellij.diagnostic.PluginException.reportDeprecatedUsage(PluginException.java:125)
	at com.intellij.openapi.actionSystem.ActionUpdateThreadAware.getActionUpdateThread(ActionUpdateThreadAware.java:21)
	at com.intellij.openapi.actionSystem.AnAction.getActionUpdateThread(AnAction.java:199)

gp大佬,我遇到了运行时的问题,启动app层的方法,提示空指针,对应报错代码是deviceItemService.list(queryWrapper);,是一个service注入

17:58:34.210 [Attach Listener] INFO i.g.l.a.u.SpringUtil - [doInit,64] - mmmmmmmmmmmmmmmmmmm any-door 1.3.2 springUtil init end mmmmmmmmmmmmmmmmmmm
17:58:34.249 [ForkJoinPool.commonPool-worker-19] INFO i.g.l.a.c.AnyDoorService - [lambda$futureResultLogConsumer$3,118] - any-door run listDevice exception:
java.util.concurrent.CompletionException: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314)
at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1702)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692)
at java.base/java.util.concurrent.ForkJoinTask.doExec$$$capture(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at io.github.lgp547.anydoor.core.AnyDoorHandlerMethod.doInvoke(AnyDoorHandlerMethod.java:97)
at io.github.lgp547.anydoor.core.AnyDoorHandlerMethod.invokeSync(AnyDoorHandlerMethod.java:40)
at io.github.lgp547.anydoor.core.AnyDoorHandlerMethod.lambda$invokeAsync$0(AnyDoorHandlerMethod.java:33)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1700)
... 8 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at io.github.lgp547.anydoor.core.AnyDoorHandlerMethod.doInvoke(AnyDoorHandlerMethod.java:95)
... 11 common frames omitted
Caused by: java.lang.NullPointerException: null
at com.ruoyi.web.controller.application.DeviceApplicationService.listDevice(DeviceApplicationService.java:169)
... 16 common frames omitted

date时间格式时区问题

date时间格式会有时区问题,代码是全局默认配置。能否支持全局配置时区和默认时间序列化格式。

启动的时候插件报错

IDEA 2023.3.2
AnyDoor 2.1.2

java.lang.NullPointerException: Cannot read field "clazz" because "this.context" is null
	at io.github.lgp547.anydoorplugin.dialog.ParamListUI.lambda$initToolBar$1(ParamListUI.java:102)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
	at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
	at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297)
	at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6657)
	at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3385)
	at java.desktop/java.awt.Component.processEvent(Component.java:6422)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5027)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4855)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4969)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4583)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4524)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2809)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4855)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:794)
	at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:739)
	at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:733)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:766)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:764)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:763)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.kt:695)
	at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.kt:635)
	at com.intellij.ide.IdeEventQueue._dispatchEvent$lambda$10(IdeEventQueue.kt:580)
	at com.intellij.openapi.application.impl.RwLockHolder.runWithEnabledImplicitRead(RwLockHolder.kt:75)
	at com.intellij.openapi.application.impl.RwLockHolder.runWithImplicitRead(RwLockHolder.kt:67)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.kt:580)
	at com.intellij.ide.IdeEventQueue.access$_dispatchEvent(IdeEventQueue.kt:72)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:355)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1$1.compute(IdeEventQueue.kt:354)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:793)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:354)
	at com.intellij.ide.IdeEventQueue$dispatchEvent$processEventRunnable$1$1.invoke(IdeEventQueue.kt:349)
	at com.intellij.ide.IdeEventQueueKt.performActivity$lambda$1(IdeEventQueue.kt:1014)
	at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:114)
	at com.intellij.ide.IdeEventQueueKt.performActivity(IdeEventQueue.kt:1014)
	at com.intellij.ide.IdeEventQueue.dispatchEvent$lambda$7(IdeEventQueue.kt:349)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:848)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.kt:391)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)

实现在填写参数的value可以提示Java类的静态属性等的代码完成

尝试使用语言注入实现,确实能做到想要的代码完成提示,但最终效果在部分场景会有报错且无法捕获,但不影响使用,故当前功能需要修复后再提供。

语言注入实现核心
image

相关commit(目前已在main注释):fe4bfa4

重现:反向commit,启动项目,在参数窗口的``中尝试引用第三方类。(value格式如下才会正确触发)

"key":"``"

希望:修复这个异常或使用其他方式实现功能

ClassPathResource的类加载器异常

使用ClassPathResource加载资源时异常,org.springframework.core.io.ClassPathResource默认使用了Thread.currentThread().getContextClassLoader(),建议设置为spring使用的类加载器

【新功能】支持批量参数批量的调用

目前已经支持批量调用(并发以及并行的方式),但参数是不可变的,要支持参数也是批量给定的批量调用。

场景:有下面方法,使用方提供3个id:1,2,3,希望可以一次交互,执行当前方法三次

public void test(int id, String name) {
}

提供参数格式可限定成:

{
    "id": [1, 2, 3],
    "name": ["1", "2", "3"]
}

完整的调试链路

记录下一串的方法执行并存储起来,支持后续一键重放整个链路的方法执行

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.