Итак, я пытаюсь развернуть свое приложение JRuby on Rails на Tomcat 7. Все работает нормально.
Пока я не попытался использовать функцию параллельного развертывания Tomcat, которая требует, чтобы имя контекста/войны имело форму name##VERSION.war
.
JRuby задыхается от этого в первый раз, когда я пытаюсь потребовать файл с ##
в пути со следующей трассировкой стека:
org.jruby.rack.RackInitializationException: no !/ in spec
from file:/opt/apache-tomcat-7.0.23/webapps/my-application##0001/WEB-INF/lib/jruby-rack-1.1.2.jar!/vendor/rack.rb:7:in `(root)'
from org/jruby/RubyKernel.java:1038:in `require'
from file:/opt/apache-tomcat-7.0.23/webapps/my-application##0001/WEB-INF/lib/jruby-rack-1.1.2.jar!/vendor/rack.rb:28:in `boot!'
from file:/opt/apache-tomcat-7.0.23/webapps/my-application##0001/WEB-INF/lib/jruby-rack-1.1.2.jar!/jruby/rack/boot/rack.rb:10:in `Rack'
from file:/opt/apache-tomcat-7.0.23/webapps/my-application##0001/WEB-INF/lib/jruby-rack-1.1.2.jar!/jruby/rack/boot/rack.rb:8:in `(root)'
from org/jruby/RubyKernel.java:1063:in `load'
from file:/opt/apache-tomcat-7.0.23/webapps/my-application##0001/WEB-INF/lib/jruby-rack-1.1.2.jar!/jruby/rack/boot/rack.rb:1:in `(root)'
at org.jruby.rack.DefaultRackApplicationFactory$4.init(DefaultRackApplicationFactory.java:206)
at org.jruby.rack.DefaultRackApplicationFactory.newErrorApplication(DefaultRackApplicationFactory.java:102)
at org.jruby.rack.DefaultRackApplicationFactory.getErrorApplication(DefaultRackApplicationFactory.java:66)
at org.jruby.rack.SharedRackApplicationFactory$1.call(SharedRackApplicationFactory.java:33)
at org.jruby.rack.AbstractRackDispatcher.process(AbstractRackDispatcher.java:30)
at org.jruby.rack.AbstractFilter.doFilter(AbstractFilter.java:31)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Как показывает трассировка стека, кажется, что он взрывается из-за требования. Может ли JRuby просто не обрабатывать пути этой формы? Есть ли способ обойти эту проблему, или это фундаментальный конфликт между JRuby и соглашением об именах Tomcat?
ОБНОВЛЕНИЕ
Я подключил отладчик к Tomcat, и проблема сводится к тому, как java.net.URL анализирует строки URL:
new URL("jar:file:/opt/apache-tomcat-7.0.23/webapps/my-app##001/WEB-INF/lib/jruby-rack-1.1.2.jar!/vendor/rack-1.3.6/rack.rb")
Это взрывается с MalformedURLException. Но:
new URL("jar:file:/opt/apache-tomcat-7.0.23/webapps/my-app/WEB-INF/lib/jruby-rack-1.1.2.jar!/vendor/rack-1.3.6/rack.rb")
Это идентично, за исключением ##001
в имени приложения, и работает нормально.
Между прочим, они вызываются в строке 1145 org.jruby.runtime.load.LoadService в JRuby.
Итак, каковы последствия этого? Ну, во-первых, похоже, что Tomcat, возможно, сделал плохо продуманный выбор символов, которые он использует для обозначения имен, если это создает проблемы при анализе URL-адресов. Я не уверен, сможет ли JRuby легко обойти это.
Мысли, кто-нибудь?
ДАЛЬНЕЙШЕЕ ОБНОВЛЕНИЕ
Вы можете заставить его работать, если вы URL-адрес избегаете хэшей. ## становится %23%23. Однако я думаю, что это нужно будет исправить в самом JRuby.