2013-10-08 73 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解决了问题!

相关问题