Статьи

Обновление Грааля с 2.0 до 2.2

Готовясь к игре Grails vs. Play Smackdown на Devoxx France на следующей неделе, я недавно обновил свою версию Grails Happy Trails с Grails 2.0.3 до Grails 2.2.1. По пути я столкнулся с несколькими проблемами и решил, что запишу их здесь, чтобы помочь другим.

Исправление источника
Первая проблема, с которой я столкнулся, была несовместимость со Споком и Groovy 2.

| Resolving plugin JAR dependencies
| Error WARNING: Dependencies cannot be resolved for plugin [mail] due to error: startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/Users/mraible/.grails/ivy-cache/org.spockframework/spock-core/jars/spock-core-0.7-groovy-1.8.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation  because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 0.7.0-groovy-1.8 is not compatible with Groovy 2.0.7. For more information, see http://versioninfo.spockframework.org

Я отправил проблему в StackOverflow и получил ответ почти сразу. Хотя этот запрос извлечения мне очень помог, в конечном итоге он был вызван моим видением: у меня было две зависимости «geb-spock», перечисленные в BuildConfig.groovy с разными groupIds.

В этот момент я также переместил все свои зависимости плагинов из application.properties в BuildConfig.groovy .

Следующая проблема, с которой я столкнулся, — это модульное тестирование и сбой функциональных тестов . Проблема модульного тестирования была вызвана тем, что моя модель Direction не была в аннотации тестов @Mock. После того, как я его добавил, проверка прошла, и я понял, что мой тест недействителен. Я добавил @Ignore и продолжил.

Казалось, что функциональный тест был вызван Гебом, который пытался использовать Chrome Driver. Один из моих тестов не работал с HtmlUnitDriver по умолчанию, поэтому я использовал ChromeDriver для одного теста.

| Running 11 spock tests... 6 of 11
| Failure:  signup as a new user(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.WebDriverException: Unable to either launch or connect to Chrome. Please check that ChromeDriver is up-to-date. Using Chrome binary at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 45.66 seconds
Build info: version: '2.27.0', revision: '18259', time: '2012-12-05 11:30:53'
System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.2', java.version: '1.7.0_04'
Driver info: org.openqa.selenium.chrome.ChromeDriver
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:187)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:533)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:216)
    at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:111)
    at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:115)
    at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:161)
    at org.openqa.selenium.chrome.ChromeDriver.(ChromeDriver.java:107)
    at happytrails.AuthenticatedUserSpec.signup as a new user(AuthenticatedUserSpec.groovy:25)

Даже при запуске «grails -Dgeb.env = chrome test-app» это все равно происходило. Это было вызвано тем, что у меня был
GebConfig.groovy в test / functions / happytrails. Переместите его, чтобы проверить / функционал решил проблему. Я также обнаружил, что я знаю, что Chrome больше не нужен, чтобы пройти этот тест. По-видимому,
HtmlUnitDriver имеет проблемы с Grails 2.2 , но, похоже, он мне подходит .

После исправления конфигурации Geb я столкнулся с ошибкой функционального теста:

| Running 11 spock tests... 5 of 11
| Failure:  click signup link(happytrails.AuthenticatedUserSpec)
|  org.openqa.selenium.ElementNotVisibleException: Element must be displayed to click (WARNING: The server did not provide any stacktrace information)

Мне удалось это исправить, изменив AddRoutePage.groovy из:

static content = {
    createButton(to: ShowRoutePage) { create() }
    name { value("Name") }
    distance { value("Distance") }
    location { value("Location") }
}

Для того, чтобы:

static content = {
    createButton(to: ShowRoutePage) { create() }
    form { $("form") }
}

А затем ссылки на имя, расстояние и местоположение соответственно (form.name и т. Д.) В AuthenticatedUserSpec.groovy .

CloudBees
После того, как у меня все работало локально, я вошел в Jenkins на CloudBees . Поскольку я не использовал его в течение некоторого времени, мне пришлось немного подождать, пока мой сервер Дженкинса будет повторно введен в эксплуатацию. Когда все закончилось, я попытался выбрать Grails 2.2.1 для сборки, но обнаружил, что он недоступен. После этого я узнал о Grails Wrapper , обнаружил, что последний плагин Grails Jenkins поддержал его, и все заработало. Позже я обнаружил, что CloudBees поддерживает Grails 2.2.1, мне просто нужно было настроить другую установку Grails для автоматической загрузки и установки 2.2.1.

Heroku
Последние две проблемы, с которыми я столкнулся, были с Heroku. Поскольку я обновлял все, я хотел, чтобы Grails собирал / запускал под Java 7 и использовал Servlet 3. Я изменил соответствующие свойства в BuildConfig.groovy , настроил Heroku и развернул. Нет кости.

Error Compilation error: startup failed:
Invalid commandline usage for javac.
javac: invalid source release: 1.7
Usage: javac  
use -help for a list of possible options

Sidenote: Я пытался строить с Java 8 на CloudBees, но обнаружил, что плагин для поиска не поддерживает его.

Compile error during compilation with javac.
/scratch/jenkins/workspace/Happy Trails - Grails 2/work/plugins/searchable-0.6.4/src/java/grails/plugin/searchable/internal/compass/index/DefaultUnindexMethod.java:94: error: reference to delete is ambiguous
                    session.delete(query);
                           ^
  both method delete(CompassQuery) in CompassOperations and method delete(CompassQuery) in CompassIndexSession match

Что касается Servlet 3, было совершенно очевидно, что версия Jetty, которую Heroku использует для Grails, не поддерживает ее. Поэтому я вернулся к сервлету 2.5.

java.lang.NoClassDefFoundError: javax/servlet/AsyncContext
	at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2444)

Я отправил вопрос о Java 7 в службу поддержки Heroku несколько дней назад, но пока не получил ответа.

Резюме
Хотя обновление Grails с 2.0 до 2.2 оказалось не таким легким, как ожидалось, это понятно. В конце концов, Grails 2.2 поставляется с Groovy 2.0, который имеет множество новых функций . Все проблемы, с которыми я столкнулся, было довольно легко решить, кроме Java 7 на Heroku. Но что вы ожидаете от бесплатного хостинга?

Если вы приедете в Devoxx France на следующей неделе, я с нетерпением жду возможности поделиться нашим исследованием Grails 2.2.1 и Play 2.1.0.