2013-10-08 3 views
2

Я в приложении java swing, у которого есть клиент WebService, реализованный в jruby. Вариант использования: Пользователь нажимает кнопку, соответствующий контроллер открывает новый поток, и этот поток берет список из локального БД, и для каждого элемента списка выполняется сценарий jruby (через ScriptingContainer).Как избежать дескриптора файла jruby's на openssl?

Всегда первые 2 или 3 вызова, что JRuby действительно преуспевает, но потом бросает:

org.jruby.embed.EvalFailedException: (Errno::EBADF) Bad file descriptor 
at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:133) 
at org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1264) 
at org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1309) 
at com.doctrans.AteaService.createMsgAndSend(AteaService.java:112) 
at com.doctrans.AteaService.communicateTransportation(AteaService.java:85) 
at com.doctrans.DocTransFacadeImpl.requestAteaCode(DocTransFacadeImpl.java:308) 
at com.doctrans.DocTransFacadeImpl.requestAteaLoadStockCodes(DocTransFacadeImpl.java:132) 
at com.doctrans.gui.controllers.RoutesCtrl$RequestTask.doInBackground(RoutesCtrl.java:501) 
at com.doctrans.gui.controllers.RoutesCtrl$RequestTask.doInBackground(RoutesCtrl.java:1) 
at javax.swing.SwingWorker$1.call(Unknown Source) 
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
at java.util.concurrent.FutureTask.run(Unknown Source) 
at javax.swing.SwingWorker.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 
Caused by: org.jruby.exceptions.RaiseException: (Errno::EBADF) Bad file descriptor 
at org.jruby.RubyIO.close(org/jruby/RubyIO.java:2052) 
at org.jruby.ext.openssl.SSLSocket.sysclose(org/jruby/ext/openssl/SSLSocket.java:704) 
at RUBY.close(jar:file:C:/DocTrans/data/DocTrans-2013.10.07.14.45.jar!/openssl/buffering.rb:447) 
at RUBY.close(jar:file:C:/DocTrans/data/DocTrans-2013.10.07.14.45.jar!/net/protocol.rb:76) 
at RUBY.transport_request(jar:file:C:/DocTrans/data/DocTrans-2013.10.07.14.45.jar!/net/http.rb:1338) 
at RUBY.request(jar:file:C:/DocTrans/data/DocTrans-2013.10.07.14.45.jar!/net/http.rb:1301) 
at RUBY.send_envio_documento_transporte(jar:file:C:/DocTrans/data/DocTrans-2013.10.07.14.45.jar!/pt/atea/client.rb:81) 
at RUBY.(root)(send_request_for_app.rb:50) 

Вот код, который повторяется для каждого элемента:

public String createMsgAndSend(RouteInfo routeInfo) throws IOException { 
    ScriptingContainer container = new ScriptingContainer(LocalContextScope.CONCURRENT); 
    String code = null; 
    try { 
     container.put("info", new Info()); 
     container.put("route_info", routeInfo); 
     container.put("logger", LoggerFactory.getLogger("RubyClient")); 
     container.put("user", UserHolder.getCurrentUser() 
       .getUser()); 
     container.put("pwd", UserHolder.getCurrentUser().getPwd()); 
     RubyObject response = (RubyObject) container.runScriptlet(
       PathType.CLASSPATH, "send_request_for_app.rb"); 
     Ruby ruby = container.getRuntime(); 
     boolean success = response.callMethod("fetch", 
       RubySymbol.newSymbol(ruby, "success")).isTrue(); 
     LOGGER.info("Success?: " + success); 
     String error = (String) response.callMethod("fetch", 
       RubySymbol.newSymbol(ruby, "error")).asJavaString(); 
     if (success && error.isEmpty()) { 
      code = (String) response.callMethod("fetch", 
        RubySymbol.newSymbol(ruby, "code")).asJavaString(); 
      LOGGER.info("Response code: " + code); 
     } else { 
      throw new ServiceException(routeInfo, error); 
     } 
    } finally { 
     if (container != null) { 
      container.resetWriter(); 
      container.resetErrorWriter(); 
      container.clear(); 
      container.terminate(); 
     } 
    } 
    return code; 
} 

JRuby сеть/http-код, который выбрасывает исключение:

 http= Net::HTTP.new(uri.host, uri.port) 
     http.use_ssl = true 
     http.ssl_version = 'SSLv3' 
     http.open_timeout= 5000 
     http.cert = OpenSSL::X509::Certificate.new(pem) 
     http.key = OpenSSL::PKey::RSA.new(pem, pem_key) 
     http.verify_mode = OpenSSL::SSL::VERIFY_PEER 
     request = Net::HTTP::Post.new(uri.request_uri) 
     http.finish if http.started? 

Я подозреваю, что это может быть связано с потоками java, bu t не знаю, где проблема. Как я могу избежать этого исключения дескриптора файла Bad?

+0

Некоторое время назад у меня была такая же ошибка с jruby. Я также получил исключение «bad file descriptor». Это было приложение swing с потоком, который запускает скрипт jruby, я поставил спать после вызова jruby, чтобы разрешить закрытие соединений сценария, но проблема осталась. В конце мы реализовали все в чистой java. Удачи! – Walt

+0

Попробовал добавить спать 2 сек. после container.terminate, но ошибка все еще происходит. – tramuntanal

+0

Также сделал тот же вызов из тестового класса без потоков, который повторяет один и тот же вызов в контейнере 10 раз и там он работает. – tramuntanal

ответ

0

Я отвечаю на свой вопрос: Это была ошибка в libs openssl. Спрошены в списке рассылки jruby, и они рекомендуют обновить. Обновление до JRuby 1.7.5 решило проблему!

Смежные вопросы