Apache Groovy - Apache Groovy

Groovy
Groovy-logo.svg
Отличный логотип
ПарадигмаОбъектно-ориентированный, императив, сценарии
РазработаноДжеймс Страчан
РазработчикГийом Лафорж (председатель PMC)
Йохен Теодору (технический руководитель)
Пол Кинг
Седрик Шампо
Впервые появился2003; 17 лет назад (2003)
Стабильный выпуск3.0.6 (26 сентября 2020 г.; 2 месяца назад (2020-09-26)[1]) [±]
Предварительный выпуск
4.0.0-alpha-1/26 сентября 2020 г.; 2 месяца назад (2020-09-26)[1]
Печатная дисциплинаДинамический, статический, сильный, утка
ПлатформаJava SE
ЛицензияЛицензия Apache 2.0
Расширения имени файла.groovy, .gvy, .gy, .gsh[2]
Интернет сайтзаводной язык.org Отредактируйте это в Викиданных
Основной реализации
Gradle, Грааль
Под влиянием
Ява, Python, Рубин, Болтовня
Под влиянием
Котлин

Apache Groovy это Ява -синтакс-совместимый объектно-ориентированный язык программирования для Платформа Java. Это одновременно статика и динамичный язык с функциями, похожими на Python, Рубин, и Болтовня. Его можно использовать как язык программирования и язык сценариев для платформы Java, скомпилирован в Виртуальная машина Java (JVM) байт-код, и без проблем взаимодействует с другим кодом Java и библиотеки. Groovy использует синтаксис фигурных скобок похож на Java. Groovy поддерживает закрытие, многострочные строки и выражения, встроенные в строки. Большая часть возможностей Groovy заключается в его AST преобразования, запускаемые через аннотации.

Groovy 1.0 был выпущен 2 января 2007 г., а Groovy 2.0 - в июле 2012 г. Начиная с версии 2, Groovy может быть скомпилирован статически, предлагая вывод типа и производительность близка к Java.[3][4] Groovy 2.4 был последним крупным выпуском в рамках Основное программное обеспечение спонсорство, которое закончилось в марте 2015 года.[5] С тех пор Groovy изменил свою структуру управления на Комитет по управлению проектами в Фонд программного обеспечения Apache.[6]

История

Джеймс Страчан впервые рассказал о разработке Groovy в своем блоге в августе 2003 года.[7] В марте 2004 года Groovy был представлен JCP как JSR 241.[8] и принято голосованием. В период с 2004 по 2006 год было выпущено несколько версий. Процесс сообщества Java (JCP) были начаты усилия по стандартизации, изменилась нумерация версий, и 2 января 2007 года была выпущена версия под названием «1.0». После того, как различные бета-версии и версии-кандидаты получили номер 1.1, 7 декабря 2007 года был выпущен Groovy 1.1 Final и сразу же перенумерован. как Groovy 1.5, чтобы отразить многие внесенные изменения.

В 2007 году Groovy выиграл первый приз конкурса JAX 2007 за инновации.[9] В 2008, Грааль, Groovy веб-фреймворк, получил вторую премию на конкурсе инноваций JAX 2008.[10]

В ноябре 2008 г. SpringSource приобрела компанию Groovy and Grails (G2One).[11] В августе 2009 г. VMware приобрел SpringSource.[12]

В апреле 2012 года, после восьми лет бездействия, руководитель специализации изменил статус JSR 241 на неактивный.[8]

Страчан молча покинул проект за год до выпуска Groovy 1.0 в 2007 году.[нужна цитата ] В октябре 2016 года Страчан заявил: «Я все еще люблю Groovy (конвейеры jenkins такие классные!), Java, go, машинописный текст и kotlin».[13]

2 июля 2012 г. был выпущен Groovy 2.0, в который, помимо других новых функций, добавлены статическая компиляция и проверка статического типа.

Когда Основное программное обеспечение совместное предприятие было выделено Корпорация EMC (EMC) и VMware в апреле 2013 года Groovy и Grails вошли в их портфель продуктов. Pivotal прекратил спонсировать Groovy и Grails с апреля 2015 года.[5]В том же месяце Groovy изменил свою структуру управления с репозитория Codehaus на Комитет по управлению проектами (PMC) в Фонд программного обеспечения Apache через свой инкубатор.[6]Groovy окончил инкубатор Apache и стал проектом высшего уровня в ноябре 2015 года.[14]

Функции

Наиболее допустимые файлы Java также являются допустимыми файлами Groovy. Хотя эти два языка похожи, код Groovy может быть более компактным, поскольку ему не нужны все элементы, необходимые Java.[15] Это позволяет Java-программистам постепенно изучать Groovy, начиная со знакомого синтаксиса Java, прежде чем приобретать больше Groovy. идиомы программирования.[16]

Функции Groovy, недоступные в Java, включают как статические, так и динамичный ввод (с ключевым словом def), перегрузка оператора, собственный синтаксис для списков и ассоциативные массивы (карты), встроенная поддержка обычные выражения, полиморфная итерация, строковая интерполяция, добавлены вспомогательные методы и оператор безопасной навигации ?. для автоматической проверки нулевые указатели (Например, переменная? .method (), или же переменная? .field).[17]

Начиная с версии 2 Groovy также поддерживает модульность (возможность поставлять только необходимые jar-файлы в соответствии с потребностями проекта, что сокращает размер библиотеки Groovy), проверку типов, статическую компиляцию, улучшения синтаксиса Project Coin, блоки с множественным захватом и постоянное повышение производительности с помощью invokedynamic инструкция введена в Java 7.[18]

Groovy обеспечивает встроенную поддержку различных языки разметки Такие как XML и HTML, выполняется с помощью встроенного Объектная модель документа (DOM) синтаксис. Эта функция позволяет определять и управлять многими типами разнородных активов данных с помощью единообразного и краткого синтаксиса и методологии программирования.[нужна цитата ]

В отличие от Java, файл исходного кода Groovy может быть выполнен как (некомпилированный) сценарий, если он содержит код вне какого-либо определения класса, если это класс с главный метод, или если это Работоспособен или же GroovyTestCase. Сценарий Groovy полностью анализируется, компилируется и генерируется перед выполнением (аналогично Python и Ruby). Это происходит под капотом, и скомпилированная версия не сохраняется как артефакт процесса.[19]

GroovyBeans, свойства

GroovyBeans это версия Groovy JavaBeans. Groovy неявно генерирует геттеры и сеттеры. В следующем коде setColor (цвет строки) и getColor () генерируются неявно. Последние две строки, которые, похоже, обращаются к цвету напрямую, на самом деле вызывают неявно сгенерированные методы.[20]

учебный класс AGroovyBean {  Нить цвет}def myGroovyBean = новый AGroovyBean()myGroovyBean.setColor('нежно голубые')утверждать myGroovyBean.getColor() == 'нежно голубые'myGroovyBean.цвет = оловянныйутверждать myGroovyBean.цвет == оловянный

Groovy предлагает простой и последовательный синтаксис для обработки списки и карты, напоминающий Java множество синтаксис.[21]

def movieList = ['Дерсу Узала', 'Ран', 'Семь самураев']  // Выглядит как массив, но представляет собой списокутверждать movieList[2] == 'Семь самураев'movieList[3] = "Касабланка"  // Добавляет элемент в списокутверждать movieList.размер() == 4def monthMap = [ 'Январь' : 31, 'Февраль' : 28, 'Марш' : 31 ]  // Объявляет картуутверждать monthMap['Марш'] == 31  // Доступ к записиmonthMap['Апреля'] = 30  // Добавляет запись на картуутверждать monthMap.размер() == 4

Расширение прототипа

Groovy предлагает поддержку для расширение прототипа через ExpandoMetaClass, Модули расширения (только в Groovy 2), похожие на Objective-C Категории и ДелегированиеMetaClass.[22]

ExpandoMetaClass предлагает предметно-ориентированный язык (DSL), чтобы легко выразить изменения в классе, аналогично Руби концепция открытого класса:

Число.метакласс {  sqrt = { Математика.sqrt(делегировать) }}утверждать 9.sqrt() == 3утверждать 4.sqrt() == 2

Изменения кода Groovy в процессе прототипирования не видны в Java, поскольку каждый вызов атрибута / метода в Groovy проходит через реестр метакласса. Доступ к измененному коду можно получить только из Java, перейдя в реестр метаклассов.

Groovy также позволяет переопределять методы как getProperty (), propertyMissing () среди прочего, позволяя разработчику перехватывать вызовы объекта и указывать для них действие в упрощенном аспектно-ориентированный путь. Следующий код включает класс java.lang.String ответить на шестнадцатеричный свойство:

перечислить Цвет {  ЧЕРНИТЬ('#000000'), БЕЛЫЙ('#FFFFFF'), КРАСНЫЙ('# FF0000'), СИНИЙ('# 0000FF')  Нить шестнадцатеричный  Цвет(Нить шестнадцатеричный) {     это.шестнадцатеричный = шестнадцатеричный   }}Нить.метакласс.getProperty = { Нить свойство ->  def stringColor = делегировать  если (свойство == шестнадцатеричный) {    Цвет.значения().найти { Это.имя().equalsIgnoreCase stringColor }?.шестнадцатеричный  }}утверждать "БЕЛЫЙ".шестнадцатеричный == "#FFFFFF"утверждать "СИНИЙ".шестнадцатеричный == "# 0000FF"утверждать "ЧЕРНИТЬ".шестнадцатеричный == "#000000"утверждать "ЗЕЛЕНЫЙ".шестнадцатеричный == ноль

Фреймворк Grails широко использует метапрограммирование, чтобы ГОРМ динамические искатели, например User.findByName ('Джош') и другие.[23]

Точка и скобки

Синтаксис Groovy позволяет в некоторых ситуациях опускать скобки и точки. Следующий отличный код

брать(кофе).с(сахар, молоко).и(ликер)

можно записать как

брать кофе с сахар, молоко и ликер

создание возможностей для развития предметно-ориентированные языки (DSL), которые выглядят как простой английский.

Функциональное программирование

Хотя Groovy в основном является объектно-ориентированным языком, он также предлагает функциональное программирование Особенности.

Закрытие

Согласно документации Groovy: «Замыкания в Groovy работают аналогично« указателю на метод », позволяя писать и запускать код в более поздний момент времени».[24] Замыкания Groovy поддерживают свободные переменные, то есть переменные, которые не были явно переданы ему в качестве параметра, но существуют в контексте его объявления, частичное применение (что это термин 'карри '[25]), делегирование, неявные, типизированные и нетипизированные параметры.

При работе с коллекциями определенного типа можно сделать вывод о закрытии, переданном операции над коллекцией:

список = [1, 2, 3, 4, 5, 6, 7, 8, 9]/*  * Ненулевые числа приводятся к истине, поэтому, когда это% 2 == 0 (даже), это ложь. * Тип неявного параметра "it" может быть определен средой IDE как целое число. * Это также может быть записано как: * list.findAll {Целое число i -> i% 2} * list.findAll {i -> i% 2} */def шансы = список.найти все { Это % 2 }утверждать шансы == [1, 3, 5, 7, 9]

Группа выражений может быть записана в закрывающем блоке без ссылки на реализацию, а отвечающий объект может быть назначен позже с помощью делегирования:

// Этот блок кода содержит выражения без ссылки на реализациюdef операции = {  объявить 5  сумма 4  разделять 3  Распечатать}
/*  * Этот класс будет обрабатывать операции, которые можно использовать в приведенном выше закрытии. Другой класс * можно было бы объявить с использованием тех же методов, но с использованием, например, операций веб-сервиса * в расчетах. */учебный класс Выражение {  BigDecimal ценить  /*    * Хотя в качестве параметра передается целое число, оно преобразуется в BigDecimal, как было    * определенный. Если бы у класса был метод declare (Integer value), он бы использовался вместо него.   */  def объявить(BigDecimal ценить) {    это.ценить = ценить  }    def сумма(BigDecimal valueToAdd) {    это.ценить += valueToAdd  }    def разделять(BigDecimal делитель) {    это.ценить /= делитель  }    def propertyMissing(Нить свойство) {    если (свойство == "Распечатать") println ценить  }}
// Здесь определяется, кто будет отвечать на выражения в блоке кода выше.операции.делегировать = новый Выражение()операции()

Карри

Обычно называется частичное применение,[25] Эта функция Groovy позволяет задавать параметрам замыканий значение по умолчанию в любом из их аргументов, создавая новое замыкание с привязанным значением. Приводя один аргумент к карри() метод исправит аргумент один. Подача N аргументов исправит аргументы 1 .. N.

def joinTwoWordsWithSymbol = { символ, первый, второй -> первый + символ + второй }утверждать joinTwoWordsWithSymbol('#', 'Привет', 'Мир') == 'Привет, мир'def concatWords = joinTwoWordsWithSymbol.карри(' ')утверждать concatWords('Привет', 'Мир') == 'Привет, мир'def prependHello = concatWords.карри('Привет')// def prependHello = joinTwoWordsWithSymbol.curry ('', 'Привет')утверждать prependHello('Мир') == 'Привет, мир'

Карри также можно использовать в обратном направлении (фиксация аргументов N в N - 1) с помощью rcurry ().

def мощность = { BigDecimal ценить, BigDecimal мощность ->  ценить**мощность}def квадрат = мощность.rcurry(2)def куб = мощность.rcurry(3)утверждать мощность(2, 2) == 4утверждать квадрат(4) == 16утверждать куб(3) == 27

Groovy также поддерживает ленивая оценка,[26][27] уменьшить / свернуть,[28] бесконечные структуры и неизменность,[29] среди прочего.[30]

Обработка JSON и XML

В нотации объектов JavaScript (JSON ) и обработки XML, Groovy использует Строитель шаблон, что делает создание структуры данных менее подробным. Например, следующий XML:

<languages>  <язык год ="1995">    <name>Ява</name>    <paradigm>объектно-ориентированный</paradigm>    <typing>статический</typing>  </language>  <язык год ="1995">    <name>Рубин</name>    <paradigm>функциональный, объектно-ориентированный</paradigm>    <typing>утиная печать, динамическая</typing>  </language>  <язык год ="2003">    <name>Groovy</name>    <paradigm>функциональный, объектно-ориентированный</paradigm>    <typing>утиная печать, динамическая, статическая</typing>  </language></languages>

можно сгенерировать с помощью следующего кода Groovy:

def писатель = новый StringWriter()def строитель = новый заводной.xml.MarkupBuilder(писатель)строитель.языки {  язык(год: 1995) {    имя "Ява"    парадигма "объектно-ориентированный"    набор текста "статический"  }  язык (год: 1995) {    имя "Рубин"    парадигма «функциональный, объектно-ориентированный»    набор текста "утиный ввод, динамический"  }  язык (год: 2003) {    имя "Отличный"    парадигма «функциональный, объектно-ориентированный»    набор текста "утиная печать, динамическая, статическая"  }}

а также может обрабатываться в потоковом режиме через StreamingMarkupBuilder. Чтобы изменить реализацию на JSON, MarkupBuilder можно заменить на JsonBuilder.[31]

Чтобы проанализировать его и найти функциональный язык, Groovy's найти все Метод может служить:

def языки = новый XmlSlurper().parseText писатель.нанизывать()// Здесь используется синтаксис регулярных выражений Groovy для сопоставителя (= ~), который будет приведен к // логическое значение: либо true, если значение содержит нашу строку, либо false в противном случае.def функциональный = языки.язык.найти все { Это.парадигма =~ "функциональный" }утверждать функциональный.собирать { Это.имя } == ["Отличный", "Рубин"]

Строчная интерполяция

В Groovy строки можно интерполировать с помощью переменных и выражений с помощью GStrings:[32]

BigDecimal учетная запись = 10.0def текст = «В аккаунте в настоящее время отображается баланс в размере $ account»утверждать текст == «В настоящее время баланс счета составляет 10,0»

Строки GString, содержащие переменные и выражения, должны быть объявлены с использованием двойных кавычек.

Сложное выражение необходимо заключать в фигурные скобки. Это предотвращает интерпретацию его частей как принадлежащих к окружающей строке, а не к выражению:

BigDecimal минус = 4.0текст = "В аккаунте в настоящее время отображается баланс $ {account - minus}"утверждать текст == «В настоящее время баланс счета равен 6.0»// Без скобок для выделения выражения это приведет к:текст = «В аккаунте в настоящее время отображается остаток на счете в $ - минус»утверждать текст == «В настоящее время на счете отображается баланс 10,0 - минус»

Вычисление выражения можно отложить, используя синтаксис стрелки:

BigDecimal налог = 0.15текст = "В аккаунте отображается текущий баланс $ {-> аккаунт - аккаунт * налог}"налог = 0.10// Значение налога было изменено ПОСЛЕ объявления GString. Выражение // переменные связываются только тогда, когда выражение действительно должно быть вычислено:утверждать текст == «В настоящее время баланс счета равен 9.000»

Преобразование абстрактного синтаксического дерева

Согласно собственной документации Groovy: «Когда компилятор Groovy компилирует скрипты и классы Groovy, в какой-то момент процесса исходный код будет представлен в памяти в виде конкретного синтаксического дерева, а затем преобразован в абстрактное синтаксическое дерево. . Цель преобразований AST - позволить разработчикам подключиться к процессу компиляции, чтобы иметь возможность изменять AST до того, как он будет преобразован в байт-код, который будет запускаться JVM. Преобразования AST предоставляют Groovy улучшенные возможности метапрограммирования во время компиляции, обеспечивающие высокую гибкость на уровне языка без потери производительности во время выполнения ".[33]

Примеры AST в Groovy:

  • Преобразование категорий и миксинов
  • Неизменяемый макрос AST
  • Newify преобразование
  • Синглтон-преобразование

среди прочего.

Черты

Согласно документации Groovy, "Черты являются структурной конструкцией языка, которая позволяет: составление поведений, реализацию интерфейсов во время выполнения, переопределение поведения и совместимость со статической проверкой / компиляцией типов ».

Черты можно рассматривать как интерфейсы, несущие как реализации по умолчанию, так и состояние. Признак определяется с помощью ключевого слова признака:

черта FlyingAbility { / * объявление трейта * /  Нить летать() { "Я летаю!" } / * объявление метода внутри трейта * /}

Затем его можно использовать как обычный интерфейс, используя ключевое слово орудия:

учебный класс Птица орудия FlyingAbility {} / * Добавляет трейт FlyingAbility к возможностям класса Bird * /def птица = новый Птица() / * создаем новую птицу * /утверждать птица.летать() == "Я летаю!" / * класс Bird автоматически получает поведение трейта FlyingAbility * /

Черты характера позволяют использовать широкий спектр способностей, от простого сочинения до тестирования.

Принятие

Известные примеры внедрения Groovy:

  • Adaptavist ScriptRunner включает реализацию Groovy для автоматизации и расширения Атласский инструменты, которые используют более 20000 организаций по всему миру.[34][35]
  • Apache OFBiz, то Открытый исходный код Планирование ресурсов предприятия (ERP), использует Groovy.[36][37]
  • Эвкалипт, система управления облаком, в значительной степени использует Groovy.
  • Gradle - популярный инструмент автоматизации сборки с использованием Groovy.
  • LinkedIn использует Groovy и Grails для некоторых своих подсистем.[38]
  • LogicMonitor, облачная платформа мониторинга, использует Groovy в источниках данных на основе сценариев.[39]
  • Дженкинс, платформа для непрерывная интеграция. В версии 2 Jenkins включает Трубопровод плагин, позволяющий писать инструкции сборки на Groovy.[40]
  • Liferay использует groovy в своем рабочем процессе kaleo
  • Sky.com использует Groovy и Grails для обслуживания массового онлайн-контента.[41]
  • SmartThings, открытая площадка для умные дома и потребитель Интернет вещей, использует ориентированное на безопасность подмножество Groovy[42]
  • SoapUI предоставляет Groovy в качестве языка для разработки тестов веб-сервисов.[43]
  • Сурвата, стартап по исследованию рынка, использует Groovy и Grails.[нужна цитата ]
  • Европейское патентное ведомство (ЕПВ) разработало программирование потока данных язык Groovy, «чтобы использовать сходство в процессах взаимодействия с патентным ведомством каждой отдельной страны и преобразовать их в единый универсальный процесс».[нужна цитата ]
  • Хотя Groovy можно интегрировать в любую среду JVM, инфраструктура JBoss Seam предоставляет Groovy, помимо Java, в качестве языка разработки прямо из коробки.[44]
  • vCalc.com использует Groovy для всей определяемой пользователем математики в своей математической системе краудсорсинга.[45]
  • Wired.com использует Groovy и Grails для отдельного раздела веб-сайта с обзорами продуктов.[46]
  • XWiki SAS использует Groovy в качестве языка сценариев в своем продукте с открытым исходным кодом для совместной работы.[47]

Поддержка IDE

Много интегрированные среды разработки (IDE) и текстовые редакторы поддержка Groovy:

Диалекты

Есть одна альтернативная реализация Groovy:

  • Grooscript преобразует код Groovy в JavaScript код.[48] Хотя Grooscript имеет некоторые ограничения по сравнению с Apache Groovy, он может использовать классы домена как на сервере, так и на клиенте.[49] Поддержка плагинов для Грааль версия 3.0, а также онлайн-преобразования кода.[50]

Смотрите также

Рекомендации

Цитаты

  1. ^ а б «Релизы - apache / groovy». Получено 2020-11-05 - через GitHub.
  2. ^ https://mrhaki.blogspot.com/2011/10/groovy-goodness-default-groovy-script.html
  3. ^ «Производительность Groovy 2.0 по сравнению с Java». 25 августа 2012 г.
  4. ^ «Java vs Groovy2.0 vs Простой тест производительности Scala». 10 июля 2012 г. Архивировано с оригинал 10 декабря 2012 г.. Получено 7 октября 2012.
  5. ^ а б «Groovy 2.4 и Grails 3.0 станут последними крупными релизами, выпущенными при основной спонсорской поддержке». 19 янв 2015.
  6. ^ а б «Groovy присоединяется к Apache Incubator». 11 марта 2015.
  7. ^ Джеймс Стрэчэн (29 августа 2003 г.). «Groovy - рождение нового динамического языка для платформы Java». Архивировано из оригинал 1 сентября 2003 г.
  8. ^ а б "Процесс сообщества Java JSR 241".
  9. ^ «Groovy занимает первое место на конкурсе инноваций JAX 2007». 2007-04-26. Архивировано из оригинал на 2015-05-13. Получено 2012-10-07.
  10. ^ «Говорят, за чашкой кофе может случиться многое». Архивировано из оригинал на 2011-04-19. Получено 2012-10-07.
  11. ^ «SpringSource приобретает компанию Groovy и Grails (G2One)». 11 ноября 2008 г.
  12. ^ «VMWare приобретает SpringSource». 10 августа 2009 г.
  13. ^ "Твит Джеймса Страчана". 24 ноября 2016 г.. Получено 2016-11-24.
  14. ^ "Объявление в списке рассылки разработчиков".
  15. ^ Кёниг 2007, стр. 32
  16. ^ «Рекомендации по стилю и языковым функциям Groovy для разработчиков Java». Groovy.codehaus.org. Архивировано из оригинал на 2015-01-17. Получено 2015-01-22.
  17. ^ «Groovy - отличия от Java». Groovy.codehaus.org. Архивировано из оригинал на 2009-03-17. Получено 2013-08-12.
  18. ^ "Что нового в Groovy 2.0?". 28 июня 2012 г.
  19. ^ Кениг 2007, стр. 37-8
  20. ^ Кениг 2007, стр. 38-9
  21. ^ Кениг 2007, стр. 41-3
  22. ^ "JN3525-MetaClasses". Архивировано из оригинал на 2012-10-01. Получено 2012-10-07.
  23. ^ «Методы метапрограммирования в Groovy и Grails». 11 июня 2009 г.
  24. ^ "Groovy - закрытие". Архивировано из оригинал на 2012-05-22.
  25. ^ а б "Groovy называет ли частичное приложение каррированием? ", 10 августа 2013 г.
  26. ^ "Groovy - ленивая трансформация". Архивировано из оригинал на 2012-10-08. Получено 2012-10-07.
  27. ^ «Боковые заметки: Ленивые списки в Groovy». 3 февраля 2011 г.
  28. ^ "Groovy's Fold". 20 июня 2011. Архивировано с оригинал 13 февраля 2015 г.. Получено 12 февраля 2015.
  29. ^ «Функциональное программирование с помощью Groovy». 5 ноя 2011.
  30. ^ «Функциональное программирование в Groovy». Архивировано из оригинал на 2012-10-08. Получено 2012-10-07.
  31. ^ "JsonBuilder". Архивировано из оригинал на 2012-10-02. Получено 2012-10-07.
  32. ^ "Groovy Strings - разные способы их создания". 26 декабря 2009 г.
  33. ^ «Метапрограммирование во время компиляции - преобразования AST». Архивировано из оригинал на 2012-10-14. Получено 2012-10-07.
  34. ^ «Документация ScriptRunner».
  35. ^ «Пресс-релиз ScriptRunner со статистикой внедрения».
  36. ^ «Groovy DSL для бизнес-логики OFBiz». Открытая вики-страница проекта Apache OFBiz.
  37. ^ "Примеры простых методов с использованием Groovy". Открытая вики-страница проекта Apache OFBiz.
  38. ^ «Grails в LinkedIn». Получено 2015-06-02.
  39. ^ «Встроенный Groovy-скриптинг». www.logicmonitor.com. Получено 2020-11-20.
  40. ^ «Трубопровод Дженкинса».
  41. ^ Роше, Грэм (2 октября 2008 г.). «Блог Грэма Роше: перезапуск Sky.com, написанный в Grails». Блог Грэма Роше. Получено 2015-06-02.
  42. ^ Анализ безопасности новых приложений для умного дома
  43. ^ «Сценарии и библиотека скриптов | Сценарии и свойства». www.soapui.org. Получено 2015-06-02.
  44. ^ «Глава 11. Groovy-интеграция». docs.jboss.org. Получено 2015-06-02.
  45. ^ "vCalc, первая социальная платформа для мира математики". Получено 2016-05-05.
  46. ^ "Wired.Com" (PDF). www.springsource.org. Получено 2015-06-02.
  47. ^ «XWiki SAS» (PDF). www.springsource.org. Получено 2015-06-02.
  48. ^ "Документация Grooscript". 12 сен 2016. Архивировано с оригинал 28 июня 2017 г.. Получено 4 июля 2017.
  49. ^ «Презентация на SpringOne / 2GX на Grooscript». 13 декабря 2015 г.
  50. ^ "Grooscript online conversions". 15 мая 2017. Архивировано с оригинал 9 июля 2017 г.. Получено 4 июля 2017.

Источники

внешняя ссылка