* The executable. Can be a full path or the name of the executable. In the latter case, the executable must be in @@ -313,6 +320,18 @@ public class ExecMojo @Parameter( property = "exec.longModulepath", defaultValue = "true" ) private boolean longModulepath; + /** + * Forces the plugin to recognize the given executable as java executable. This helps with {@link #longClasspath} + * and {@link #longModulepath} parameters. + * + *
You shouldn't normally be needing this unless you renamed your java binary or are executing tools + * other than {@code java} which need modulepath or classpath parameters in a separate file.
+ * + * @since 3.1.1 + */ + @Parameter (property = "exec.forceJava", defaultValue = "false" ) + private boolean forceJava; + /** * If set to true the child process executes asynchronously and build execution continues in parallel. */ @@ -727,12 +746,35 @@ boolean isResultCodeAFailure( int result ) private boolean isLongClassPathArgument( String arg ) { - return longClasspath && ( "-classpath".equals( arg ) || "-cp".equals( arg ) ); + return isJavaExec() && longClasspath && ( "-classpath".equals( arg ) || "-cp".equals( arg ) ); } private boolean isLongModulePathArgument( String arg ) { - return longModulepath && ( "--module-path".equals( arg ) || "-p".equals( arg ) ); + return isJavaExec() && longModulepath && ( "--module-path".equals( arg ) || "-p".equals( arg ) ); + } + + /** + * Returns {@code true} when a java binary is being executed. + * + * @return {@code true} when a java binary is being executed. + */ + private boolean isJavaExec() + { + if ( forceJava ) + { + return true; + } + + if ( this.executable.contains( "%JAVA_HOME" ) + || this.executable.contains( "${JAVA_HOME}" ) + || this.executable.contains( "$JAVA_HOME" ) ) + { + // also applies to *most* other tools. + return true; + } + + return ENDS_WITH_JAVA.matcher( this.executable ).matches(); } /** diff --git a/src/test/java/org/codehaus/mojo/exec/ExecMojoTest.java b/src/test/java/org/codehaus/mojo/exec/ExecMojoTest.java index 66ec7c4d..2231c7db 100644 --- a/src/test/java/org/codehaus/mojo/exec/ExecMojoTest.java +++ b/src/test/java/org/codehaus/mojo/exec/ExecMojoTest.java @@ -1,7 +1,6 @@ package org.codehaus.mojo.exec; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static java.util.Collections.emptyMap; /* * Copyright 2005 The Codehaus. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this @@ -15,7 +14,7 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; -import java.io.PrintStream; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -28,18 +27,9 @@ import org.apache.commons.exec.Executor; import org.apache.commons.exec.OS; import org.apache.maven.execution.MavenSession; -import org.apache.maven.monitor.logging.DefaultLog; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.logging.SystemStreamLog; import org.apache.maven.plugin.testing.AbstractMojoTestCase; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuilder; -import org.apache.maven.project.ProjectBuildingRequest; -import org.codehaus.plexus.logging.Logger; -import org.codehaus.plexus.logging.console.ConsoleLogger; -import org.codehaus.plexus.util.StringOutputStream; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; /** * @author Jerome Lacoste @@ -129,145 +119,11 @@ public void testRunOK() * output ); } */ - /** + /* * integration test... - compile the Test class using mvn clean compile - run the test file using java, use it to * generate a file whose contains are compared to expected output */ - // public void testRunOKWithAutoComputedClasspath() - // throws MojoExecutionException, Exception - // { - // String projectName = "project1"; - // - // ExecMojo mojo = new ExecMojo(); - // - // setUpProject( projectName, mojo ); - // - // // compile project - // mojo.setExecutable( SOME_EXECUTABLE ); - // mojo.setWorkingDirectory( new File( "src/test/projects/" + projectName + "/" ) ); - // mojo.setArguments( Arrays.asList( new String[]{"clean", "compile"} ) ); - // - // mojo.execute(); - // - // mojo.getLog().info( "executed mvn clean compile" ); - // - // // the command executes the test class - // mojo.setExecutable( "java" ); - // mojo.setWorkingDirectory( (File) null ); - // Classpath classpath = new Classpath(); - // mojo.setArguments( Arrays.asList( new Object[]{"-Dproject.env1=value1", "-classpath", classpath, - // "org.codehaus.mojo.exec.test.Test", - // new File( "src/test/projects/" + projectName + "/target/exec/output.txt" ).getAbsolutePath(), "arg1", - // "arg2"} ) ); - // - // mojo.execute(); - // - // // checking the command line would involve resolving the repository - // // checkMojo( "java -cp" ); - // - // assertFileEquals( null, getTestFile( "src/test/projects/" + projectName + "/output.txt" ), - // getTestFile( "src/test/projects/" + projectName + "/target/exec/output.txt" ) ); - // - // // the command executes the test class, this time specifying the dependencies - // mojo.setExecutable( "java" ); - // mojo.setWorkingDirectory( (File) null ); - // classpath = new Classpath(); - // List dependencies = new ArrayList(); - // dependencies.add( "commons-io:commons-io" ); - // classpath.setDependencies( dependencies ); - // mojo.setArguments( Arrays.asList( new Object[]{"-Dproject.env1=value1", "-classpath", classpath, - // "org.codehaus.mojo.exec.test.Test", - // new File( "src/test/projects/" + projectName + "/target/exec/output.txt" ).getAbsolutePath(), "arg1", - // "arg2"} ) ); - // - // mojo.execute(); - // - // // checking the command line would involve resolving the repository - // // checkMojo( "java -cp" ); - // - // assertFileEquals( null, getTestFile( "src/test/projects/" + projectName + "/output.txt" ), - // getTestFile( "src/test/projects/" + projectName + "/target/exec/output.txt" ) ); - // } - - /** - * - * @param pom the pom file - * @param goal the goal to execute - * @return output from System.out during mojo execution - * @throws Exception if any exception occurs - */ - protected String execute( File pom, String goal ) - throws Exception - { - - ExecMojo mojo; - mojo = (ExecMojo) lookupMojo( goal, pom ); - - setUpProject( pom, mojo ); - - MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" ); - - // why isn't this set up by the harness based on the default-value? TODO get to bottom of this! - // setVariableValueToObject( mojo, "includeProjectDependencies", Boolean.TRUE ); - // setVariableValueToObject( mojo, "killAfter", new Long( -1 ) ); - - assertNotNull( mojo ); - assertNotNull( project ); - - // trap System.out - PrintStream out = System.out; - StringOutputStream stringOutputStream = new StringOutputStream(); - System.setOut( new PrintStream( stringOutputStream ) ); - // ensure we don't log unnecessary stuff which would interfere with assessing success of tests - mojo.setLog( new DefaultLog( new ConsoleLogger( Logger.LEVEL_ERROR, "exec:exec" ) ) ); - - try - { - mojo.execute(); - } - catch ( Throwable e ) - { - e.printStackTrace( System.err ); - fail( e.getMessage() ); - } - finally - { - System.setOut( out ); - } - - return stringOutputStream.toString(); - } - - private void setUpProject( File pomFile, ExecMojo mojo ) - throws Exception - { - super.setUp(); - - MockitoAnnotations.initMocks( this ); - - ProjectBuildingRequest buildingRequest = mock( ProjectBuildingRequest.class ); - when( session.getProjectBuildingRequest() ).thenReturn( buildingRequest ); - - ProjectBuilder builder = lookup( ProjectBuilder.class ); - - mojo.setBasedir( File.createTempFile( "mvn-temp", "txt" ).getParentFile() ); - - MavenProject project = builder.build( pomFile, buildingRequest ).getProject(); - - // this gets the classes for these tests of this mojo (exec plugin) onto the project classpath for the test - project.getBuild().setOutputDirectory( new File( "target/test-classes" ).getAbsolutePath() ); - - mojo.setProject( project ); - - mojo.setLog( new SystemStreamLog() - { - public boolean isDebugEnabled() - { - return true; - } - } ); - } // MEXEC-12, MEXEC-72 public void testGetExecutablePath() @@ -442,6 +298,24 @@ public void testParseCommandlineOSWin() assertEquals( javaHome, args[0] ); } + + public void test_exec_receives_all_parameters() throws MojoExecutionException + { + // given + ExecMojo execMojo = new ExecMojo(); + execMojo.setExecutable( "mkdir" ); + execMojo.setArguments( Arrays.asList( "-p", "dist/mails" ) ); + execMojo.setBasedir( new File("target") ); + + // when + final CommandLine commandLine = execMojo.getExecutablePath( emptyMap(), new File( "target" ) ); + execMojo.execute(); + + // then + assertTrue( "dir should have been created", + Paths.get( "target", "dist", "mails" ).toFile().exists() ); + } + private void checkMojo( String expectedCommandLine ) { assertEquals( 1, mojo.getAmountExecutedCommandLines() );