我如何在嵌入式JRuby中使用gems-in-a-jar?

Tom*_*son 6 rubygems jruby javax.script gems-in-a-jar

我想使用优秀的Sass作为构建过程的一部分.我的构建过程由Gradle管理.这意味着编写一个插件来运行Sass.Sass是Ruby,Gradle是Groovy,但是由于Groovy在JVM上运行,我可以使用JRuby来运行它,使用Java 脚本API.Gradle脚本以jar文件的形式获得依赖关系; 我可以从Maven Central获得JRuby ,但我需要自己将Sass打包成jar.

我试图遵循尼克·西格尔(Nick Sieger)的宝石手套来做这件事,但没有成功.无论我做什么,我都无法让JRuby拿起Sass宝石.

为了隔离这个问题,我写了一个最小的Java(不是Gradle)程序试图通过JRuby使用Sass - 我创造性地称之为JSass:

有两三个有趣的位.第一个是脚本generate-gem-jar.sh,它构建了gem jar:

gem install -i build/gems sass --no-rdoc --no-ri
jar cf lib/gemsass.jar -C build/gems .
Run Code Online (Sandbox Code Playgroud)

第二个是运行JRuby 的so.demo.JSass类:

ScriptEngine rubyEngine = new ScriptEngineManager().getEngineByName("jruby");
ScriptContext context = rubyEngine.getContext();
context.setAttribute("inputFile", inputFile, ScriptContext.ENGINE_SCOPE);
String script = IOUtils.toString(JSass.class.getResourceAsStream("sassdriver.rb"));
rubyEngine.eval(script, context);
Run Code Online (Sandbox Code Playgroud)

第三个是主要类试图用来操作Sass的Ruby脚本:

require 'sass'
template = File.load(inputFile)
sass_engine = Sass::Engine.new(template)
output = sass_engine.render
puts output
Run Code Online (Sandbox Code Playgroud)

该程序能够加载JRuby引擎并执行脚本,但它失败了require 'sass',说:

LoadError: no such file to load -- sass
  require at org/jruby/RubyKernel.java:1033
   (root) at <script>:1
org.jruby.embed.EvalFailedException: (LoadError) no such file to load -- sass
    at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:132)
    at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:90)
    at so.demo.JSass.main(JSass.java:24)
Caused by: org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- sass
Exception in thread "main" javax.script.ScriptException: org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- sass
    at org.jruby.embed.jsr223.JRubyEngine.wrapException(JRubyEngine.java:115)
    at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:93)
    at so.demo.JSass.main(JSass.java:24)
Caused by: org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- sass
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

kar*_*res 2

在我看来,只有当它作为 a 执行时它才会起作用java -jar -rgems.jar ,您可以使其工作,您不需要将其打包在 .jar 中,只需将sass-xxx目录( 的结果gem install sass)并将其存储在已知位置并将其 lib 目录添加到$LOAD_PATH... 因为您已经构建了 jar,所以我假设它位于当前工作目录中:

rubyEngine.eval("$LOAD_PATH << 'file://gemsass.jar!/gems/sass-3.1.15/lib'", context);
Run Code Online (Sandbox Code Playgroud)

这需要在你的最后一行之前发生rubyEngine.eval(script, context);

如果它不在 jar 中,它应该是相同的,只需指定路径即可,例如

rubyEngine.eval("$LOAD_PATH << 'file:/home/42/gems/sass-3.1.15/lib'", context);
Run Code Online (Sandbox Code Playgroud)

请注意,只有当 sass gems 不依赖于其他 gems 时,这才有效!