Search code examples
javamavenmaven-exec-plugin

Maven exec goal does not provide correct output


I am having a Maven project in Eclipse EE (jdk 1.8) and I'm using Maven on command line to build and execute the program, with the following command:

mvn clean install exec:exec

All the dependencies have been added to pom.xml file and I'm using Maven 3.6.3. Now, suppose my main method is as follows:

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
    
        System.out.print("Enter string: ");
        String str = input.nextLine();
    }
}

Now when I build and run this, it prompts to provide input before outputting "Enter string: ". Also after entering something to the console, it does not show up. Only when Enter key is hit, does the typed text show up followed by the "Enter string: ".

Output enter image description here

Now if the code is as follows:

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
    
        System.out.println("Enter string: ");
        String str = input.nextLine();
    }
}

It outputs "Enter string: " first followed by the prompt. However, here too, the typed text only appears after hitting Enter.

Output enter image description here

However, when the Maven build is done within Eclispe, the typed text is shown without any problem. But, the "input before print statement" exists.

I would like to get these issues resolved as I prefer Maven command line.

This is the configuration of maven-exec-plugin:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
        <executable>java</executable>
        <arguments>
            <argument>-classpath</argument>
            <classpath />
            <argument>package_name.Main</argument>
        </arguments>
    </configuration>
</plugin>

Solution

  • I think the answer here is also valid for this question. Why not just execute it with something like:

    java -classpath ./target/test-0.0.1-SNAPSHOT.jar com/Main
    

    after have packaged it with mvn package (above assumes your artifactId is test and your package name for the main class is com)

    Edit: As pointed out in the comments. Above also assumes, (if you have dependencies in you project as you say you have), the jar contains its dependencies by, for example, following maven shade plugin configuration in pom.xml:

      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.4</version>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>shade</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    

    Another way is to make the jar executable and execute it with java -jar ./target/test-0.0.1-SNAPSHOT.jar