这是 8 年前的问题 here从那以后8年过去了。我想再问这个问题,看看有没有人开发过做猴子补丁的框架、工具或库。
基本上我需要它的是一个 java 应用程序,我应用了我自己的补丁。由于这个项目由另一个团队维护,我希望能够保留/应用我制作的任何补丁,到他们制作的补丁。
最佳答案
有许多技术可能适用于此,但您的问题过于模糊,无法将它们缩小为一个答案。
在 Ruby 中使用的字面意义上的“猴子修补”(即“在运行时替换类的方法”,参见例如 [1])可以使用“Java 代理”和“重新转换”API,但是它比在 Ruby 中要难得多。
I need it for a java application that I applied my own patch to
如果您有某个应用程序的源代码,请输入 git ,然后您可以 fork 他们的项目,应用您自己的补丁并构建修改后的版本。
I want to be able to keep apply any patch I make, to the patches they make.
如果您在分支上创建补丁,那么使用 git 会很容易将“上游”项目中的任何 future 更改引入您的分支,并构建一个新的修改版本。
一种更接近 Monkey Patching 的简单技术是从目标应用程序编译单个类,并进行修改,并将其放在类路径中比原始 JAR 更早的位置。 (这在旧的 Monkey Patching q 在这个答案中有介绍:https://stackoverflow.com/a/381240/8261)
JVM 按名称加载所有类,并将使用它在类路径中为任何类找到的第一个类文件,因此您可以从要修改的项目中逐个替换类。如果您有目标项目的源代码,则将其逐个文件复制到您的应用程序中,然后将您的补丁应用于 java 源代码。
(您将需要使用此方法手动应用任何 future 的上游更改。)
JVM 有一个名为“Java Agents”的 API,它允许您注册代码以在加载类时修改类。
还有一个“retransform”API 可让您更改已加载类的定义。这是由 JRebel 使用的更新正在运行的应用程序中的代码。 Ruby 的猴子修补程序的局限性要大得多,因为您不能添加或删除方法(您可以更改方法体)。
此机制被https://github.com/fommil/class-monkey 使用例如,“猴子补丁”一个 JVM 错误。
关于java - 是否可以在 Java 中进行猴子修补,如果不能,是否有其他选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42139413/
类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
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案