Как я могу создать глобальные КОНСТАНТЫ пространства имен во время инициализации Rails в Tomcat?
Сначала немного предыстории: у меня есть приложение Rails 2.2.2 со всеми видами зависимостей и настроек, которые не позволяют мне обновиться до 2.2.2. Текущий план состоит в том, чтобы перенести это приложение в JRuby (1.6.5), развернув его как войну в Tomcat (6.0.23 - еще не привязанную к этой конкретной версии FWIW), используя warbler (1.3.2) для его упаковки.
Я хочу, чтобы ветка JRuby приложения существенно не отличалась от приложения vanilla, поскольку я не знаю, сколько времени потребуется, чтобы выявить и устранить все проблемы, вызванные несоответствиями в средах выполнения. Так что я хочу иметь возможность продолжать чистое и легкое объединение в текущей работе из приложения vanilla.
Ряд настраиваемых поведений в приложении можно настроить с помощью глобальных констант пространства имен, установленных в environments/*.rb
файлы. Но эти значения могут быть переопределены с помощью файла конфигурации yaml или установки переменной среды оболочки; это прежде всего для гибкости в процессе разработки, где разные разработчики иногда должны настраивать различные параметры. До сих пор эта система работала хорошо, оставляя environments/development.rb
файл относительно стабилен и не перегружен, но все же дает нам большой контроль над настройкой во время взлома.
Я хотел бы сохранить эту систему настройки при переходе на JRuby. Пока я использую настроенный config/web.xml.erb
который преобразует соответствующие переменные окружения и настройки из файла yaml в <env-entry>
фрагменты, что делает их доступными во время инициализации через java:comp/env
JNDI контекст. В более ограниченных средах (таких как подготовка или производство) многие из этих настроек могут быть заблокированы путем включения соответствующих <Environment>
настройки в контейнере context.xml
файл с override
атрибут установлен в false
,
Все идет нормально. Но сейчас я пытаюсь превратить значения, извлеченные из контекста JNDI, в глобальные константы пространства имен во время инициализации. Вот выдержки из соответствующих битов:
конфигурации / среда /developer.rb:
...
envset "FOO", "baz"
FOO="fail" unless defined? FOO
printf "FOO is now '%s'\n", FOO
...
Библиотека / config_helper.rb:
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
web.xml:
...
<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>
...
catalina.out:
setting FOO to 'bar'
FOO is now 'fail'
Там, где я ожидаю, что эта последняя строка будет "FOO теперь" бар "", конечно. Линия 14 из lib/config_helper.rb
Кажется, там все идет не так. Подобный код отлично работал в vanilla ruby, но здесь он не работает во время инициализации в Tomcat.
Итак, как я могу создать глобальные КОНСТАНТЫ пространства имен из записей среды JNDI во время инициализации Rails в Tomcat?
1 ответ
Хорошее эмпирическое правило заключается в том, что всегда есть лучший ответ, чем eval()
, Замена строки 15 следующей строкой корректно создает константы в глобальном пространстве имен:
Object.const_set(value_name, value)
Я до сих пор не уверен, в каком пространстве имен исходные константы создавались, но Object
кажется "глобальным".