简体   繁体   中英

How can I monkey patch JRuby to give it a pseudo file system?

Previously I was trying to give the Java engine for JavaScript - rhino - a pseudo file system and I have had success ( jszip maven plugin )

I now am turning my attention to the SASS compiler

I have integrated JRuby into my Maven plugin and I can call through to the SASS compiler just fine, so now the final step (before the great refactoring from hack-land to maintainable code) is to fake out the paths that JRuby sees,

My feeling is that I will not be able to reuse my Rhino trick (where I remap the java.io.File class adapter in the Rhino scope) as Ruby in general does not have adapter layers to correct for the differences between different Ruby VMs

So my next thought was monkey patch... But I am unsure how big a job that would be...

With JavaScript I just had to fake java.io.File , java.io.FileReader , java.io.FileWriter , java.io.FileInputStream , java.io.FileOutputStream

How much would I need to monkey patch in the Ruby runtime... Or am I better using an ASM based rewriting classloader to pull the rug from under JRuby itself (where I risk breaking legitimate File use to load eg Gems)

An answer to my specific problem with regards to the SASS compiler, but not an answer to the general question of what to do to monkey-patch JRuby to give it a fake file system.

It turns out that Sass has a concept of an Sass::Importer::Base which is the base class for resolving .scss and .sass files. So all I needed to do is create my own implementation which delegates to my virtual file system and configure the options passed to Sass::Engine.new such that the default file-system based importer is replaced with my Importer implementation.

Seems to be working though I have had some issues trying to get it to compile Foundation 3 perhaps due to it relying on Compass which contrasts with the testing experience I had for LESS support, where Bootstrap is stand-alone.

Update

With regard to the ASM based rewriting classloader. Perhaps the trick in that approach is to use AspectC to modify only those classes in the JRuby runtime. In other words, only apply the aspect if the class extends RubyObject. That should retain the legitimate needs of JRuby to load the ruby source code, while giving the embedded VM the fake file system.

With regard to Monkey-patching, it seems there would be a lot of work filling in all the equivalent methods that Ruby's File APIs provide in order to ensure that the monkey patch holds, and especially given that we don't know the exact footprint of what APIs the SASS compiler will use.

So, I guess the full answer is: "You don't want to do either monkey-patching or ASM rewriting as the library you want to use provides a nice abstraction to allow feeding it the virtual filesystem anyway"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM