Skip to content

How to fix: Why is Maven JAR Plugin writing *.jar contents into the *.pom file?

In a standard Maven build lifecycle, the maven-jar-plugin is responsible for packaging compiled .class files and resources into a .jar (Java Archive). Separately, Maven generates a .pom file which acts as the Project Object Model XML descriptor.

When you see binary data (often starting with the hex signature 50 4B 03 04 or the string PK - the ZIP file header) inside a file named your-artifact.pom, it indicates a collision in the build output stream. The Maven session has essentially been misconfigured to treat the POM’s destination path as the output target for the JAR binary. This results in an unreadable POM file, causing failures during the install or deploy phases because the repository manager cannot parse the XML metadata.

Cause Technical Description
Misconfigured <outputFile> Explicitly overriding the maven-jar-plugin output path to a string ending in .pom.
Shade Plugin Conflict The maven-shade-plugin with createDependencyReducedPom set to true, pointing to the same location as the JAR output.
Artifact Attachment Hijacking A custom plugin or maven-antrun-plugin task manually renaming the binary artifact to the POM filename.
Property Collision Using a property like ${project.build.finalName} in a way that forces the JAR to overwrite the POM descriptor during the package phase.

1. Audit the maven-jar-plugin Configuration

Section titled “1. Audit the maven-jar-plugin Configuration”

The most common cause is an accidental path override. Ensure you are not forcing the plugin to write to a .pom extension.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<!-- BAD: Forcing the output to a POM path -->
<!-- <outputDirectory>${project.build.directory}/classes</outputDirectory> -->
<!-- <finalName>${project.artifactId}.pom</finalName> -->
<!-- GOOD: Let Maven handle the extension -->
<classifier>bin</classifier>
</configuration>
</plugin>

If you are creating an “uber-jar,” the Shade plugin generates a dependency-reduced-pom.xml. If the dependencyReducedPomLocation is misconfigured, it can cause file system contention.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!-- Ensure this isn't pointing to your primary artifact path -->
<createDependencyReducedPom>true</createDependencyReducedPom>
<dependencyReducedPomLocation>
${project.build.directory}/dependency-reduced-pom.xml
</dependencyReducedPomLocation>
</configuration>
</execution>
</executions>
</plugin>

Hidden configurations in parent POMs or active profiles might be overriding your defaults. Run the following command to see the merged XML:

mvn help:effective-pom -Doutput=effective-pom.xml

Search the generated effective-pom.xml for any instances of <extension>pom</extension> inside a plugin configuration that handles binary packaging.

If you are using the maven-antrun-plugin to move files, ensure you aren’t overwriting the POM.

<!-- Example of what to avoid in antrun -->
<tasks>
<move file="${project.build.directory}/${project.build.finalName}.jar"
tofile="${project.build.directory}/${project.build.finalName}.pom" /> <!-- CRITICAL ERROR -->
</tasks>
  • Stick to Conventions: Avoid overriding ${project.build.directory} or ${project.build.finalName} unless absolutely necessary. Maven’s “Convention over Configuration” exists to prevent exactly this type of IO collision.
  • Use Classifiers: If you need to produce multiple JARs, use <classifier> (e.g., sources, javadoc, shaded) instead of changing the file extension or base name.
  • Validate Artifacts: Before running mvn deploy, always run mvn clean package and inspect the target folder.
  • Plugin Version Management: Use the <pluginManagement> section in your parent POM to lock plugin versions, preventing “rogue” behavior from older, buggy versions of packaging plugins.
  • Verify POM Integrity: Use cat target/*.pom | head -n 5 to ensure the file starts with <?xml version="1.0" ... and not binary garbage.