From 5789bc78350d40412dc5f2338d095f579558622f Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Tue, 28 May 2024 18:14:45 +0200 Subject: [PATCH] HSEARCH-3319 WIP: maven plugin to generate "metamodel classes" while compiling in the same module ... --- metamodel/generator-plugin/pom.xml | 2 + ...HibernateSearchMetamodelGeneratorMojo.java | 101 ++++++++++++++++-- metamodel/generator-test/generation/pom.xml | 2 +- metamodel/generator-test/model/pom.xml | 28 +++++ 4 files changed, 122 insertions(+), 11 deletions(-) diff --git a/metamodel/generator-plugin/pom.xml b/metamodel/generator-plugin/pom.xml index c5b584394aa..35822183588 100644 --- a/metamodel/generator-plugin/pom.xml +++ b/metamodel/generator-plugin/pom.xml @@ -18,6 +18,8 @@ false true org.hibernate.search.metamodel.generator.plugin + true + true diff --git a/metamodel/generator-plugin/src/main/java/org/hibernate/search/metamodel/generator/plugin/HibernateSearchMetamodelGeneratorMojo.java b/metamodel/generator-plugin/src/main/java/org/hibernate/search/metamodel/generator/plugin/HibernateSearchMetamodelGeneratorMojo.java index 7ed7ee193cf..2dcb350d4cf 100644 --- a/metamodel/generator-plugin/src/main/java/org/hibernate/search/metamodel/generator/plugin/HibernateSearchMetamodelGeneratorMojo.java +++ b/metamodel/generator-plugin/src/main/java/org/hibernate/search/metamodel/generator/plugin/HibernateSearchMetamodelGeneratorMojo.java @@ -6,15 +6,28 @@ */ package org.hibernate.search.metamodel.generator.plugin; +import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Properties; +import java.util.stream.Collectors; + +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; import org.hibernate.SessionFactory; import org.hibernate.search.engine.backend.metamodel.IndexDescriptor; @@ -25,6 +38,7 @@ import org.hibernate.search.util.impl.integrationtest.backend.lucene.LuceneBackendConfiguration; import org.hibernate.search.util.impl.integrationtest.mapper.orm.OrmSetupHelper; +import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -43,9 +57,17 @@ public class HibernateSearchMetamodelGeneratorMojo extends AbstractMojo { @Parameter(property = "annotatedTypes") List annotatedTypes; + @Parameter(property = "packagesToCompile") + List packagesToCompile; + @Parameter(property = "properties") Properties properties; + @Parameter(property = "sameModuleCompile", defaultValue = "false") + boolean sameModuleCompile; + + private URLClassLoader classLoader; + @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info( "Hibernate Search Metamodel Generator" ); @@ -60,8 +82,6 @@ public void execute() throws MojoExecutionException, MojoFailureException { Path generatedMetamodelLocation = Path.of( project.getBuild().getOutputDirectory() ).resolveSibling( "generated-metamodel-sources" ); - project.addCompileSourceRoot( generatedMetamodelLocation.toString() ); - try ( SessionFactory sessionFactory = setupContext.setup( annotatedTypes() ) ) { SearchMapping mapping = Search.mapping( sessionFactory ); @@ -75,7 +95,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { getLog().info( "Indexed entities: " + indexedEntities ); } - + project.addCompileSourceRoot( generatedMetamodelLocation.toString() ); } } @@ -112,18 +132,79 @@ private void createClass(SearchIndexedEntity indexedEntity, Path root) { } private Class[] annotatedTypes() { - try { - Class[] types = new Class[annotatedTypes.size()]; - for ( int i = 0; i < annotatedTypes.size(); i++ ) { - types[i] = Class.forName( annotatedTypes.get( i ) ); + if ( sameModuleCompile ) { + try { + List roots = new ArrayList<>(); + List classes = new ArrayList<>(); + for ( String compileSourceRoot : this.project.getCompileSourceRoots() ) { + Path root = Path.of( compileSourceRoot ); + roots.add( root ); + + for ( String pkg : packagesToCompile ) { + Path path = root.resolve( Path.of( pkg.replace( ".", FileSystems.getDefault().getSeparator() ) ) ); + if ( Files.exists( path ) ) { + Files.list( path ).filter( f -> f.getFileName().toString().endsWith( ".java" ) ) + .forEach( classes::add ); + } + } + } + + Path output = Path.of( project.getBuild().getOutputDirectory() ) + .resolveSibling( "generated-metamodel-pre-compiled-classes" ); + Files.createDirectories( output ); + + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager( null, null, null ); + fileManager.setLocationFromPaths( StandardLocation.SOURCE_PATH, roots ); + fileManager.setLocation( StandardLocation.CLASS_PATH, getDependenciesAsFiles() ); + fileManager.setLocationFromPaths( StandardLocation.CLASS_OUTPUT, List.of( output ) ); + + Iterable toCompile = fileManager.getJavaFileObjectsFromPaths( classes ); + + DiagnosticCollector diagnostic = new DiagnosticCollector<>(); + JavaCompiler.CompilationTask task = + compiler.getTask( null, fileManager, diagnostic, List.of(), null, toCompile ); + + task.call(); + + classLoader = new URLClassLoader( "hibernate-search-generator", + new URL[] { output.toUri().toURL() }, this.getClass().getClassLoader() ); + Thread.currentThread().setContextClassLoader( classLoader ); + + Class[] types = new Class[annotatedTypes.size()]; + for ( int i = 0; i < annotatedTypes.size(); i++ ) { + types[i] = classLoader.loadClass( annotatedTypes.get( i ) ); + } + return types; + + } + catch (IOException | ClassNotFoundException e) { + throw new RuntimeException( e ); } - return types; } - catch (ClassNotFoundException e) { - throw new RuntimeException( e ); + else { + try { + Class[] types = new Class[annotatedTypes.size()]; + for ( int i = 0; i < annotatedTypes.size(); i++ ) { + types[i] = Class.forName( annotatedTypes.get( i ) ); + } + return types; + } + catch (ClassNotFoundException e) { + throw new RuntimeException( e ); + } } } + private Collection getDependenciesAsFiles() { + project.setArtifactFilter( artifact -> true ); + project.setArtifacts( null ); + return project.getArtifacts() + .stream() + .map( Artifact::getFile ) + .collect( Collectors.toList() ); + } + private boolean hasOrmMapper(List dependencies) { for ( Dependency dependency : dependencies ) { if ( "hibernate-search-mapper-orm".equals( dependency.getArtifactId() ) ) { diff --git a/metamodel/generator-test/generation/pom.xml b/metamodel/generator-test/generation/pom.xml index 7ace37ce175..5571ee51238 100644 --- a/metamodel/generator-test/generation/pom.xml +++ b/metamodel/generator-test/generation/pom.xml @@ -15,7 +15,7 @@ false org.hibernate.search.metamodel.generator.test - h2 + true diff --git a/metamodel/generator-test/model/pom.xml b/metamodel/generator-test/model/pom.xml index 69b0abaae2a..dde5d20b157 100644 --- a/metamodel/generator-test/model/pom.xml +++ b/metamodel/generator-test/model/pom.xml @@ -15,6 +15,7 @@ false org.hibernate.search.metamodel.generator + true @@ -65,6 +66,33 @@ + + org.hibernate.search + hibernate-search-metamodel-generator-plugin + ${project.version} + + + generate + + generate-metamodel + + generate-sources + + true + + org.hibernate.search.metamodel.generator.model.MyEntity + org.hibernate.search.metamodel.generator.model.MyProgrammaticEntity + + + org.hibernate.search.metamodel.generator.model + + + org.hibernate.search.metamodel.generator.model.MyConfigurer + + + + +