001/* 002 * Copyright 2017-2022 original authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.micronaut.maven.aot; 017 018import io.micronaut.maven.AbstractMicronautMojo; 019import io.micronaut.maven.Packaging; 020import io.micronaut.maven.services.CompilerService; 021import org.apache.commons.io.FileUtils; 022import org.apache.maven.plugin.MojoExecutionException; 023import org.apache.maven.plugins.annotations.Parameter; 024import org.apache.maven.project.MavenProject; 025import org.eclipse.aether.resolution.DependencyResolutionException; 026 027import java.io.File; 028import java.io.IOException; 029 030/** 031 * Abstract Mojo for Micronaut AOT. 032 */ 033public abstract class AbstractMicronautAotMojo extends AbstractMicronautMojo { 034 035 protected final CompilerService compilerService; 036 037 protected final MavenProject mavenProject; 038 039 /** 040 * Micronaut AOT runtime. Possible values: <code>jit</code>, <code>native</code>. 041 */ 042 @Parameter(property = "micronaut.aot.runtime", required = true, defaultValue = "jit") 043 protected String runtime; 044 045 /** 046 * Micronaut AOT version. 047 */ 048 @Parameter(property = "micronaut.aot.version", required = true) 049 protected String micronautAotVersion; 050 051 /** 052 * Whether to enable or disable Micronaut AOT. 053 */ 054 @Parameter(property = "micronaut.aot.enabled", defaultValue = "false") 055 protected boolean enabled; 056 057 /** 058 * Directory where compiled application classes are. 059 */ 060 @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) 061 protected File outputDirectory; 062 063 public AbstractMicronautAotMojo(CompilerService compilerService, MavenProject mavenProject) { 064 this.compilerService = compilerService; 065 this.mavenProject = mavenProject; 066 } 067 068 abstract void onSuccess(File outputDir) throws MojoExecutionException; 069 070 protected final File getBaseOutputDirectory() { 071 var targetDirectory = new File(mavenProject.getBuild().getDirectory(), "aot"); 072 return new File(targetDirectory, runtime); 073 } 074 075 protected final File outputFile(String name) { 076 return new File(getBaseOutputDirectory(), name); 077 } 078 079 @Override 080 public final void execute() throws MojoExecutionException { 081 if (!enabled) { 082 return; 083 } 084 validateRuntime(); 085 getLog().info("Running Micronaut AOT " + micronautAotVersion + " " + getName()); 086 try { 087 File baseOutputDirectory = getBaseOutputDirectory(); 088 clean(baseOutputDirectory); 089 clean(outputDirectory); 090 doExecute(); 091 onSuccess(baseOutputDirectory); 092 } catch (DependencyResolutionException | IOException e) { 093 throw new MojoExecutionException("Unable to generate AOT optimizations", e); 094 } 095 } 096 097 private void clean(File baseOutputDirectory) throws IOException { 098 if (baseOutputDirectory.exists()) { 099 getLog().debug("Deleting " + baseOutputDirectory.getAbsolutePath()); 100 FileUtils.deleteDirectory(baseOutputDirectory); 101 } 102 baseOutputDirectory.mkdirs(); 103 } 104 105 private void validateRuntime() { 106 var packaging = Packaging.of(mavenProject.getPackaging()); 107 var aotRuntime = AotRuntime.valueOf(runtime.toUpperCase()); 108 switch (packaging) { 109 case JAR, DOCKER_CRAC, DOCKER -> { 110 if (aotRuntime != AotRuntime.JIT) { 111 warnRuntimeMismatchAndSetCorrectValue(AotRuntime.JIT); 112 } 113 } 114 case NATIVE_IMAGE, DOCKER_NATIVE -> { 115 if (aotRuntime != AotRuntime.NATIVE) { 116 warnRuntimeMismatchAndSetCorrectValue(AotRuntime.NATIVE); 117 } 118 } 119 default -> throw new IllegalArgumentException("Unsupported packaging: " + packaging); 120 } 121 } 122 123 private void warnRuntimeMismatchAndSetCorrectValue(final AotRuntime correctRuntime) { 124 String correctRuntimeString = correctRuntime.name().toLowerCase(); 125 getLog().warn("Packaging is set to [" + mavenProject.getPackaging() + "], but Micronaut AOT runtime is set to [" + runtime + "]. Setting AOT runtime to: [" + correctRuntimeString + "]"); 126 this.runtime = correctRuntimeString; 127 } 128 129 protected abstract void doExecute() throws DependencyResolutionException, MojoExecutionException; 130 131 abstract String getName(); 132}