diff --git a/documentation/src/main/asciidoc/topical/bytecode/BytecodeEnhancement.adoc b/documentation/src/main/asciidoc/topical/bytecode/BytecodeEnhancement.adoc index 812658b936..157b09ed6e 100644 --- a/documentation/src/main/asciidoc/topical/bytecode/BytecodeEnhancement.adoc +++ b/documentation/src/main/asciidoc/topical/bytecode/BytecodeEnhancement.adoc @@ -78,13 +78,16 @@ hibernate { ---- ==== -Currently the "enhance" extension supports 3 properties: +Currently the "enhance" extension supports 4 properties: * `enableLazyInitialization` * `enableDirtyTracking` * `enableAssociationManagement` + * `enableFieldAccessEnhancement` -Once enhancement overall is enabled, the default for these 3 properties is `true`. +Once enhancement overall is enabled, the default for the first 3 properties is `true`. Field access is not enhanced by +default, as it can potentially trigger enhancement of code outside the entities, and also because it assumes that all +the target entities are enhanced, which may not always be the case. === Ant Task diff --git a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/EnhanceExtension.groovy b/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/EnhanceExtension.groovy index 58ccf5f576..a3d2a660f5 100644 --- a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/EnhanceExtension.groovy +++ b/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/EnhanceExtension.groovy @@ -16,8 +16,9 @@ class EnhanceExtension { def boolean enableLazyInitialization = true def boolean enableDirtyTracking = true def boolean enableAssociationManagement = true + def boolean enableFieldAccessEnhancement = false boolean shouldApply() { - return enableLazyInitialization || enableDirtyTracking || enableAssociationManagement; + return enableLazyInitialization || enableDirtyTracking || enableAssociationManagement || enableFieldAccessEnhancement; } } diff --git a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/EnhancerTask.groovy b/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/EnhancerTask.groovy deleted file mode 100644 index dfecfe3786..0000000000 --- a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/EnhancerTask.groovy +++ /dev/null @@ -1,159 +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 . - */ -package org.hibernate.orm.tooling.gradle - -import javax.persistence.ElementCollection -import javax.persistence.Entity -import javax.persistence.ManyToMany -import javax.persistence.OneToMany -import javax.persistence.Transient - -import javassist.ClassPool -import javassist.CtClass -import javassist.CtField - -import org.gradle.api.DefaultTask -import org.gradle.api.file.FileTree -import org.gradle.api.tasks.TaskAction - -import org.hibernate.bytecode.enhance.spi.EnhancementContext -import org.hibernate.bytecode.enhance.spi.Enhancer - -/** - * Gradle Task to apply Hibernate's bytecode Enhancer - * - * @author Jeremy Whiting - */ -public class EnhancerTask extends DefaultTask implements EnhancementContext { - - private ClassLoader overridden - - public EnhancerTask() { - super() - setDescription( 'Enhances Entity classes for efficient association referencing.' ) - } - - @TaskAction - def enhance() { - logger.info( 'enhance task started' ) - ext.pool = new ClassPool( false ) - ext.enhancer = new Enhancer( this ) - FileTree tree = project.fileTree( dir: project.sourceSets.main.output.classesDir ) - tree.include '**/*.class' - tree.each( { File file -> - final byte[] enhancedBytecode; - InputStream is = null; - CtClass clas = null; - try { - is = new FileInputStream( file.toString() ) - clas = ext.pool.makeClass( is ) - // Enhancer already does this check to see if it should enhance, why are we doing it again here? - if ( !clas.hasAnnotation( Entity.class ) ) { - logger.debug( "Class $file not an annotated Entity class. skipping..." ) - } - else { - enhancedBytecode = ext.enhancer.enhance( clas.getName(), clas.toBytecode() ); - } - } - catch (Exception e) { - logger.error( "Unable to enhance class [${file.toString()}]", e ) - return - } - finally { - try { - if ( null != is ) { - is.close() - }; - } - finally {} - } - if ( null != enhancedBytecode ) { - if ( file.delete() ) { - if ( !file.createNewFile() ) { - logger.error( "Unable to recreate class file [" + clas.getName() + "]" ) - } - } - else { - logger.error( "Unable to delete class file [" + clas.getName() + "]" ) - } - FileOutputStream outputStream = new FileOutputStream( file, false ) - try { - outputStream.write( enhancedBytecode ) - outputStream.flush() - } - finally { - try { - if ( outputStream != null ) { - outputStream.close() - } - clas.detach()//release memory - } - catch (IOException ignore) { - } - } - } - } ) - logger.info( 'enhance task finished' ) - } - - public ClassLoader getLoadingClassLoader() { - if ( null == this.overridden ) { - return getClass().getClassLoader(); - } - else { - return this.overridden; - } - } - - public void setClassLoader(ClassLoader loader) { - this.overridden = loader; - } - - public boolean isEntityClass(CtClass classDescriptor) { - return true; - } - - public boolean hasLazyLoadableAttributes(CtClass classDescriptor) { - return true; - } - - public boolean isLazyLoadable(CtField field) { - return true; - } - - public boolean isCompositeClass(CtClass classDescriptor) { - return false; - } - - public boolean doBiDirectionalAssociationManagement(CtField field) { - return false; - } - - public boolean doDirtyCheckingInline(CtClass classDescriptor) { - return true; - } - - public CtField[] order(CtField[] fields) { - // TODO: load ordering from configuration. - return fields; - } - - public boolean isMappedCollection(CtField field) { - try { - return (field.getAnnotation(OneToMany.class) != null || - field.getAnnotation(ManyToMany.class) != null || - field.getAnnotation(ElementCollection.class) != null); - } - catch (ClassNotFoundException e) { - return false; - } - } - - public boolean isPersistentField(CtField ctField) { - return !ctField.hasAnnotation( Transient.class ); - } -} diff --git a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/HibernatePlugin.java b/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/HibernatePlugin.java index 2a18134146..02b2ea8dd0 100644 --- a/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/HibernatePlugin.java +++ b/tooling/hibernate-gradle-plugin/src/main/groovy/org/hibernate/orm/tooling/gradle/HibernatePlugin.java @@ -110,6 +110,11 @@ public class HibernatePlugin implements Plugin { public boolean isLazyLoadable(CtField field) { return hibernateExtension.enhance.getEnableLazyInitialization(); } + + @Override + public boolean doFieldAccessEnhancement(CtClass classDescriptor) { + return hibernateExtension.enhance.getEnableFieldAccessEnhancement(); + } }; final Enhancer enhancer = new Enhancer( enhancementContext ); diff --git a/tooling/hibernate-gradle-plugin/src/test/groovy/org/hibernate/orm/tooling/gradle/HibernatePluginTest.groovy b/tooling/hibernate-gradle-plugin/src/test/groovy/org/hibernate/orm/tooling/gradle/HibernatePluginTest.groovy index ff5452fc92..cf46d2af04 100644 --- a/tooling/hibernate-gradle-plugin/src/test/groovy/org/hibernate/orm/tooling/gradle/HibernatePluginTest.groovy +++ b/tooling/hibernate-gradle-plugin/src/test/groovy/org/hibernate/orm/tooling/gradle/HibernatePluginTest.groovy @@ -5,15 +5,12 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.orm.tooling.gradle - import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder import org.junit.Test import static org.junit.Assert.assertNotNull -import static org.junit.Assert.assertTrue - /** * Test what we can. ProjectBuilder is better than nothing, but still quited limited in what * you can test (e.g. you cannot test task execution). @@ -35,7 +32,10 @@ class HibernatePluginTest { project.plugins.apply 'org.hibernate.orm' project.extensions.findByType( HibernateExtension.class ).enhance { + enableLazyInitialization = true + enableDirtyTracking = true enableAssociationManagement = false + enableFieldAccessEnhancement = false } } }