Class ExecJavaMojo

  • All Implemented Interfaces:
    org.apache.maven.plugin.ContextEnabled, org.apache.maven.plugin.Mojo

    @Mojo(name="java",
          threadSafe=true,
          requiresDependencyResolution=TEST)
    public class ExecJavaMojo
    extends AbstractExecMojo
    Executes the supplied java class in the current VM with the enclosing project's dependencies as classpath.
    Since:
    1.0
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      (package private) class  ExecJavaMojo.IsolatedThreadGroup
      a ThreadGroup to isolate execution and collect exceptions.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.util.List<java.lang.String> additionalClasspathElements
      Additional elements to be appended to the classpath.
      private java.lang.String[] arguments
      The class arguments.
      private boolean blockSystemExit
      Whether to try and prohibit the called Java program from terminating the JVM (and with it the whole Maven build) by calling System.exit(int).
      private java.util.List<java.lang.String> classpathFilenameExclusions
      List of file to exclude from the classpath.
      private boolean cleanupDaemonThreads
      Whether to interrupt/join and possibly stop the daemon threads upon quitting.
      private org.codehaus.plexus.PlexusContainer container  
      private long daemonThreadJoinTimeout
      This defines the number of milliseconds to wait for daemon threads to quit following their interruption.
      This is only taken into account if cleanupDaemonThreads is true.
      private boolean includePluginDependencies
      Indicates if this plugin's dependencies should be used when executing the main class.
      private boolean includeProjectDependencies
      Indicates if the project dependencies should be used when executing the main class.
      private boolean keepAlive
      Deprecated.
      since 1.1-alpha-1
      private java.lang.String mainClass
      The main class to execute.
      With Java 9 and above you can prefix it with the modulename, e.g.
      private java.util.Properties originalSystemProperties  
      private int preloadCommonPool
      Forces the creation of fork join common pool to avoids the threads to be owned by the isolated thread group and prevent a proper shutdown.
      private org.eclipse.aether.RepositorySystem repositorySystem  
      private boolean stopUnresponsiveDaemonThreads
      Wether to call Thread.stop() following a timing out of waiting for an interrupted thread to finish.
      private AbstractProperty[] systemProperties
      A list of system properties to be passed.
      private static java.lang.String THREAD_STOP_UNAVAILABLE  
      • Fields inherited from interface org.apache.maven.plugin.Mojo

        ROLE
    • Constructor Summary

      Constructors 
      Constructor Description
      ExecJavaMojo()  
    • Field Detail

      • THREAD_STOP_UNAVAILABLE

        private static final java.lang.String THREAD_STOP_UNAVAILABLE
        See Also:
        Constant Field Values
      • repositorySystem

        @Component
        private org.eclipse.aether.RepositorySystem repositorySystem
      • mainClass

        @Parameter(required=true,
                   property="exec.mainClass")
        private java.lang.String mainClass
        The main class to execute.
        With Java 9 and above you can prefix it with the modulename, e.g. com.greetings/com.greetings.Main Without modulename the classpath will be used, with modulename a new modulelayer will be created.

        Note that you can also provide a Runnable fully qualified name. The runnable can get constructor injections either by type if you have maven in your classpath (can be provided) or by name (ensure to enable -parameters Java compiler option) for loose coupling. Current support loose injections are:

        • systemProperties: Properties, session system properties
        • systemPropertiesUpdater: BiConsumer<String, String>, session system properties update callback (pass the key/value to update, null value means removal of the key)
        • userProperties: Properties, session user properties
        • userPropertiesUpdater: BiConsumer<String, String>, session user properties update callback (pass the key/value to update, null value means removal of the key)
        • projectProperties: Properties, project properties
        • projectPropertiesUpdater: BiConsumer<String, String>, project properties update callback (pass the key/value to update, null value means removal of the key)
        • highestVersionResolver: Function<String, String>, passing a groupId:artifactId you get the latest resolved version from the project repositories
        Since:
        1.0
      • preloadCommonPool

        @Parameter(property="exec.preloadCommonPool",
                   defaultValue="0")
        private int preloadCommonPool
        Forces the creation of fork join common pool to avoids the threads to be owned by the isolated thread group and prevent a proper shutdown. If set to zero the default parallelism is used to precreate all threads, if negative it is ignored else the value is the one used to create the fork join threads.
        Since:
        3.0.1
      • arguments

        @Parameter(property="exec.arguments")
        private java.lang.String[] arguments
        The class arguments.
        Since:
        1.0
      • systemProperties

        @Parameter
        private AbstractProperty[] systemProperties
        A list of system properties to be passed. Note: as the execution is not forked, some system properties required by the JVM cannot be passed here. Use MAVEN_OPTS or the exec:exec instead. See the user guide for more information.
        Since:
        1.0
      • keepAlive

        @Parameter(property="exec.keepAlive",
                   defaultValue="false")
        @Deprecated
        private boolean keepAlive
        Deprecated.
        since 1.1-alpha-1
        Indicates if mojo should be kept running after the mainclass terminates. Use full for server like apps with daemon threads.
        Since:
        1.0
      • includeProjectDependencies

        @Parameter(property="exec.includeProjectDependencies",
                   defaultValue="true")
        private boolean includeProjectDependencies
        Indicates if the project dependencies should be used when executing the main class.
        Since:
        1.1-beta-1
      • includePluginDependencies

        @Parameter(property="exec.includePluginsDependencies",
                   defaultValue="false")
        private boolean includePluginDependencies
        Indicates if this plugin's dependencies should be used when executing the main class.

        This is useful when project dependencies are not appropriate. Using only the plugin dependencies can be particularly useful when the project is not a java project. For example a mvn project using the csharp plugins only expects to see dotnet libraries as dependencies.

        Since:
        1.1-beta-1
      • cleanupDaemonThreads

        @Parameter(property="exec.cleanupDaemonThreads",
                   defaultValue="true")
        private boolean cleanupDaemonThreads
        Whether to interrupt/join and possibly stop the daemon threads upon quitting.
        If this is false, maven does nothing about the daemon threads. When maven has no more work to do, the VM will normally terminate any remaining daemon threads.

        In certain cases (in particular if maven is embedded), you might need to keep this enabled to make sure threads are properly cleaned up to ensure they don't interfere with subsequent activity. In that case, see daemonThreadJoinTimeout and stopUnresponsiveDaemonThreads for further tuning.

        Since:
        1.1-beta-1
      • daemonThreadJoinTimeout

        @Parameter(property="exec.daemonThreadJoinTimeout",
                   defaultValue="15000")
        private long daemonThreadJoinTimeout
        This defines the number of milliseconds to wait for daemon threads to quit following their interruption.
        This is only taken into account if cleanupDaemonThreads is true. A value <=0 means to not timeout (i.e. wait indefinitely for threads to finish). Following a timeout, a warning will be logged.

        Note: properly coded threads should terminate upon interruption but some threads may prove problematic: as the VM does interrupt daemon threads, some code may not have been written to handle interruption properly. For example java.util.Timer is known to not handle interruptions in JDK <= 1.6. So it is not possible for us to infinitely wait by default otherwise maven could hang. A sensible default value has been chosen, but this default value may change in the future based on user feedback.

        Since:
        1.1-beta-1
      • stopUnresponsiveDaemonThreads

        @Parameter(property="exec.stopUnresponsiveDaemonThreads",
                   defaultValue="false")
        private boolean stopUnresponsiveDaemonThreads
        Wether to call Thread.stop() following a timing out of waiting for an interrupted thread to finish. This is only taken into account if cleanupDaemonThreads is true and the daemonThreadJoinTimeout threshold has been reached for an uncooperative thread. If this is false, or if Thread.stop() fails to get the thread to stop, then a warning is logged and Maven will continue on while the affected threads (and related objects in memory) linger on. Consider setting this to true if you are invoking problematic code that you can't fix. An example is Timer which doesn't respond to interruption. To have Timer fixed, vote for this bug.

        Note: In JDK 20+, the long deprecated Thread.stop() (since JDK 1.2) has been removed and will throw an UnsupportedOperationException. This will be handled gracefully, yielding a log warning "Thread.stop() is unavailable in this JRE version, cannot force-stop any threads" once and not trying to stop any further threads during the same execution.

        Since:
        1.1-beta-1
      • originalSystemProperties

        private java.util.Properties originalSystemProperties
      • additionalClasspathElements

        @Parameter
        private java.util.List<java.lang.String> additionalClasspathElements
        Additional elements to be appended to the classpath.
        Since:
        1.3
      • classpathFilenameExclusions

        @Parameter
        private java.util.List<java.lang.String> classpathFilenameExclusions
        List of file to exclude from the classpath. It matches the jar name, for example slf4j-simple-1.7.30.jar.
        Since:
        3.0.1
      • blockSystemExit

        @Parameter(property="exec.blockSystemExit",
                   defaultValue="false")
        private boolean blockSystemExit
        Whether to try and prohibit the called Java program from terminating the JVM (and with it the whole Maven build) by calling System.exit(int). When active, loaded classes will replace this call by a custom callback. In case of an exit code 0 (OK), it will simply log the fact that System.exit(int) was called. Otherwise, it will throw a SystemExitException, failing the Maven goal as if the called Java code itself had exited with an exception. This way, the error is propagated without terminating the whole Maven JVM. In previous versions, users had to use the exec instead of the java goal in such cases, which now with this option is no longer necessary.
        Since:
        3.2.0
      • container

        @Component
        private org.codehaus.plexus.PlexusContainer container
    • Constructor Detail

      • ExecJavaMojo

        public ExecJavaMojo()
    • Method Detail

      • execute

        public void execute()
                     throws org.apache.maven.plugin.MojoExecutionException,
                            org.apache.maven.plugin.MojoFailureException
        Execute goal.
        Throws:
        org.apache.maven.plugin.MojoExecutionException - execution of the main class or one of the threads it generated failed.
        org.apache.maven.plugin.MojoFailureException - something bad happened...
      • doExec

        private void doExec​(java.lang.String bootClassName)
                     throws java.lang.Throwable
        Throws:
        java.lang.Throwable
      • doMain

        private void doMain​(java.lang.invoke.MethodHandle mainHandle)
                     throws java.lang.Throwable
        Throws:
        java.lang.Throwable
      • doRun

        private void doRun​(java.lang.Class<?> bootClass)
                    throws java.lang.InstantiationException,
                           java.lang.IllegalAccessException,
                           java.lang.reflect.InvocationTargetException,
                           java.lang.NoSuchMethodException
        Throws:
        java.lang.InstantiationException
        java.lang.IllegalAccessException
        java.lang.reflect.InvocationTargetException
        java.lang.NoSuchMethodException
      • lookupParam

        private java.lang.Object lookupParam​(java.lang.reflect.Parameter param)
                                      throws org.codehaus.plexus.component.repository.exception.ComponentLookupException
        Throws:
        org.codehaus.plexus.component.repository.exception.ComponentLookupException
      • lookup

        private java.lang.Object lookup​(java.lang.reflect.Parameter param,
                                        java.lang.String name)
                                 throws org.codehaus.plexus.component.repository.exception.ComponentLookupException
        Throws:
        org.codehaus.plexus.component.repository.exception.ComponentLookupException
      • resolveVersion

        private java.util.function.Function<java.lang.String,​java.lang.String> resolveVersion​(java.util.function.Function<org.eclipse.aether.resolution.VersionRangeResult,​java.lang.Object> fn)
      • propertiesUpdater

        private java.util.function.BiConsumer<java.lang.String,​java.lang.String> propertiesUpdater​(java.util.Properties props)
      • preloadCommonPool

        private void preloadCommonPool()
        To avoid the exec:java to consider common pool threads leaked, let's pre-create them.
      • joinNonDaemonThreads

        private void joinNonDaemonThreads​(java.lang.ThreadGroup threadGroup)
      • joinThread

        private void joinThread​(java.lang.Thread thread,
                                long timeoutMsecs)
      • terminateThreads

        private void terminateThreads​(java.lang.ThreadGroup threadGroup)
      • getActiveThreads

        private java.util.Collection<java.lang.Thread> getActiveThreads​(java.lang.ThreadGroup threadGroup)
      • setSystemProperties

        private void setSystemProperties()
        Pass any given system properties to the java system properties.
      • getClassLoader

        private java.net.URLClassLoader getClassLoader()
                                                throws org.apache.maven.plugin.MojoExecutionException
        Set up a classloader for the execution of the main class.
        Returns:
        the classloader
        Throws:
        org.apache.maven.plugin.MojoExecutionException - if a problem happens
      • addAdditionalClasspathElements

        private void addAdditionalClasspathElements​(java.util.List<java.nio.file.Path> path)
      • addRelevantPluginDependenciesToClasspath

        private void addRelevantPluginDependenciesToClasspath​(java.util.List<java.nio.file.Path> path)
                                                       throws org.apache.maven.plugin.MojoExecutionException
        Add any relevant project dependencies to the classpath. Indirectly takes includePluginDependencies and ExecutableDependency into consideration.
        Parameters:
        path - classpath of URL objects
        Throws:
        org.apache.maven.plugin.MojoExecutionException - if a problem happens
      • addRelevantProjectDependenciesToClasspath

        private void addRelevantProjectDependenciesToClasspath​(java.util.List<java.nio.file.Path> path)
        Add any relevant project dependencies to the classpath. Takes includeProjectDependencies into consideration.
        Parameters:
        path - classpath of URL objects
      • determineRelevantPluginDependencies

        private java.util.Set<org.apache.maven.artifact.Artifact> determineRelevantPluginDependencies()
                                                                                               throws org.apache.maven.plugin.MojoExecutionException
        Determine all plugin dependencies relevant to the executable. Takes includePlugins, and the executableDependency into consideration.
        Returns:
        a set of Artifact objects. (Empty set is returned if there are no relevant plugin dependencies.)
        Throws:
        org.apache.maven.plugin.MojoExecutionException - if a problem happens resolving the plufin dependencies
      • resolveExecutableDependencies

        private java.util.Set<org.apache.maven.artifact.Artifact> resolveExecutableDependencies​(org.apache.maven.artifact.Artifact executableArtifact)
                                                                                         throws org.apache.maven.plugin.MojoExecutionException
        Resolve the executable dependencies for the specified project
        Parameters:
        executableArtifact - the executable plugin dependency
        Returns:
        a set of Artifacts
        Throws:
        org.apache.maven.plugin.MojoExecutionException - if a failure happens
      • waitFor

        private void waitFor​(long millis)
        Stop program execution for nn millis.
        Parameters:
        millis - the number of millis-seconds to wait for, 0 stops program forever.