草庐IT

java - 在运行时替换某些方法的内容

coder 2023-05-18 原文

我想在运行时替换一些方法的内容。

我知道我可以为此使用 javassist,但它不起作用,因为我想增强的类已经由系统 classLoader 加载。

如何在运行时替换方法的内容?我应该尝试卸载类(class)吗?我怎样才能做到这一点 ?我看到这是可能的,但我不知道该怎么做。

如果可能,我想避免为此使用外部库,我想自己编写代码。

更多信息: - 我想增强的类包含在一个框架中(在一个 jar 文件中) - 我的代码实际上是这个框架的一个插件 - 我的插件运行的框架有它自己的classLoader,但是这个classLoader不加载它自己的类(它把它们委托(delegate)给系统类加载器) - 我使用的框架是Play

感谢您的帮助!

最佳答案

可以使用 Javaassist 以及任何其他字节码工程库来完成。神奇之处在于 Java Attach API,它允许程序附加到正在运行的 JVM(并修改加载的类)。

可以在 com.sun.tools.attach 中找到包,顾名思义,是特定于 Oracle JVM 的。尽管如此,jstackjmap 等 JDK 工具使用它来支持它们的“附加到正在运行的 JVM”功能,因此可以肯定地说它会继续存在。

Attach API 上的文档描述性很强,而这个 Oracle blog post演示在运行时附加代理。一般来说,它归结为:

  • 使用 premain 等以“常规”-javaagent 方式制作重新转换程序
  • premain 重命名为 agentmain
  • 创建一个临时 JAR 文件,其中包含您的代理类并有一个 list 将 Agent-Class 指向您的代理(agentmain-包含)类,并且 可以- Retransform-Classes 设置为 true
  • 获取目标JVM(可能是同一进程)的PID,并将临时jar附加到它上面

谢天谢地,API 无需您做太多工作就可以做到这一点,但如果您在运行时生成 JAR,打包代理所需的所有类可能会有点棘手。

我希望包含一个演示代理来演示在运行时附加分析器,但它最终太长而无法发布。尽管如此,我还是把它放在了 Github repo 中。 .

此方法的

一个警告 是它使您的程序依赖于 JDK 附带的 tools.jar,而 JRE 中不存在该 tools.jar。您可以通过将 tools.jar 与您的应用程序一起(或在其中提取)来解决此问题,但您仍然需要提供 Attach API 所需的 attach native 库你的申请。我已经在上面链接的存储库中包含了我可以找到的所有平台的库,尽管您也可以自己获取它们。

根据您的用例,这可能是理想的,也可能不是理想的。但它确实有效!


这在问题中并不清楚,但如果您希望在运行时使用您自己的类完全“热交换”一个类,则不需要使用任何字节码操作库。相反,您可以单独编译您的类(确保相同的包、类名等)并在目标上调用 transform 时简单地返回新类的字节类。

关于java - 在运行时替换某些方法的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11749409/

有关java - 在运行时替换某些方法的内容的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  6. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  7. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  10. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

随机推荐