promptfornonlocaldatabase generatechangelog extension example java spring hibernate gradle liquibase

java - generatechangelog - Actualiza el registro de cambios de Liquibase automáticamente mientras se construye.



liquibase import file (2)

Actualmente estoy trabajando en un proyecto de Spring que utiliza Hibernate y Liquibase. Lo que estoy tratando de lograr es actualizar el registro de cambios de Liquibase automáticamente cada vez que construyo el proyecto. Se supone que debe generar un diferencial basado en mi actual base de datos productiva y en mis entidades de Hibernate actualizadas.

Pero el problema que tengo es que cada vez que limpio y reconstruyo mi proyecto obtengo el siguiente error:

liquibase-plugin: Running the ''main'' activity... INFO 6/22/15 11:12 AM: liquibase-hibernate: Reading hibernate configuration hibernate:spring:com.example.name.domain?dialect=org.hibernate.dialect.MySQL5Dialect INFO 6/22/15 11:12 AM: liquibase-hibernate: Found package com.example.app.domain INFO 6/22/15 11:12 AM: liquibase-hibernate: Found dialect org.hibernate.dialect.MySQL5Dialect Unexpected error running Liquibase: Unable to resolve persistence unit root URL SEVERE 6/22/15 11:12 AM: liquibase: Unable to resolve persistence unit root URL liquibase.exception.DatabaseException: javax.persistence.PersistenceException: Unable to resolve persistence unit root URL at liquibase.integration.commandline.CommandLineUtils.createDatabaseObject(CommandLineUtils.java:69) at liquibase.integration.commandline.Main.createReferenceDatabaseFromCommandParams(Main.java:1169) at liquibase.integration.commandline.Main.doMigration(Main.java:936) at liquibase.integration.commandline.Main.run(Main.java:175) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324) at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.invoke(StaticMetaMethodSite.java:43) at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:88) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at org.liquibase.gradle.LiquibaseTask.runLiquibase(LiquibaseTask.groovy:97) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:382) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1015) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) at org.liquibase.gradle.LiquibaseTask$_liquibaseAction_closure1.doCall(LiquibaseTask.groovy:52) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1015) at groovy.lang.Closure.call(Closure.java:423) at groovy.lang.Closure.call(Closure.java:439) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1379) at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1310) at org.codehaus.groovy.runtime.dgm$150.invoke(Unknown Source) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at org.liquibase.gradle.LiquibaseTask.liquibaseAction(LiquibaseTask.groovy:46) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75) at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:226) at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:219) at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:208) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:589) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:572) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:310) at org.gradle.api.internal.AbstractTask.execute(AbstractTask.java:305) at org.gradle.api.internal.TaskInternal$execute$0.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) at build_au43cnsvyw2rwctsxb5mg4cmw$_run_closure4.doCall(/Users/mihajlovic/Documents/repos/Backend/dbmigration/build.gradle:52) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1015) at groovy.lang.Closure.call(Closure.java:423) at groovy.lang.Closure.call(Closure.java:439) at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:558) at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:539) at org.gradle.api.internal.tasks.TaskMutator$1.execute(TaskMutator.java:77) at org.gradle.api.internal.tasks.TaskMutator$1.execute(TaskMutator.java:73) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:310) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88) at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62) at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23) at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68) at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55) at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149) at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106) at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86) at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:90) at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28) at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35) at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41) at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28) at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:50) at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:27) at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:40) at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:169) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237) at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210) at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35) at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206) at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33) at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22) at org.gradle.launcher.Main.doAction(Main.java:33) at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54) at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35) at org.gradle.launcher.GradleMain.main(GradleMain.java:23) Caused by: javax.persistence.PersistenceException: Unable to resolve persistence unit root URL at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.determineDefaultPersistenceUnitRootUrl(DefaultPersistenceUnitManager.java:580) at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.preparePersistenceUnitInfos(DefaultPersistenceUnitManager.java:436) at liquibase.ext.hibernate.database.HibernateSpringDatabase.buildConfigurationFromScanning(HibernateSpringDatabase.java:227) at liquibase.ext.hibernate.database.HibernateSpringDatabase.buildConfiguration(HibernateSpringDatabase.java:55) at liquibase.ext.hibernate.database.HibernateDatabase.setConnection(HibernateDatabase.java:45) at liquibase.database.DatabaseFactory.findCorrectDatabaseImplementation(DatabaseFactory.java:123) at liquibase.database.DatabaseFactory.openDatabase(DatabaseFactory.java:143) at liquibase.integration.commandline.CommandLineUtils.createDatabaseObject(CommandLineUtils.java:50) ... 140 more Caused by: java.io.FileNotFoundException: class path resource [] cannot be resolved to URL because it does not exist at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:187) at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.determineDefaultPersistenceUnitRootUrl(DefaultPersistenceUnitManager.java:577) ... 147 more

Por lo que entiendo, el problema es que Liquibase requiere que todas las clases de entidades se carguen en el classpath de gradle, pero dado que las clases de Java solo se están compilando o no se han compilado, este no es el caso todavía, de ahí el mensaje de error.

Puedo corregir este error construyendo el proyecto en dos pasos:

  1. Primero ejecuto la tarea compileJava para construir las clases de entidad.
  2. Una vez hecho esto, puedo realizar una build normal, ahora sin ningún problema.

Sin embargo, construir el proyecto en dos pasos es bastante tedioso. ¿Hay alguna manera de solucionar este problema para construirlo en un solo paso?

Mi build.gradle actualmente se ve así:

buildscript { ext { springBootVersion = ''1.2.3.RELEASE'' } repositories { mavenCentral() files ''build/classes/main'' } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") classpath("io.spring.gradle:dependency-management-plugin:0.5.0.RELEASE") classpath("org.liquibase:liquibase-gradle-plugin:1.1.0") classpath("mysql:mysql-connector-java:5.1.35") classpath(''org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final'') classpath(''org.liquibase.ext:liquibase-hibernate4:3.5'') classpath(''org.springframework.data:spring-data-jpa:1.8.0.RELEASE'') classpath files(''build/classes/main/'') } } apply plugin: ''org.liquibase.gradle'' apply plugin: ''java'' apply plugin: ''eclipse-wtp'' apply plugin: ''idea'' apply plugin: ''spring-boot'' apply plugin: ''io.spring.dependency-management'' apply plugin: ''war'' war { baseName = ''example'' version = ''0.0.1-SNAPSHOT'' } sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() flatDir { dirs ''libs'' } } configurations { providedRuntime } dependencies { compile("org.springframework.boot:spring-boot-starter-data-jpa") compile("org.springframework.boot:spring-boot-starter-web") compile("org.apache.commons:commons-lang3:3.0") compile("mysql:mysql-connector-java:5.1.35") compile(''org.liquibase:liquibase-core:3.3.5'') providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") testCompile("org.springframework.boot:spring-boot-starter-test") } liquibase { activities { main { changeLogFile ''src/main/resources/db/changelog/db.changelog-master.xml'' url ''jdbc:mysql://localhost:3306/Example'' username ''root'' password '''' referenceDriver ''liquibase.ext.hibernate.database.connection.HibernateDriver'' referenceUrl ''hibernate:spring:com.example.app.domain?dialect=org.hibernate.dialect.MySQL5Dialect'' } } runList = ''main'' } eclipse { classpath { containers.remove(''org.eclipse.jdt.launching.JRE_CONTAINER'') containers ''org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7'' } } task wrapper(type: Wrapper) { gradleVersion = ''2.4'' }


¡Finalmente lo resolví! Puede usar el tipo Exec para ejecutar comandos en la línea de comandos que posteriormente inicia un nuevo proceso. Puedes encontrar más información en la documentación .

Esta es la solución que terminé con:

task updateChangeLog(type: Exec) { commandLine ''gradle'', ''diffChangeLog'' } updateChangeLog.dependsOn compileJava

Esto inicia un nuevo proceso de gradle separado con mi tarea diffChangeLog .


Puedes definir la Tarea Liquibase así:

task liquibase(type: JavaExec, depends: build) { classpath = sourceSets.main.runtimeClasspath ... }