All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tentackle.maven.plugin.jlink.JLinkMojo Maven / Gradle / Ivy

There is a newer version: 21.16.1.0
Show newest version
/*
 * Tentackle - https://tentackle.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.tentackle.maven.plugin.jlink;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;

import org.tentackle.common.StringHelper;

/**
 * Creates a self-contained java application with the jlink tool.
 * 

* This mojo works for modular, non-modular and even mixed applications. It's not just a wrapper for jlink, * but analyzes the project's dependencies and finds the best strategy to invoke jlink to * create a directory containing an application-specific jimage module. As a result, it requires * only minimum configuration. *

* Basically, applications fall into one of 3 categories: *

    *
  1. Full-blown modular applications: all module-infos must require real modules only. Jlink creates * an image from those modules. Optional artifacts and runtime modules can still be added.
  2. *
  3. Modular applications with non-modular dependencies: jlink is used to create an image from the minimum necessary java runtime modules only, * which are determined by the plugin either from the module-infos or via the jdeps tool. * The application's dependencies are placed on the modulepath via the generated run-script.
  4. *
  5. Non-modular traditional classpath applications: same as 2, but all dependencies are placed on the classpath.
  6. *
* Since it is very likely, that even modern modular applications require some 3rd-party dependencies not modularized yet, * most of those applications will probably fall into the second category. *

* Artifacts not processed by jlink are copied to separate folders and passed to the java runtime explicitly * via the module- and/or classpath. A platform-specific launch script will be generated according to * the {@link #runTemplate}. For applications using Tentackle's auto update feature, an update script is generated via the {@link #updateTemplate} * as well. Finally, the created directory is packed into a deployable zip file. *

* The minimum plugin configuration is very simple: * *

 *   ...
 *   <packaging>jlink</packaging>
 *   ...
 *       <plugin>
 *         <groupId>org.tentackle</groupId>
 *         <artifactId>tentackle-jlink-maven-plugin</artifactId>
 *         <version>${tentackle.version}</version>
 *         <extensions>true</extensions>
 *         <configuration>
 *           <mainModule>com.example</mainModule>
 *           <mainClass>com.example.MyApp</mainClass>
 *         </configuration>
 *       </plugin>
 * 
* * The freemarker templates are copied to the project's template folder, if missing. * They become part of the project and can be changed easily according to project specific needs (for example by adding runtime arguments). * To install and edit the templates before running jlink (or jpackage, see {@link JPackageMojo}), use {@link InitMojo} first. *

* The template model provides the following variables: * *

    *
  • mainModule: the name of the main module. Empty if classpath application.
  • *
  • mainClass: the name of the main class.
  • *
  • modulePath: the module path.
  • *
  • classPath: the class path
  • *
  • phase: the mojo lifecycle phase
  • *
  • goal: the plugin goal (jlink or jpackage)
  • *
  • id: the execution id
  • *
  • all system properties (dots in property names translated to camelCase, e.g. "os.name" becomes "osName"
  • *
  • all maven properties (translated to camelCase as well)
  • *
  • the plugin configuration {@link AbstractJLinkMojo#getVariables()}
  • *
* * Modules not passed to jlink and automatic modules are copied to the mp folder * and added to the modulePath template variable. If no such modules are detected, no folder is created.
* Non-modular classpath artifacts are copied to the cp folder and added to the classPath template variable. * Again, the folder will only be created if necessary.
* Additional project resources, such as property files or logger configurations, are copied to the conf directory and * this directory prepended to the classpath. *

* The generation of the ZIP-file and attachment of the artifact for installation and deployment can be customized by an * application-specific implementation. This allows further modification of the generated image or files in the jlink target * directory. It is also possible to add more than one artifact, for example, each with a different configuration. * To do so, provide a plugin dependency that contains a class annotated with {@code @Service(}{@link ArtifactCreator}). *

* Notice that you can create an image for a different java version than the one used for the maven build process * by specifying an explicit {@code AbstractJLinkMojo#getToolchain()}. */ @Mojo(name = "jlink", requiresDependencyResolution = ResolutionScope.RUNTIME, defaultPhase = LifecyclePhase.PACKAGE) public class JLinkMojo extends AbstractJLinkMojo { /** filename of the NAME template. */ public static final String NAME_TEMPLATE = "name.ftl"; /** filename of the RUN template. */ public static final String RUN_TEMPLATE = "run.ftl"; /** filename of the UPDATE template. */ public static final String UPDATE_TEMPLATE = "update.ftl"; /** * The name of the template to generate the name of the runner script.
* For *nixes this is usually {@code run.sh}, for windozes {@code run.cmd} or {@code run.bat}. */ @Parameter(defaultValue = NAME_TEMPLATE) private String nameTemplate; /** * The name of the runner script template. */ @Parameter(defaultValue = RUN_TEMPLATE) private String runTemplate; /** * The name of the update script template. */ @Parameter(defaultValue = UPDATE_TEMPLATE) private String updateTemplate; /** * Gets the name of the name template. * * @return the template to generate the name of the runner script */ public String getNameTemplate() { return nameTemplate; } /** * Gets the name of the runner template. * * @return the template to generate the runner script */ public String getRunTemplate() { return runTemplate; } /** * Gets the name of the update template. * * @return the template to generate the update script, null if don't generate an update script */ public String getUpdateTemplate() { return isWithUpdater() ? updateTemplate : null; } @Override public void executeImpl() throws MojoExecutionException, MojoFailureException { super.executeImpl(); ArtifactCreator.getInstance().createAndAttachArtifact(this); } @Override protected void generateFiles(JLinkResolver.Result result) throws MojoExecutionException { // generate the script to run the application in the bin subdirectory new JLinkGenerator(this, result).generateScripts(); } @Override protected boolean validate() throws MojoExecutionException { if (super.validate()) { if (StringHelper.isAllWhitespace(nameTemplate)) { throw new MojoExecutionException("nameTemplate missing"); } if (StringHelper.isAllWhitespace(runTemplate)) { throw new MojoExecutionException("runTemplate missing"); } if (isWithUpdater() && StringHelper.isAllWhitespace(updateTemplate)) { throw new MojoExecutionException("updateTemplate missing"); } return true; } return false; } @Override protected void installTemplates(boolean overwrite) throws MojoExecutionException { installTemplate(NAME_TEMPLATE, nameTemplate, overwrite); installTemplate(RUN_TEMPLATE, runTemplate, overwrite); if (getUpdateTemplate() != null) { installTemplate(UPDATE_TEMPLATE, getUpdateTemplate(), overwrite); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy