当从ruby调用java时,JRuby无法强制将类型强制转换为自身

时间:2013-12-22 02:41:52

标签: java ruby jruby

我正在尝试与服务器中的java类接口以将它们与ruby一起使用,我需要提供回调类。不幸的是,JRuby似乎试图强迫一种类型自己,我不明白为什么它这样做并且没有尝试这样做。

我在ruby中有以下方法

def registerEvent(id, type, priority = :normal, ignoreCancelled = false, &handler)
  fullClassName = "org.bukkit.event." + type.join(".")
  fullType = java.lang.Class.forName fullClassName

  eventHandler = net.connorcpu.plugscript.EventHandler.new

  eventHandler.setHandlerId id
  eventHandler.setPriority matchToEnum(priority.to_s, org.bukkit.event.EventPriority)
  eventHandler.setEventType fullType
  eventHandler.setIgnoreCancelled ignoreCancelled

  handlerWrapper = EventExecutorWrapper.new(self, handler)
  eventHandler.setExecutor handlerWrapper

  puts eventHandler.java_class.to_s

  $context.registerEvent eventHandler # line 44 from the stacktrace
  return eventHandler
end

像这样使用

registerEvent(
  "edit the quit message because reasons",
  [:player, :PlayerQuitEvent]
) {|event|
  puts 'test message'
}

当我尝试使用它时,我得到以下stacktrace

[21:34:05 WARN]: TypeError: failed to coerce net.connorcpu.plugscript.EventHandler to net.connorcpu.plugscript.EventHandler
  registerEvent at <script>:44
         (root) at <script>:1
            run at SourceFile:617
[21:34:05 ERROR]: [PlugScript] [PlugScript] An exception occurred initializing the script file .\plugins\dev.rb
javax.script.ScriptException: org.jruby.embed.EvalFailedException: (TypeError) failed to coerce net.connorcpu.plugscript.EventHandler to net.connorcpu.plugscript.EventHandler
        at org.jruby.embed.jsr223.JRubyEngine.wrapException(JRubyEngine.java:104) ~[jruby.jar:?]
        at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:121) ~[jruby.jar:?]
        at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:146) ~[jruby.jar:?]
        at net.connorcpu.plugscript.ScriptedPlugin.reloadScript(ScriptedPlugin.java:46) [PlugScript.jar:?]
        at net.connorcpu.plugscript.PlugScript.loadRubyEngines(PlugScript.java:149) [PlugScript.jar:?]
        at net.connorcpu.plugscript.PlugScript.onEnable(PlugScript.java:47) [PlugScript.jar:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:218) [spigot.jar:git-Spigot-1207]
        at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:457) [spigot.jar:git-Spigot-1207]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:385) [spigot.jar:git-Spigot-1207]
        at org.bukkit.craftbukkit.v1_7_R1.CraftServer.loadPlugin(CraftServer.java:302) [spigot.jar:git-Spigot-1207]
        at org.bukkit.craftbukkit.v1_7_R1.CraftServer.enablePlugins(CraftServer.java:284) [spigot.jar:git-Spigot-1207]
        at net.minecraft.server.v1_7_R1.MinecraftServer.m(MinecraftServer.java:348) [spigot.jar:git-Spigot-1207]
        at net.minecraft.server.v1_7_R1.MinecraftServer.g(MinecraftServer.java:325) [spigot.jar:git-Spigot-1207]
        at net.minecraft.server.v1_7_R1.MinecraftServer.a(MinecraftServer.java:281) [spigot.jar:git-Spigot-1207]
        at net.minecraft.server.v1_7_R1.DedicatedServer.init(DedicatedServer.java:184) [spigot.jar:git-Spigot-1207]
        at net.minecraft.server.v1_7_R1.MinecraftServer.run(MinecraftServer.java:430) [spigot.jar:git-Spigot-1207]
        at net.minecraft.server.v1_7_R1.ThreadServerApplication.run(SourceFile:617) [spigot.jar:git-Spigot-1207]
Caused by: org.jruby.embed.EvalFailedException: (TypeError) failed to coerce net.connorcpu.plugscript.EventHandler to net.connorcpu.plugscript.EventHandler
        at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:133) ~[jruby.jar:?]
        at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:118) ~[jruby.jar:?]
        ... 15 more
Caused by: org.jruby.exceptions.RaiseException: (TypeError) failed to coerce net.connorcpu.plugscript.EventHandler to net.connorcpu.plugscript.EventHandler
        at RUBY.registerEvent(<script>:44) ~[?:?]
        at RUBY.(root)(<script>:1) ~[?:?]
        ... 1 more

感谢您对此提供任何帮助,我已经被遗忘了一段时间。

1 个答案:

答案 0 :(得分:0)

事实证明,这是与类加载器有关的问题。在代码的每个位置使用了两个独特的类加载器。解决方案是使用与创建脚本环境的代码相同的类加载器初始化JRuby脚本引擎。

engine = new ScriptingContainer(LocalContextScope.SINGLETHREAD, LocalVariableBehavior.PERSISTENT);
engine.setCompileMode(RubyInstanceConfig.CompileMode.JIT);
engine.setCompatVersion(rubyCompat());
engine.setClassLoader(PlugScript.class.getClassLoader());