Jruby: использование Pry с JRuby (и JRubyFx)

Как правильно использовать Pry gem с JRuby и JRubyFx в Windows?

Я использую JRubyFx (привязка JavaFX JRuby - https://github.com/jruby/jrubyfx), и для своего теста я использую этот пример, сжатый до минимально необходимых строк.

require 'jrubyfx'
require 'pry'

class SimpleFXApplication < JRubyFX::Application
    def start(stage)
    stage.title = "jrubyfx app"
    @ctrlr = SimpleFXController.load_fxml("some_fxml_code_for_ui.fxml", stage)
    stage.show
  end
end

class SimpleFXController < JRubyFX::Controller
end

SimpleFXApplication.launch
binding.pry

После запуска приложения I консоль больше не принимает ввод, и "pry" возвращается только после ввода окна, когда я закрываю окно SimpleFXApplication.

Я также пытался использовать потоки Java:

...
binding.pry
Java.java.lang.Thread.new do SimpleFXApplication.launch end

Но затем, хотя новый идентификатор потока показывается как работающий, SimpleFXApplication никогда не запускается.

Еще я попробовал запустить pry из консоли, а затем потребовать и запустить SimpleFXApplication:

Jruby -S Pry

требуют './jrubyfx_demo.rb'

правда

SimpleFXApplication.launch

И я получаю следующие ошибки...

Исключительная ситуация Приложение: java.net.MalformedURLException: неизвестный протокол: c java.net.URL.(Неизвестный источник) java.net.URL.(Неизвестный источник) sun.reflect.NativeConstructorAccessorImpl.newInstance0(собственный метод) sun.reflect.NativeConstructorAccessorImpl.newInstance(неизвестный источник) sun.reflect.DelegatingConstructorAccessorImpl.newInstance(неизвестный источник) java.lang.reflect.Constructor.newInstance(неизвестный источник) org.jruby.javasupport.JavaConstructor.newInstanceDirect(Java:ruru.jpg) java.invokers.ConstructorInvoker.call(ConstructorInvoker.java:104) org.jruby.java.invokers.ConstructorInvoker.call(ConstructorInvoker.java:197) org.jruby.runtime.callsite.CachingCallSite.jallB2 (CallSite.CallB) (org.jruby..java:211) org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:217) org.jruby.RubyClass.newInstance(RubyClass.java:862) org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.ru) или.internal.runtime.methods.JavaMethod$JavaMethodZeroOrOneOrTwoOrNBlock.call(JavaMethod.java:295) org.jruby.java.proxies.ConcreteJavaProxy$3 CachingCallSite.java:346) org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:204) org.jruby.ast.CallTwoArgNode.interpret(CallTwoArgNode.java:59) org.jruretNode.Nerp. NewlineNode.java:105) org.jruby.ast.BlockNode.interpret(BlockNode.java:71) org.jruby.ast.IfNode.interpret(IfNode.java:118) org.jruby.ast.AttrAssignOneArgNode.interpret(Attrg Java:33) org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) org.jruby.ast.BlockNode.interpret(BlockNode.java:71) org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.js:75) org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:268) org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:220) org.jruby.runtime.callsiteCacciteCacheCacheCacheCacheCache Java:366) org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:238) org.jruby.ast.FCallThreeArgNode.interpret(FCallThreeArgNode.java:40) org.jruby.ast.LinterAsgnNode Java:123) org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) org.jruby.ast.BlockNode.interpret(BlockNode.java:71) org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.js:75) org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:225) org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:204) org.jruby.suntime.CachingCallSite.cacheAndCall(CachingCallSite.java:346) org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:204) org.jruby.ast.CallTwoArgNode.interpret(CallTwoArgNode.java:59) org.jruby.ast.InstAsgnNode.interpret(InstAsgnNode.java:95) org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) org.jruby.ast.BlockNode.interpret(BlockNode.java:71) org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75) org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182) org.jrud..call(DefaultMethod.java:188) org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326) org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.jru.java:1).CallOneArgNode.interpret(CallOneArgNode.java:57) org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) org.jruby.ast.BlockNode.interpret(BlockNode.java:71) org.jruby.ast.RescueNode.executeBody(RescueNode.java:224) org.jruby.ast.RescueNode.interpret(RescueNode.java:119) org.jruby.ast.BeginNode.interpret(BeginNode.java:83) org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112) org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209) org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.jt. call (Interpreted19Block.java:128) org.jruby.runtime.Block.call(Block.java:89) org.jruby.RubyProc.call(RubyProc.java:261) org.jruby.RubyProc.call(RubyProc.java:213) org.jruby.javasupport.JavaUtil$1.call(JavaUtil.java:237) org.jruby.javasupport.util.RuntimeHelpers$MethodMissingMethod.call(RuntimeHelpers.java:445) org.jruby.mp.1. /jruby/gen/InterfaceImpl1014569521.gen:13) com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:215) com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179) com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176) java.security.AccessController.doPrivileged(собственный метод) com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176) com.sun.glass.ui.win.WinApplication._runLoop(собственный метод) com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29) com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73) java.lang.Thread.run(неизвестный источник) => ноль

Я предполагаю, что это как-то связано с тем, как JrubyFx использует потоки, или я не знаю, является ли это более общей проблемой, которая влияет на использование Pry с JRuby... Я хотел бы узнать больше, я был бы признателен, если бы кто-то мог поделись советом.

2 ответа

Решение

SimpleFXApplication.launch никогда не возвращается, пока не будет вызван Platform.exit (закрытие окон делает это в фоновом режиме)

Чтобы сделать то, что вы пытаетесь сделать, отключите метод start или какой-либо другой метод таймера, как только JavaFX запустит приложение.

Как один из разработчиков JRubyFX, я также могу рассказать вам, как работает многопоточность в JRubyFX/JavaFX:

  1. основной поток порождает поток JavaFX пользовательского интерфейса и ожидает блокировки из потока JavaFX
  2. Поток пользовательского интерфейса запускает кучу платформенных вещей
  3. Поток пользовательского интерфейса вызывает начало (этап)
  4. start (stage) устанавливает обработчики событий, пользовательский интерфейс и т. д. (здесь вы должны запустить pry)
  5. пользователь вызывает stage.show для запуска событий JavaFX (щелчок, перемещение мыши, нажатие клавиши, сворачивание и т. д.)
  6. поток событий обращается к потоку пользовательского интерфейса с обработчиками событий
  7. Пользователь сообщает, нажимая [x] или вызывая Platform.exit, что он хочет закрыть JavaFX
  8. stage.show получает блокировку события и возвращает
  9. Поток пользовательского интерфейса снимает блокировку на основном потоке.
  10. Поток пользовательского интерфейса очищается, а основной поток продолжается

В соответствии с этим:

Исключительная ситуация. Приложение: java.net.MalformedURLException: неизвестный протокол: c java.net.URL.(Неизвестный источник) java.net.URL.(Неизвестный источник)

У вас есть что-то в вашем конфигурационном файле, который определяет местоположение файла? Если так, какова там ценность?

Если вы используете "C:[что-то]", а C - ваш текущий диск, я бы посоветовал удалить "C:" на случай, если pry запутается в букве диска.

- Кит

Другие вопросы по тегам