Как заставить компилятор scala работать в среде OSGi
Я использую шаблонизатор Scala (Scalate) для компиляции шаблонов во время выполнения в среде OSGi (Scala 2.9.1). Шаблоны не могут быть предварительно скомпилированы, потому что они создаются динамически.
Чтобы это работало, компилятор Scala должен работать в среде OSGi. Однако, поскольку компилятор Scala не может принимать загрузчик классов в качестве входных данных, это не работает "из коробки".
Из моего исследования, кажется, есть два общих подхода к решению:
1) Плагин компилятора Scala ( здесь он запущен, но с 2009 года его не трогали, а в списке 2009 года сообщалось, что он не готов к использованию.
2) Создание виртуальной файловой системы поверх контекста пакета, которая затем может использоваться компилятором Scala. Судя по всему, парни из Apache успешно использовали этот подход на старой версии Scala.
Кто-нибудь заставил Scalate, Scala 2.9.1 и OSGi работать вместе для динамической компиляции шаблонов?
2 ответа
В моей команде сейчас есть компиляция и выполнение Scala для Scalate в OSGi.
В общем, параметры ScalaCompiler должны быть предоставлены с набором объектов AbstractFile, которые соответствуют соответствующим пакетам OSGi. Это поддерживается Guggla, на что ссылается @michid. Но хотя Guggla предоставляет слой AbstractFile, он пока не предоставляет никаких примеров или кода для создания экземпляров AbstractFile в среде OSGi. Пример кода для выполнения последнего можно найти в проекте Sling (происхождение самого Guggla), а также в проекте Scalate (см. ScalaCompiler, но обратите внимание на наши изменения в нем ниже).
Мы выбрали OSGi-ified scala-комплекты ( компилятор и библиотека) из проекта ServiceMix. Смотрите выпуск SMX-1048 (с патчем) в комплекте scala-компилятора.
Наше первоначальное намерение состояло в том, чтобы заставить это работать в Scalate, и поэтому остальная часть этого ответа специфична для этого проекта.
В коде Scalate уже была большая часть логики, необходимой для работы в среде OSGi, включая виртуальный уровень AbstractFile, а также установку пути к классам компилятора. Однако нам нужно было установить Scalate ( https://github.com/scalate/scalate/pull/16), чтобы он заработал:
1) Переопределение OsgiCompiler класса ScalaCompiler не было включено должным образом, поэтому пакеты не были обнаружены как входы classpath для компилятора, и
2) Загрузчик классов выполнения шаблона (во время выполнения) был настроен на загрузчик классов пакета с ядром скалирования, что приводило к появлению CNFE во время выполнения.
Вышеприведенный запрос на изменение настраивает Scalate в среде OSGi по умолчанию для загрузчика классов потока-контекста во время выполнения. Это, кажется, самый простой способ получить ссылку на загрузчик классов вызывающей стороны без необходимости явно вставлять ее вызывающей стороне (например, Spring-DM). osgi:service
объявление экспорта службы шаблона может использовать context-class-loader="service-provider"
атрибут, чтобы установить это автоматически. Это также делает поведение Scalate OSGi во время выполнения соответствующим существующему поведению во время компиляции, которое уже использовало TCCL.
Поэтому вызывающий Scalate должен установить TCCL в свой собственный загрузчик классов или явно внедрить нужный загрузчик классов в шаблонизатор, например templateEngine.classLoader = ...
перед выполнением шаблона.
Обновление 31 августа 2012: Scalate master теперь содержит все патчи, упомянутые в этом посте.
Обновление 10 апреля 2013: Scalate 1.6.1, с компиляцией шаблона во время выполнения с помощью компилятора Scala, совместим с OSGi. Также Scala 2.10 и выше являются действительными пакетами OSGi, как выпущено.
Я думаю, что вам нужно установить политику друзей. Следующее должно помочь.
http://wiki.eclipse.org/index.php/Context_Class_Loader_Enhancements
http://www.eclipsezone.com/eclipse/forums/t90282.html
В вашем пакете вы можете сказать, что вам нужно использовать тот же загрузчик классов, что и в другом пакете.