如何在Tomcat的Rails初始化期间创建全局命名空间CONSTANT?

时间:2011-12-09 19:41:47

标签: tomcat jruby jrubyonrails warbler jruby-rack

首先是一些背景:我有一个Rails 2.2.2应用程序,其中包含各种janky依赖关系和自定义设置,这使我暂时无法升级到2.2.2。目前的计划是将此应用程序迁移到JRuby(1.6.5),将其部署为Tomcat中的战争(6.0.23-尚未绑定到此特定版本FWIW),使用warbler(1.3.2)对其进行打包。 / p>

我想让应用程序的JRuby分支与vanilla应用程序大不相同,因为我不知道要花多长时间来梳理和解决运行时环境中的差异所导致的所有问题。因此,我希望能够继续干净利落地轻松融入来自香草应用程序的正在进行的工作。

应用程序中的许多自定义行为可以使用environments/*.rb文件中设置的全局命名空间CONSTANT进行配置。但是可以使用yaml配置文件或设置shell环境变量来覆盖这些值;这主要是为了在开发过程中的灵活性,不同的开发人员有时需要自定义各种设置。到目前为止,该系统运行良好,使我们的environments/development.rb文件相对稳定和整洁,同时在我们黑客攻击时仍然可以对我们进行大量的自定义控制。

我想在迁移到JRuby时保留这个定制系统。到目前为止,我使用的是自定义config/web.xml.erb,它将yaml文件中的相关环境变量和设置转换为<env-entry>个片段,这使得它们在初始化期间可通过java:comp/env JNDI上下文使用。在更受限制的环境(如登台或生产)中,可以通过在容器的<Environment>文件中包含相应的context.xml设置来锁定其中的许多设置,并将override属性设置为{{1 }}

到目前为止,这么好。但是现在我正在努力在初始化期间将从JNDI上下文检索的值转换为全局命名空间CONSTANT。以下是相关位的摘录:

配置/环境/ developer.rb:

false

LIB / config_helper.rb:

...
envset "FOO", "baz"
FOO="fail" unless defined? FOO
printf "FOO is now '%s'\n", FOO
 ...

的web.xml:

1  include Java
2  import javax.naming.InitialContext
3  import javax.naming.NameNotFoundException
4  
5  ctx = InitialContext.new
6  
7  def envset(value_name, default_value)
8      value = nil
9      begin
10         value = ctx.lookup("java:comp/env/#{value_name}")
11     rescue NameNotFoundException => e
12         value = default_value
13     end
14     printf "setting %s to '%s'\n", value_name, value
15     eval("%Q[ #{value_name} = '#{value}' ]")
16 end

catalina.out中:

...
<env-entry>
    <env-entry-name>FOO</env-entry-name>
    <env-entry-value>bar</env-entry-value>
    <env-entry-type>java.lang.String</env-entry-type>
</env-entry>
...

当然,我期待这最后一行是“FOO现在是'酒吧'”。 setting FOO to 'bar' FOO is now 'fail' 的第14行似乎是出错的地方。类似的代码在vanilla ruby​​中运行良好,但在Tomcat初始化期间它不起作用。

那么,如何在Tomcat的Rails初始化期间从JNDI环境条目中创建全局命名空间CONSTANT?

1 个答案:

答案 0 :(得分:0)

一个好的经验法则是总是eval()更好的答案。用以下行替换第15行正确地在全局命名空间中创建常量:

Object.const_set(value_name, value)

我仍然不确定原始创建常量的命名空间,但Object似乎是“全局”。