Использование Grails Кварцевый плагин без Hibernate - PullRequest
3 голосов
/ 18 февраля 2010

Я работаю над внутренним приложением Grails, которое периодически извлекает информацию из службы RESTful. Для этого я установил плагин Grails Quartz.

grails install-plugin quartz

Затем я создал работу, используя

grails create-job My

, который генерирует файл MyJob, который я настроил с помощью триггера cron

static triggers = {
    cron name: 'myTrigger', cronExpression: '0 0 * * * ?' // hourly
}

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

2010-02-18, 00:04:32 ERROR org.codehaus.groovy.grails.web.context.GrailsContextLoader - Error occurred shutting down plug-in manager: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler':
Cannot resolve reference to bean 'sessionBinderListener' while setting bean property 'jobListeners' with key [0]; nested
 exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionBinderListener': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sessionFactory': Cannot resolve reference to bean 'hibernateProperties' while setting bean property 'hibernateProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'hibernateProperties': Cannot resolve reference to bean 'dialectDetector' while setting bean property 'properties' with key [hibernate.dialect]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException : Access is denied: Session is closed

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

Running script C:\Downloads\grails-1.2.1\scripts\RunApp.groovy  
Environment set to development  
[groovyc] Compiling 18 source files to C:\Projects\myapp\target\classes  
[groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Compile error during compilation with javac.  
[groovyc] ...\myapp\plugins\quartz-0.4.1\src\java\org\codehaus\groovy\grails\plugins\quartz\listeners\SessionBinderJobListener.java:19: package org.hibernate does not exist  
[groovyc] import org.hibernate.FlushMode;  
...

Есть ли способ использовать плагин Quartz без плагина Hibernate?
Если нет, то лучше ли будет настроить базу данных в памяти для использования в Quartz?
(меня не волнует сохранение каких-либо из этих данных.)

Ответы [ 5 ]

4 голосов
/ 03 мая 2012

Я получил плагин Quartz (0.4.2), работающий довольно чисто без плагина Hibernate и без редактирования плагина Quartz.

Добавьте зависимость времени выполнения от Hibernate в BuildConfig.groovy просто для извлечения jar-файлов:

dependencies {
    ...
    // the Quartz plugin depends on some Hibernate classes being available
    runtime('org.hibernate:hibernate-core:3.6.7.Final') {
        exclude group:'commons-logging', name:'commons-logging'
        exclude group:'commons-collections', name:'commons-collections'
        exclude group:'org.slf4j', name:'slf4j-api'
        exclude group:'xml-apis', name:'xml-apis'
        exclude group:'dom4j', name:'dom4j'
        exclude group:'antlr', name:'antlr'
    }
}

Кварц все еще устанавливает SessionBinderJobListener для привязки сеанса Hibernate к потоку задания. Создайте привязку сеанса NOP, как это:

import org.quartz.listeners.JobListenerSupport

class NopSessionBinderJobListener extends JobListenerSupport {
    String getName() { return "sessionBinderListener" }
}

И создайте bean-компонент Spring в resources.groovy:

beans = {
    ...
    // dummy session binder to work around issue with Quartz requiring Hibernate
    sessionBinderListener(NopSessionBinderJobListener) { }
}
0 голосов
/ 03 мая 2013

Для версии 1.0.RC7 плагина Quartz grails мне пришлось добавить несколько дополнительных шагов. Это основано на ответе @ DavidTinker.

В resources.groovy мне пришлось добавить фабрику сессий Nop и сессию Nop (убедитесь, что она реализует org.hibernate.classic.Session)

beans = {
   // dummy session binder to work around issue with Quartz requiring Hibernate
   sessionBinderListener(NopSessionBinderJobListener) { }
   sessionFactory( NopSessionFactory) {}
}

NopSessionFactory.groovy:

class NopSessionFactory implements SessionFactory
{

    @Override
    Session openSession() throws HibernateException {
       return new NopSession()
    }
 // Implement all of the methods required by this interface and return a NopSession for any method that returns a session
}  

И, в моем случае, мне нужно либо добавить No-op Transaction Manager для любых сервисов, добавленных в мои задания Quartz, либо пометить сервисы как нетранзакционные (что я и выбрал).

class FooService {     
   static transactional = false

Мне также пришлось исключить переходные зависимости гибернации, но, поскольку я использую gradle для сборки проекта, это выглядело так:

// Needed by quartz
runtime('org.hibernate:hibernate-core:3.6.10.Final') {
    exclude group:'commons-logging', module:'commons-logging'
    exclude group:'commons-collections', module:'commons-collections'
    exclude group:'org.slf4j', module:'slf4j-api'
    exclude group:'xml-apis', module:'xml-apis'
    exclude group:'dom4j', module:'dom4j'
    exclude group:'antlr', module:'antlr'
}
0 голосов
/ 18 февраля 2010

Мне удалось заставить это работать, оставив плагин Hibernate установленным и сконфигурировав базу данных в памяти. В DataSource.groovy

...
environments {
  development {
    dataSource {
      dbCreate = "create-drop" // one of 'create', 'create-drop','update'
      url = "jdbc:hsqldb:mem:myDevDb"
    }
  }
  test {
    dataSource {
      dbCreate = "create-drop"
      url = "jdbc:hsqldb:mem:myTestDb"
    }
  }
  production {
    dataSource {
      dbCreate = "create-drop"
      url = "jdbc:hsqldb:mem:myProdDb;shutdown=true"
    }
  }
}
...

Изменение состояло в том, чтобы установить «create-drop» в тестовой и производственной базах данных и установить для производственной базы данных «mem» вместо «file».

0 голосов
/ 20 февраля 2010

Итак,

Вот решение, которое я придумала (обратите внимание, что я был недоволен тем, что сначала оставался в спящем режиме). Решение протестировано с Grails 1.2.1 и кварцевым плагином 0.4.1 обычным способом гибернации (grails uninstall-plugin hibernate). Хранение в памяти базы данных также не самый лучший вариант, который я мог найти.

Создание или редактирование scripts/_Events.groovy:

eventCompileStart = {bindings->
 println "Compile Start: Plugin dir is ${grailsSettings.projectPluginsDir}"
 // Kill standard listener which actually wants to use hibernate (to restore hibernate session)!
 Ant.delete(file:"${grailsSettings.projectPluginsDir}/quartz-0.4.1/src/java/org/codehaus/groovy/grails/plugins/quartz/listeners/SessionBinderJobListener.java")
}

Теперь, чтобы компенсировать удаление файла (это указано где-то в GrailsQuartzPlugin.groovy, нам нужно создать «безопасную» версию класса в проекте, то есть src/java/org/codehaus/groovy/grails/plugins/quartz/listeners/SessionBinderJobListener.java

это то, что я положил туда, сохранив все авторские права и автора без изменений - но не оставив спящего режима (пусть это R.I.P.):


/* Copyright 2006-2008 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.codehaus.groovy.grails.plugins.quartz.listeners;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.listeners.JobListenerSupport;

/**
 * JobListener implementation which binds Hibernate Session to thread before
 * execution of job and flushes it after job execution.
 * 
 * @author Sergey Nebolsin (nebolsin@gmail.com)
 * 
 * @since 0.2
 */
public class SessionBinderJobListener extends JobListenerSupport
{
  private static final transient Log LOG = LogFactory.getLog(SessionBinderJobListener.class);

  public static final String NAME = "sessionBinderListener";

  public String getName()
  {
    return NAME;
  }

  @Override
  public void jobToBeExecuted(final JobExecutionContext context)
  {
  }

  @Override
  public void jobWasExecuted(final JobExecutionContext context, final JobExecutionException exception)
  {
  }

}

Предупреждение: Решением является "взлом", который переопределяет некоторые файлы из плагина. удалить взломать

  • убедитесь, что вы удалили кварцевый плагин,

  • перейдите к ${grailsSettings.projectPluginsDir} (местоположение печатается хаком при каждом запуске сценариев grails compile и более высокого уровня, включая grails war) и убедитесь, что артефактов не осталось.

  • Удалить оба артефакта взлома

  • Переустановите свежий кварцевый плагин.

0 голосов
/ 18 февраля 2010

Кажется, что есть зависимость кода, в quartz-0.4.1\src\java\org\codehaus\groovy\grails\plugins\quartz\listeners\SessionBinderJobListener.java:1

И тогда вы не можете скомпилировать quartz plugin без классов гибернации.Может быть, вы можете положить их в папку lib?или добавьте его как compile зависимость, если вы используете maven / gradle

...