From a00c017a84bdf8cbbd4cbf2843776629cbdbd390 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 17 Oct 2025 09:13:41 +0200 Subject: [PATCH 1/2] Update to Gradle 9.1 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2a84e18..2e11132 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 74972b41f9bc0fe98fbccc0af0311d1c469b46f7 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Fri, 17 Oct 2025 14:42:04 +0200 Subject: [PATCH 2/2] Make plugin register the task rather than relying on doLast and project references --- README.md | 9 ++- .../build/gradle/inject/InjectionPlugin.java | 27 ++++--- .../build/gradle/inject/InjectionSpec.java | 28 +------ ...njectionAction.java => InjectionTask.java} | 74 +++++++++---------- .../build/gradle/inject/TargetMember.java | 6 +- 5 files changed, 70 insertions(+), 74 deletions(-) rename src/main/java/org/hibernate/build/gradle/inject/{InjectionAction.java => InjectionTask.java} (83%) diff --git a/README.md b/README.md index 7b404e1..14050a0 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ version-injection-plugin Gradle plugin used by Hibernate to inject project version into compiled classes To use you'd simply apply the plugin (after making sure it is added to your buildscript classpath): -``` +```groovy buildscript { ... dependencies { @@ -16,9 +16,12 @@ apply plugin: 'version-injection' ``` Then, you'd configure it. Configuration mainly involves naming the Class member to inject the project version into: -``` +```groovy versionInjection { - into( 'com.acme.Version', 'getVersionString' ) + version.set('version') + targetMembers.set(List.of( + member('com.acme.Version', 'getVersionString') + )) } ``` diff --git a/src/main/java/org/hibernate/build/gradle/inject/InjectionPlugin.java b/src/main/java/org/hibernate/build/gradle/inject/InjectionPlugin.java index 735c2d0..2b37742 100644 --- a/src/main/java/org/hibernate/build/gradle/inject/InjectionPlugin.java +++ b/src/main/java/org/hibernate/build/gradle/inject/InjectionPlugin.java @@ -25,7 +25,8 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; -import org.gradle.api.Task; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.tasks.TaskProvider; /** * Mainly used to apply the InjectionAction to the main compileJava task @@ -39,15 +40,23 @@ public class InjectionPlugin implements Plugin { public void apply(Project project) { project.getPluginManager().apply( "java" ); - // Allow user to configure - final InjectionSpec injectionSpec = new InjectionSpec( project ); - project.getExtensions().add( EXTENSION_NAME, injectionSpec ); + final InjectionSpec injectionSpec = project.getExtensions().create( EXTENSION_NAME, InjectionSpec.class ); - // The action to run after compilation - final InjectionAction injectionAction = new InjectionAction( injectionSpec ); - final Task compileJava = project.getTasks().getByName( "compileJava" ); - compileJava.getInputs().property( "version-injection-targets", injectionSpec.getTargetMembers() ); - compileJava.doLast( injectionAction ); + final TaskProvider injectionTaskProvider = project.getTasks().register( + InjectionTask.TASK_NAME, InjectionTask.class, task -> { + JavaPluginExtension javaExtension = (JavaPluginExtension) project.getExtensions().getByName( "java" ); + + task.getVersion().set( injectionSpec.getVersion() ); + task.getInjectionTargets().set( injectionSpec.getTargetMembers() ); + + task.getClasspath().setFrom( + javaExtension.getSourceSets().getByName( "main" ).getOutput().getClassesDirs() + ); + + task.dependsOn( project.getTasks().named( "compileJava" ) ); + } + ); + project.getTasks().named( "classes" ).configure( classes -> classes.dependsOn( injectionTaskProvider ) ); } } diff --git a/src/main/java/org/hibernate/build/gradle/inject/InjectionSpec.java b/src/main/java/org/hibernate/build/gradle/inject/InjectionSpec.java index daf145f..701c796 100644 --- a/src/main/java/org/hibernate/build/gradle/inject/InjectionSpec.java +++ b/src/main/java/org/hibernate/build/gradle/inject/InjectionSpec.java @@ -1,35 +1,15 @@ package org.hibernate.build.gradle.inject; -import javax.inject.Inject; - -import org.gradle.api.Project; -import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.Property; /** * @author Steve Ebersole */ -public class InjectionSpec { - private final ListProperty targetMembers; - - @Inject - public InjectionSpec(ObjectFactory objects) { - targetMembers = objects.listProperty( TargetMember.class ); - } - - public InjectionSpec(Project project) { - this( project.getObjects() ); - } +public abstract class InjectionSpec { - public ListProperty getTargetMembers() { - return targetMembers; - } + public abstract Property getVersion(); - public void into(String className, String member) { - into( new TargetMember( className, member ) ); - } + public abstract ListProperty getTargetMembers(); - private void into(TargetMember targetMember) { - targetMembers.add( targetMember ); - } } diff --git a/src/main/java/org/hibernate/build/gradle/inject/InjectionAction.java b/src/main/java/org/hibernate/build/gradle/inject/InjectionTask.java similarity index 83% rename from src/main/java/org/hibernate/build/gradle/inject/InjectionAction.java rename to src/main/java/org/hibernate/build/gradle/inject/InjectionTask.java index 3fc1d38..075e308 100644 --- a/src/main/java/org/hibernate/build/gradle/inject/InjectionAction.java +++ b/src/main/java/org/hibernate/build/gradle/inject/InjectionTask.java @@ -33,6 +33,9 @@ import java.net.URLClassLoader; import java.util.ArrayList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import javassist.ClassPool; import javassist.CtClass; import javassist.CtField; @@ -43,64 +46,62 @@ import javassist.bytecode.ClassFile; import javassist.bytecode.ConstantAttribute; import javassist.bytecode.FieldInfo; -import org.gradle.api.Action; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.SourceSetContainer; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.gradle.api.DefaultTask; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.provider.ListProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputFiles; +import org.gradle.api.tasks.TaskAction; /** - * Responsible for coordinating the actual injection of project version. Runs as a Gradle Action (doLast typically - * to the main CompileJava task) + * Responsible for coordinating the actual injection of project version. * * @author Steve Ebersole */ -public class InjectionAction implements Action { - private static final Logger log = LoggerFactory.getLogger( InjectionAction.class ); +public abstract class InjectionTask extends DefaultTask { + static final String TASK_NAME = "injectVersion"; + private static final Logger log = LoggerFactory.getLogger( InjectionTask.class ); private LoaderClassPath loaderClassPath; private ClassPool classPool; - private final InjectionSpec injectionSpec; + @InputFiles + abstract ConfigurableFileCollection getClasspath(); - public InjectionAction(InjectionSpec injectionSpec) { - this.injectionSpec = injectionSpec; - } + @Input + public abstract Property getVersion(); + + @Input + public abstract ListProperty getInjectionTargets(); - @Override - public void execute(Task task) { - final ClassLoader runtimeScopeClassLoader = buildRuntimeScopeClassLoader( task.getProject() ); + @TaskAction + public void execute() { + final ClassLoader runtimeScopeClassLoader = buildRuntimeScopeClassLoader(); loaderClassPath = new LoaderClassPath( runtimeScopeClassLoader ); classPool = new ClassPool( true ); classPool.appendClassPath( loaderClassPath ); - performInjections( task.getProject() ); + performInjections(); } - private ClassLoader buildRuntimeScopeClassLoader(Project project) { + private ClassLoader buildRuntimeScopeClassLoader() { final ArrayList classPathUrls = new ArrayList<>(); - final SourceSet mainSourceSet = project - .getExtensions() - .getByType( SourceSetContainer.class ) - .getByName( SourceSet.MAIN_SOURCE_SET_NAME ); - for ( File file : mainSourceSet.getRuntimeClasspath() ) { + getClasspath().forEach( file -> { try { classPathUrls.add( file.toURI().toURL() ); } catch (MalformedURLException e) { throw new InjectionException( "Could not determine artifact URL [" + file.getPath() + "]", e ); } - } + } ); return new URLClassLoader( classPathUrls.toArray( URL[]::new ), getClass().getClassLoader() ); } - private void performInjections(Project project) { - final String projectVersion = project.getVersion().toString(); + private void performInjections() { + final String projectVersion = getVersion().get(); - for ( TargetMember targetMember : injectionSpec.getTargetMembers().get() ) { + for ( TargetMember targetMember : getInjectionTargets().get() ) { resolveInjectionTarget( targetMember ).inject( projectVersion ); } } @@ -113,7 +114,7 @@ private InjectionTarget resolveInjectionTarget(TargetMember targetMember) { CtField field = ctClass.getField( targetMember.getMemberName() ); return new FieldInjectionTarget( targetMember, ctClass, field ); } - catch( NotFoundException ignore ) { + catch (NotFoundException ignore) { } // see if it is a method... @@ -133,7 +134,7 @@ private InjectionTarget resolveInjectionTarget(TargetMember targetMember) { // finally throw an exception throw new InjectionException( "Unknown member [" + targetMember.getQualifiedName() + "]" ); } - catch ( Throwable e ) { + catch (Throwable e) { throw new InjectionException( "Unable to resolve class [" + targetMember.getClassName() + "]", e ); } } @@ -146,14 +147,13 @@ private interface InjectionTarget { * Inject the given value per this target's strategy. * * @param value The value to inject. - * * @throws org.hibernate.build.gradle.inject.InjectionException Indicates a problem performing the injection. */ void inject(String value); } private abstract class BaseInjectionTarget implements InjectionTarget { - @SuppressWarnings( {"UnusedDeclaration"}) + @SuppressWarnings({ "UnusedDeclaration" }) private final TargetMember targetMember; private final CtClass ctClass; private final File classFileLocation; @@ -164,7 +164,7 @@ protected BaseInjectionTarget(TargetMember targetMember, CtClass ctClass) { try { classFileLocation = new File( loaderClassPath.find( targetMember.getClassName() ).toURI() ); } - catch ( Throwable e ) { + catch (Throwable e) { throw new InjectionException( "Unable to resolve class file path", e ); } } @@ -205,7 +205,7 @@ private class FieldInjectionTarget extends BaseInjectionTarget { private FieldInjectionTarget(TargetMember targetMember, CtClass ctClass, CtField ctField) { super( targetMember, ctClass ); this.ctField = ctField; - if ( ! Modifier.isStatic( ctField.getModifiers() ) ) { + if ( !Modifier.isStatic( ctField.getModifiers() ) ) { throw new InjectionException( "Field is not static [" + targetMember.getQualifiedName() + "]" ); } } @@ -237,7 +237,7 @@ protected void doInjection(String value) { try { ctMethod.setBody( "{return \"" + value + "\";}" ); } - catch ( Throwable t ) { + catch (Throwable t) { throw new InjectionException( "Unable to replace method body", t ); } } diff --git a/src/main/java/org/hibernate/build/gradle/inject/TargetMember.java b/src/main/java/org/hibernate/build/gradle/inject/TargetMember.java index 758473e..0cb1643 100644 --- a/src/main/java/org/hibernate/build/gradle/inject/TargetMember.java +++ b/src/main/java/org/hibernate/build/gradle/inject/TargetMember.java @@ -33,11 +33,15 @@ public class TargetMember implements Serializable { private final String className; private final String memberName; - public TargetMember(String className, String memberName) { + private TargetMember(String className, String memberName) { this.className = className; this.memberName = memberName; } + public static TargetMember member(String className, String memberName) { + return new TargetMember( className, memberName ); + } + public String getClassName() { return className; }