From 76055475dab1dbc8647afc5503aded5c724a4fd5 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Wed, 8 Jun 2022 07:39:10 -0500 Subject: [PATCH] HHH-15314 - Hibernate Gradle plugin is not working for Kotlin projects --- .../hibernate/orm/tooling/gradle/Helper.java | 81 +++++++++++- .../tooling/gradle/HibernateOrmPlugin.java | 49 ++++++- .../gradle/enhance/EnhancementHelper.java | 70 ++++------ .../gradle/enhance/EnhancementSpec.java | 3 + .../gradle/enhance/EnhancementTask.java | 118 ----------------- .../gradle/HibernateOrmPluginTest.java | 124 +++++++++++++----- 6 files changed, 240 insertions(+), 205 deletions(-) delete mode 100644 tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementTask.java diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/Helper.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/Helper.java index 5c59274aaf..096c523fbb 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/Helper.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/Helper.java @@ -12,10 +12,10 @@ import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Path; +import java.util.Set; import org.gradle.api.GradleException; -import org.gradle.api.Project; -import org.gradle.api.file.Directory; +import org.gradle.api.file.FileCollection; import org.hibernate.bytecode.enhance.spi.Enhancer; @@ -24,15 +24,84 @@ import org.hibernate.bytecode.enhance.spi.Enhancer; */ public class Helper { - public static ClassLoader toClassLoader(Directory classesDir) { - final File classesDirFile = classesDir.getAsFile(); - final URI classesDirUri = classesDirFile.toURI(); + public static String determineCompileSourceSetName(String name) { + return determineCompileNameParts( name )[0]; + } + + public static String[] determineCompileNameParts(String name) { + StringBuilder firstPart = null; + StringBuilder secondPart = null; + + boolean processingFirstPart = false; + boolean processingSecondPart = false; + final char[] nameChars = name.toCharArray(); + for ( int i = 0; i < nameChars.length; i++ ) { + final char nameChar = nameChars[ i ]; + if ( processingFirstPart ) { + if ( Character.isUpperCase( nameChar ) ) { + // this is the start of the second-part + processingFirstPart = false; + processingSecondPart = true; + secondPart = new StringBuilder( String.valueOf( Character.toLowerCase( nameChar ) ) ); + } + else { + firstPart.append( nameChar ); + } + } + else if ( processingSecondPart ) { + if ( Character.isUpperCase( nameChar ) ) { + throw new RuntimeException( "Unexpected compilation task name : " + name ); + } + else { + secondPart.append( nameChar ); + } + } + else { + if ( Character.isUpperCase( nameChar ) ) { + processingFirstPart = true; + firstPart = new StringBuilder( String.valueOf( Character.toLowerCase( nameChar ) ) ); + } + } + } + + if ( firstPart == null ) { + throw new RuntimeException( "Unexpected compilation task name : " + name ); + } + + if ( secondPart == null ) { + return new String[] { "main", firstPart.toString() }; + } + + return new String[] { firstPart.toString(), secondPart.toString() }; + } + + + public static ClassLoader toClassLoader(FileCollection directories) { + final Set files = directories.getFiles(); + final URL[] urls = new URL[ files.size() ]; + int index = 0; + for ( File classesDir : files ) { + final URI classesDirUri = classesDir.toURI(); + try { + urls[index] = classesDirUri.toURL(); + } + catch (MalformedURLException e) { + throw new GradleException( "Unable to resolve classpath entry to URL : " + classesDir.getAbsolutePath(), e ); + } + + index++; + } + return new URLClassLoader( urls, Enhancer.class.getClassLoader() ); + } + + public static ClassLoader toClassLoader(File classesDir) { + final URI classesDirUri = classesDir.toURI(); try { final URL url = classesDirUri.toURL(); return new URLClassLoader( new URL[] { url }, Enhancer.class.getClassLoader() ); } catch (MalformedURLException e) { - throw new GradleException( "Unable to resolve classpath entry to URL : " + classesDirFile.getAbsolutePath(), e ); + throw new GradleException( "Unable to resolve classpath entry to URL : " + classesDir.getAbsolutePath(), e ); } } diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java index d1830909e5..fc5394529a 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/HibernateOrmPlugin.java @@ -6,25 +6,34 @@ */ package org.hibernate.orm.tooling.gradle; +import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; -import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.Task; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.plugins.JvmEcosystemPlugin; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.compile.AbstractCompile; -import org.hibernate.orm.tooling.gradle.enhance.EnhancementTask; +import org.hibernate.orm.tooling.gradle.enhance.EnhancementHelper; import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask; +import static org.hibernate.orm.tooling.gradle.Helper.determineCompileSourceSetName; + /** * Hibernate ORM Gradle plugin */ public class HibernateOrmPlugin implements Plugin { @Override public void apply(Project project) { - project.getPlugins().apply( JavaPlugin.class ); + // for SourceSet support and other JVM goodies + project.getPlugins().apply( JvmEcosystemPlugin.class ); project.getLogger().debug( "Adding Hibernate extensions to the build [{}]", project.getPath() ); final HibernateOrmSpec ormDsl = project.getExtensions().create( HibernateOrmSpec.DSL_NAME, HibernateOrmSpec.class, project ); - EnhancementTask.apply( ormDsl, ormDsl.getSourceSetProperty().get(), project ); + prepareEnhancement( ormDsl, project ); + JpaMetamodelGenerationTask.apply( ormDsl, ormDsl.getSourceSetProperty().get(), project ); // project.getDependencies().add( @@ -35,4 +44,36 @@ public class HibernateOrmPlugin implements Plugin { // ) // ); } + + private void prepareEnhancement(HibernateOrmSpec ormDsl, Project project) { + project.getGradle().getTaskGraph().whenReady( (graph) -> { + if ( !ormDsl.getSupportEnhancementProperty().get() ) { + return; + } + graph.getAllTasks().forEach( (task) -> { + if ( task instanceof AbstractCompile ) { + final SourceSet sourceSetLocal = ormDsl.getSourceSetProperty().get(); + + final String compiledSourceSetName = determineCompileSourceSetName( task.getName() ); + if ( !sourceSetLocal.getName().equals( compiledSourceSetName ) ) { + return; + } + + final AbstractCompile compileTask = (AbstractCompile) task; + //noinspection Convert2Lambda + task.doLast( new Action<>() { + @Override + public void execute(Task t) { + final DirectoryProperty classesDirectory = compileTask.getDestinationDirectory(); + final ClassLoader classLoader = Helper.toClassLoader( sourceSetLocal.getOutput().getClassesDirs() ); + + EnhancementHelper.enhance( classesDirectory, classLoader, ormDsl, project ); + } + } ); + + task.finalizedBy( this ); + } + } ); + } ); + } } diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java index 7bd110cbac..67f17f30d5 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementHelper.java @@ -16,7 +16,6 @@ import org.gradle.api.Project; import org.gradle.api.file.Directory; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.logging.Logger; -import org.gradle.work.InputChanges; import org.hibernate.bytecode.enhance.spi.DefaultEnhancementContext; import org.hibernate.bytecode.enhance.spi.EnhancementContext; @@ -24,7 +23,7 @@ import org.hibernate.bytecode.enhance.spi.Enhancer; import org.hibernate.bytecode.enhance.spi.UnloadedClass; import org.hibernate.bytecode.enhance.spi.UnloadedField; import org.hibernate.cfg.Environment; -import org.hibernate.orm.tooling.gradle.Helper; +import org.hibernate.orm.tooling.gradle.HibernateOrmSpec; import static org.hibernate.orm.tooling.gradle.Helper.determineClassName; @@ -34,50 +33,35 @@ import static org.hibernate.orm.tooling.gradle.Helper.determineClassName; public class EnhancementHelper { public static void enhance( DirectoryProperty classesDirectoryProperty, - InputChanges inputChanges, - EnhancementSpec enhancementDsl, + ClassLoader classLoader, + HibernateOrmSpec ormDsl, Project project) { - final Directory classesDir = classesDirectoryProperty.get(); - final File classesDirFile = classesDir.getAsFile(); + final Directory classesDirectory = classesDirectoryProperty.get(); + final File classesDir = classesDirectory.getAsFile(); - final Enhancer enhancer = generateEnhancer( classesDir, enhancementDsl ); + final Enhancer enhancer = generateEnhancer( classLoader, ormDsl ); - final String classesDirPath = classesDirFile.getAbsolutePath(); + walk( classesDir, classesDir, enhancer, project ); + } - inputChanges.getFileChanges( classesDirectoryProperty ).forEach( (change) -> { - switch ( change.getChangeType() ) { - case ADDED: - case MODIFIED: { - final File changedFile = change.getFile(); - if ( changedFile.getName().endsWith( ".class" ) ) { - final String classFilePath = changedFile.getAbsolutePath(); - if ( classFilePath.startsWith( classesDirPath ) ) { - // we found the directory it came from - use that to determine the class name - final String className = determineClassName( classesDirFile, changedFile ); - - final long lastModified = changedFile.lastModified(); - - enhance( changedFile, className, enhancer, project ); - - final boolean timestampReset = changedFile.setLastModified( lastModified ); - if ( !timestampReset ) { - project.getLogger().debug( "`{}`.setLastModified failed", project.relativePath( changedFile ) ); - } - - break; - } - } - break; - } - case REMOVED: { - // nothing to do - break; - } - default: { - throw new UnsupportedOperationException( "Unexpected ChangeType : " + change.getChangeType().name() ); - } + private static void walk(File classesDir, File dir, Enhancer enhancer, Project project) { + for ( File subLocation : dir.listFiles() ) { + if ( subLocation.isDirectory() ) { + walk( classesDir, subLocation, enhancer, project ); } - } ); + else if ( subLocation.isFile() && subLocation.getName().endsWith( ".class" ) ) { + final String className = determineClassName( classesDir, subLocation ); + final long lastModified = subLocation.lastModified(); + + enhance( subLocation, className, enhancer, project ); + + final boolean timestampReset = subLocation.setLastModified( lastModified ); + if ( !timestampReset ) { + project.getLogger().debug( "`{}`.setLastModified failed", project.relativePath( subLocation ) ); + } + + } + } } private static void enhance( @@ -104,8 +88,8 @@ public class EnhancementHelper { } } - private static Enhancer generateEnhancer(Directory classesDir, EnhancementSpec enhancementDsl) { - final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + public static Enhancer generateEnhancer(ClassLoader classLoader, HibernateOrmSpec ormDsl) { + final EnhancementSpec enhancementDsl = ormDsl.getEnhancementSpec(); final EnhancementContext enhancementContext = new DefaultEnhancementContext() { @Override diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementSpec.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementSpec.java index ab46075d59..37cb074382 100644 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementSpec.java +++ b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementSpec.java @@ -10,6 +10,7 @@ import javax.inject.Inject; import org.gradle.api.Project; import org.gradle.api.provider.Property; +import org.gradle.api.tasks.SourceSetContainer; import org.hibernate.orm.tooling.gradle.HibernateOrmSpec; @@ -31,6 +32,8 @@ public class EnhancementSpec { @Inject public EnhancementSpec(HibernateOrmSpec ormDsl, Project project) { + final SourceSetContainer sourceSets = project.getExtensions().getByType( SourceSetContainer.class ); + enableLazyInitialization = makeProperty( project ); enableDirtyTracking = makeProperty( project ); enableAssociationManagement = makeProperty( project ); diff --git a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementTask.java b/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementTask.java deleted file mode 100644 index 4d05bea375..0000000000 --- a/tooling/hibernate-gradle-plugin/src/main/java/org/hibernate/orm/tooling/gradle/enhance/EnhancementTask.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later - * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html - */ -package org.hibernate.orm.tooling.gradle.enhance; - -import java.util.concurrent.atomic.AtomicBoolean; -import javax.inject.Inject; - -import org.gradle.api.DefaultTask; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.execution.TaskExecutionAdapter; -import org.gradle.api.execution.TaskExecutionGraph; -import org.gradle.api.file.DirectoryProperty; -import org.gradle.api.tasks.InputDirectory; -import org.gradle.api.tasks.OutputDirectory; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.TaskAction; -import org.gradle.api.tasks.TaskState; -import org.gradle.work.Incremental; -import org.gradle.work.InputChanges; - -import org.hibernate.orm.tooling.gradle.HibernateOrmSpec; - -import static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE; - -/** - * @author Steve Ebersole - */ -public class EnhancementTask extends DefaultTask { - public static final String DSL_NAME = "hibernateEnhance"; - - public static void apply(HibernateOrmSpec pluginDsl, SourceSet mainSourceSet, Project project) { - final EnhancementTask enhancementTask = project.getTasks().create( - DSL_NAME, - EnhancementTask.class, - pluginDsl, - mainSourceSet, - project - ); - enhancementTask.setGroup( HIBERNATE ); - enhancementTask.setDescription( "Performs Hibernate ORM enhancement of the project's compiled classes" ); - enhancementTask.onlyIf( (t) -> pluginDsl.getSupportEnhancementProperty().getOrElse( true ) ); - - final String compileJavaTaskName = mainSourceSet.getCompileJavaTaskName(); - final Task compileJavaTask = project.getTasks().getByName( compileJavaTaskName ); - enhancementTask.dependsOn( compileJavaTask ); - compileJavaTask.finalizedBy( enhancementTask ); - } - - private final EnhancementSpec enhancementDsl; - private final DirectoryProperty javaCompileOutputDirectory; - private final DirectoryProperty outputDirectory; - - @Inject - public EnhancementTask(HibernateOrmSpec pluginDsl, SourceSet mainSourceSet, Project project) { - enhancementDsl = pluginDsl.getEnhancementSpec(); - javaCompileOutputDirectory = mainSourceSet.getJava().getDestinationDirectory(); - - outputDirectory = project.getObjects().directoryProperty(); - outputDirectory.set( project.getLayout().getBuildDirectory().dir( "tmp/hibernateEnhancement" ) ); - - final AtomicBoolean didCompileRun = new AtomicBoolean( false ); - - final TaskExecutionGraph taskGraph = project.getGradle().getTaskGraph(); - - taskGraph.addTaskExecutionListener( - new TaskExecutionAdapter() { - @Override - public void afterExecute(Task task, TaskState state) { - super.afterExecute( task, state ); - if ( "compileJava".equals( task.getName() ) ) { - if ( state.getDidWork() ) { - didCompileRun.set( true ); - } - } - - taskGraph.removeTaskExecutionListener( this ); - } - } - ); - - getOutputs().upToDateWhen( (task) -> ! didCompileRun.get() ); - } - - @InputDirectory - @Incremental - public DirectoryProperty getJavaCompileDirectory() { - return javaCompileOutputDirectory; - } - - @OutputDirectory - public DirectoryProperty getOutputDirectory() { - return outputDirectory; - } - - @TaskAction - public void enhanceClasses(InputChanges inputChanges) { - if ( !enhancementDsl.hasAnythingToDo() ) { - return; - } - - if ( !inputChanges.isIncremental() ) { - getProject().getLogger().debug( "EnhancementTask inputs were not incremental" ); - } - - if ( enhancementDsl.getEnableExtendedEnhancement().get() ) { - // for extended enhancement, we may need to enhance everything... - // for now, assume we don't - getProject().getLogger().info( "Performing extended enhancement" ); - } - - EnhancementHelper.enhance( javaCompileOutputDirectory, inputChanges, enhancementDsl, getProject() ); - } -} diff --git a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/HibernateOrmPluginTest.java b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/HibernateOrmPluginTest.java index 10bc31cb09..41813c3d21 100644 --- a/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/HibernateOrmPluginTest.java +++ b/tooling/hibernate-gradle-plugin/src/test/java/org/hibernate/orm/tooling/gradle/HibernateOrmPluginTest.java @@ -6,6 +6,7 @@ */ package org.hibernate.orm.tooling.gradle; +import java.io.File; import java.nio.file.Path; import org.gradle.testkit.runner.BuildResult; @@ -13,7 +14,8 @@ import org.gradle.testkit.runner.BuildTask; import org.gradle.testkit.runner.GradleRunner; import org.gradle.testkit.runner.TaskOutcome; -import org.junit.jupiter.api.Disabled; +import org.hibernate.engine.spi.Managed; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -38,27 +40,10 @@ class HibernateOrmPluginTest { ); @Test - public void testEnhancementTask(@TempDir Path projectDir) { + public void testEnhancement(@TempDir Path projectDir) throws Exception { Copier.copyProject( "simple/build.gradle", projectDir ); System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); - final GradleRunner gradleRunner = GradleRunner.create() - .withProjectDir( projectDir.toFile() ) - .withPluginClasspath() - .withDebug( true ) - .withArguments( "clean", "hibernateEnhance", "--stacktrace", "--no-build-cache" ) - .forwardOutput(); - - final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":hibernateEnhance" ); - assertThat( task ).isNotNull(); - assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); - } - - @Test - public void testEnhancementTaskAsFinalizer(@TempDir Path projectDir) { - Copier.copyProject( "simple/build.gradle", projectDir ); - final GradleRunner gradleRunner = GradleRunner.create() .withProjectDir( projectDir.toFile() ) .withPluginClasspath() @@ -67,15 +52,24 @@ class HibernateOrmPluginTest { .forwardOutput(); final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":hibernateEnhance" ); + final BuildTask task = result.task( ":compileJava" ); assertThat( task ).isNotNull(); -// assertThat( task.getOutcome() ).is( anyOf( SUCCESS, UP_TO_DATE ) ); assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + + // make sure the class is enhanced + final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" ); + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + verifyEnhanced( classLoader, "TheEmbeddable" ); + verifyEnhanced( classLoader, "TheEntity" ); + } + + private void verifyEnhanced(ClassLoader classLoader, String className) throws Exception { + final Class loadedClass = classLoader.loadClass( className ); + assertThat( Managed.class ).isAssignableFrom( loadedClass ); } @Test - @Disabled( "up-to-date checking not working" ) - public void testEnhancementTaskUpToDate(@TempDir Path projectDir) { + public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception { Copier.copyProject( "simple/build.gradle", projectDir ); { @@ -84,13 +78,18 @@ class HibernateOrmPluginTest { .withProjectDir( projectDir.toFile() ) .withPluginClasspath() .withDebug( true ) - .withArguments( "clean", "hibernateEnhance", "--stacktrace", "--no-build-cache" ) + .withArguments( "clean", "compileJava", "--stacktrace", "--no-build-cache" ) .forwardOutput(); final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":hibernateEnhance" ); + final BuildTask task = result.task( ":compileJava" ); assertThat( task ).isNotNull(); assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + + // make sure the class is enhanced + final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" ); + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + verifyEnhanced( classLoader, "TheEntity" ); } { @@ -99,12 +98,17 @@ class HibernateOrmPluginTest { .withProjectDir( projectDir.toFile() ) .withPluginClasspath() .withDebug( true ) - .withArguments( "hibernateEnhance", "--stacktrace", "--no-build-cache" ) + .withArguments( "compileJava", "--stacktrace", "--no-build-cache" ) .forwardOutput(); final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":hibernateEnhance" ); + final BuildTask task = result.task( ":compileJava" ); assertThat( task ).isNotNull(); assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); + + // and again + final File classesDir = new File( projectDir.toFile(), "build/classes/java/main" ); + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + verifyEnhanced( classLoader, "TheEntity" ); } } @@ -126,7 +130,7 @@ class HibernateOrmPluginTest { } @Test - @Disabled( "up-to-date checking not working" ) +// @Disabled( "up-to-date checking not working" ) public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) { Copier.copyProject( "simple/build.gradle", projectDir ); @@ -136,7 +140,7 @@ class HibernateOrmPluginTest { .withProjectDir( projectDir.toFile() ) .withPluginClasspath() .withDebug( true ) - .withArguments( "clean", "generateJpaMetamodel", "-xhibernateEnhance", "--stacktrace", "--no-build-cache" ) + .withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) .forwardOutput(); final BuildResult result = gradleRunner.build(); @@ -151,7 +155,7 @@ class HibernateOrmPluginTest { .withProjectDir( projectDir.toFile() ) .withPluginClasspath() .withDebug( true ) - .withArguments( "clean", "generateJpaMetamodel", "-xhibernateEnhance", "--stacktrace", "--no-build-cache" ) + .withArguments( "generateJpaMetamodel", "--stacktrace", "--no-build-cache" ) .forwardOutput(); final BuildResult result2 = gradleRunner2.build(); @@ -162,19 +166,71 @@ class HibernateOrmPluginTest { } @Test - @Disabled( "HHH-15314" ) - public void testEnhanceKotlinModel(@TempDir Path projectDir) { + public void testEnhanceKotlinModel(@TempDir Path projectDir) throws Exception { Copier.copyProject( "simple-kotlin/build.gradle", projectDir ); final GradleRunner gradleRunner = GradleRunner.create() .withProjectDir( projectDir.toFile() ) .withPluginClasspath() .withDebug( true ) - .withArguments( "clean", "hibernateEnhance", "--stacktrace", "--no-build-cache" ) + .withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" ) .forwardOutput(); final BuildResult result = gradleRunner.build(); - final BuildTask task = result.task( ":hibernateEnhance" ); + final BuildTask task = result.task( ":compileKotlin" ); assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + + // make sure the class is enhanced + final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" ); + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + verifyEnhanced( classLoader, "TheEntity" ); + } + + @Test + public void testEnhanceKotlinModelUpToDate(@TempDir Path projectDir) throws Exception { + Copier.copyProject( "simple-kotlin/build.gradle", projectDir ); + + { + System.out.println( "First execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + + final GradleRunner gradleRunner = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( "clean", "compileKotlin", "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + + final BuildResult result = gradleRunner.build(); + final BuildTask task = result.task( ":compileKotlin" ); + assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS ); + + // make sure the class is enhanced + final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" ); + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + verifyEnhanced( classLoader, "TheEntity" ); + } + { + System.out.println( "Second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); + + final GradleRunner gradleRunner = GradleRunner.create() + .withProjectDir( projectDir.toFile() ) + .withPluginClasspath() + .withDebug( true ) + .withArguments( "compileKotlin", "--stacktrace", "--no-build-cache" ) + .forwardOutput(); + + final BuildResult result = gradleRunner.build(); + final BuildTask task = result.task( ":compileKotlin" ); + assertThat( task ).isNotNull(); + assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE ); + + // make sure the class is enhanced + final File classesDir = new File( projectDir.toFile(), "build/classes/kotlin/main" ); + final ClassLoader classLoader = Helper.toClassLoader( classesDir ); + verifyEnhanced( classLoader, "TheEntity" ); + } + } }