2013-10-08 87 views
2

我在一個java swing應用程序中,它的WebService客戶端在jruby中實現。 用例是用戶單擊一個按鈕,相應的控制器將打開一個新的線程,並且此線程從本地數據庫獲取一個列表,並且列表中的每個項目都會運行一個jruby腳本(通過ScriptingContainer)。如何避免openssl上的jruby的錯誤文件描述符?

總是第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不知道問題出在哪裏。 我該如何避免這個壞文件描述符異常?

+0

前段時間我和jruby有過這個非常相同的錯誤。我也得到了「壞文件描述符」異常。 這是一個帶有運行jruby腳本的線程的swing應用程序,我在調用jruby之後放置了一個睡眠以允許關閉腳本連接,但問題仍然存在。最後,我們在純java中實現了所有的東西。祝你好運! – Walt

+0

試圖添加2秒的睡眠。在container.terminate之後,但仍然發生錯誤。 – tramuntanal

+0

也做了一個沒有線程的測試類的調用,它重複了10次對容器的相同調用,並且它工作。 – tramuntanal

回答

0

我回答我自己的問題: 這是openssl庫中的一個bug。在jruby郵件列表中提問,他們建議升級。 升級到JRuby 1.7.5解決了問題!

相關問題