19

My maven project intentionally only needs src/test/java and src/test/resources. After removing src/main/* folders, the expected warning showed up upon mvn verify:

[WARNING] JAR will be empty - no content was marked for inclusion!
[INFO] Building jar: D:\dev\java\my-project\target\my-project-0.0.1-SNAPSHOT.jar

How to suppress this warning apart from having a class with an empty main() method in src/main/java?

EDIT:

As -q suppresses the warning, a followup would be if this can be done programmatically in the pom.xml?

k_rollo
  • 5,304
  • 16
  • 63
  • 95
  • This post helps you to change the LOG level of your Maven: [https://stackoverflow.com/questions/4782089/how-to-change-maven-logging-level-to-display-only-warning-and-errors](https://stackoverflow.com/questions/4782089/how-to-change-maven-logging-level-to-display-only-warning-and-errors) – zappee Jul 28 '18 at 11:01
  • 1
    Possible duplicate of [How to change maven logging level to display only warning and errors?](https://stackoverflow.com/questions/4782089/how-to-change-maven-logging-level-to-display-only-warning-and-errors) – zappee Jul 28 '18 at 11:02
  • @zappee Any way to do this programmatically in `pom.xml`? – k_rollo Jul 28 '18 at 11:25
  • Is this project used as a test-jar only? Or as a test dependency ? Apart from that this has nothing to do with an empty main method... – khmarbaise Jul 28 '18 at 12:03
  • If you simply move the code to `src/main/java`and `src/main/resources` and change the scope for this to `test` where you use it that will solve all the problems. This results in no supplemental configuration in pom file... – khmarbaise Jul 30 '18 at 05:17
  • Thanks for the tip, this is a test framework and it would be best to honor the maven directory structure as intended. – k_rollo Jul 30 '18 at 05:21
  • @silver you are exactly honoring the directory structure...? – khmarbaise Jul 30 '18 at 05:34
  • 1
    `src/main/*` pertains to application. `src/test/*` pertains to tests ([click](https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html)). – k_rollo Jul 30 '18 at 05:47

6 Answers6

12

This is (according to me) the cleanest solution
for projects that don't contain production code but do contain tests:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <skipIfEmpty>true</skipIfEmpty>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

It indicates what you want:

  • to skip trying to package "no production code" into a jar
  • don't try to install/deploy the non-existing jar

leaving test execution untouched.


Like @John Camerin mentioned it is NOT advised to use <packaging>pom</packaging>
unless the ONLY thing your pom should do is gather dependencies.
Otherwise, if you have tests, they would be skipped without warning, which is not what you want.

A shorter alternative

Some of these configuration parameters are tied to user properties:

  • maven-jar-plugin's skipIfEmpty parameter sadly is not linked to any user property
  • maven-install-plugin's skip parameter gets its value from maven.install.skip
  • maven-deploy-plugin's skip parameter gets its value from maven.deploy.skip

This means the pom could be shortened to

    <properties>
        <maven.install.skip>true</maven.install.skip>
        <maven.deploy.skip>true</maven.deploy.skip>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <skipIfEmpty>true</skipIfEmpty>
                </configuration>
            </plugin>
        </plugins>
    </build>
neXus
  • 2,005
  • 3
  • 29
  • 53
8

The warning is actually based on whether it can find the configured <classesDirectory> - by default target\classes.

This means one simple way to bypass the warning is to point it at another deliberately empty directory:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <classesDirectory>dummy</classesDirectory>
            </configuration>
        </plugin>
    </plugins>
</build>

Alternatively, to avoid the need for the empty directory, exclude everything from another directory:

        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <classesDirectory>src</classesDirectory>
                <excludes>
                    <exclude>**</exclude>
                </excludes>
            </configuration>
        </plugin>
df778899
  • 10,703
  • 1
  • 24
  • 36
  • I did not particularly use this solution but it gave me the idea of what I wanted to achieve. Upvoted and marked as answer. – k_rollo Jul 29 '18 at 06:10
  • 1
    As anything in SO, an answer with an explanation why is more useful. – k_rollo Jul 30 '18 at 04:38
  • 1
    Violate the convention over configuration paradigm in two ways: First change the default directory layout and using a configuration for maven-jar-plugin which is not the best... – khmarbaise Sep 01 '18 at 10:46
5

Both solutions suppressed the warning message programmatically.

Solution 1:

<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-jar-plugin -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.1.0</version>
    <!-- Ignore src/main in JAR packaging -->
    <configuration>
        <classesDirectory>src</classesDirectory>
        <excludes>
            <exclude>main</exclude>
        </excludes>
    </configuration>
</plugin>

Solution 2:

Since the above essentially created an empty JAR (and I did not really want to include test classes and test resources), I opted to "skip" the JAR creation instead.

What is the best way to avoid maven-jar?

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>default-jar</id>
            <phase>none</phase>
        </execution>
    </executions>
</plugin>
k_rollo
  • 5,304
  • 16
  • 63
  • 95
  • 1
    Is there really no simpler way to disable this in the POM? Consider a JAR whose only purpose is to pull in other dependencies. Would I really need to add path exclusions just to remove disable the warning? – Garret Wilson Oct 20 '18 at 16:34
  • You can try adding a class with an empty main() – k_rollo Oct 21 '18 at 03:24
  • 1
    If you disable `maven-jar-plugin` you will probably want to disable `maven-install-plugin`. Otherwise, `mvn install` will fail the build. – Gili Dec 15 '18 at 03:19
2

None of the other solutions seemed particularly attractive to me, so my solution was to add a file src/main/resources/dummy containing the explanation:

Dummy file to avoid empty jar warning from Maven.

At least this does not produce any noise in the pom.xml, and there cannot be any misunderstandings about the purpose of the file. It produces a jar with exactly that file, but this was no problem in my case.

Alex Krauss
  • 9,438
  • 4
  • 27
  • 31
0

If all you are trying to do is gather dependecies, you could add <packaging>pom</packaging> to change from the default jar packaging.

However, based on the context in your question, having src/test/java and src/test/resources folders leads me to believe you have a component that is just tests? Changing packaging to pom would stop the tests from being run from maven. If this is indeed your use case, it would seem that you are trying to skip the packaging. The best way to achieve that is to bind the plugin for the modules packaging to phase none, as there is no way to skip the package phase of the maven lifecycle. This is identified as Solution 1 above.

John Camerin
  • 677
  • 5
  • 15
-1

The simply and best solution is to keep the test code in src/main/java yes this is not a typo. Furthermore if it is a test framework the test framework must have tests itself so it makes sense to locate the tests for the productive code from the user point of view into src/main/java and the tests in src/test/java.

From the user point of view it will be simply jar file where you should define the <scope>test</scope>.

This will solve all the issues without any supplemental configuration and changing any default and no violation of conventions.

khmarbaise
  • 92,914
  • 28
  • 189
  • 235
  • Putting the code in `src/main` and setting dependencies to `test` in `pom.xml` resulted in unresolved imports in Eclipse? – k_rollo Sep 01 '18 at 13:57
  • The tests stop executing with `mvn verify` after they were moved to `src/main`. The cucumber-jvm framework uses a JUnit runner and thus kicks in when placed under `src/test`. – k_rollo Sep 01 '18 at 14:15