Broken binary files when using maven-resources-plugin

Today I’ve got a question from one of our developers. He was building a WAR file and then copied it from one location to another. When he tried to run the first file with Winstone everything worked fine. However when we tried to run the second file – he got an exception:

 [Winstone 2013/10/17 13:59:12] - Beginning extraction from war file
 [Winstone 2013/10/17 13:59:12] - Error initializing web application: prefix []
 java.util.zip.ZipException: invalid bit length repeat
 at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
 at java.io.FilterInputStream.read(FilterInputStream.java:107)
 at winstone.HostConfiguration.getWebRoot(HostConfiguration.java:262)
 at winstone.HostConfiguration.<init>(HostConfiguration.java:73)
 at winstone.HostGroup.initHost(HostGroup.java:85)
 at winstone.HostGroup.<init>(HostGroup.java:45)
 at winstone.Launcher.<init>(Launcher.java:196)
 at com.softteco.radioman.winstone.WinstoneServiceProvider.start(WinstoneServiceProvider.java:38)
 at com.softteco.radioman.Launcher.main(Launcher.java:38)

Okay, something is wrong about ZIP file structure. Running the same two files on my Linux host displayed pretty much the same results. So the problem seemed to be cross-platform. Binary comparison of the files showed that several bytes

andy@andy:~/Temp$ cmp ~/cryptcast.1.war ~/cryptcast.2.war 
/home/andy/cryptcast.1.war /home/andy/cryptcast.2.war differ: byte 11, line 2

So for some reason some bytes change during copy of the file. This was eye-opening. Finally we were able to formulate an adequate Google query to help us. The first link explained us what to do but didn’t really clarify why this happened. The part of our pom.xml was:

<execution>
  <id>copy-resources</id>
  <phase>validate</phase>
  <goals>
    <goal>copy-resources</goal>
  </goals>
  <configuration>
    <outputDirectory>./</outputDirectory>
    <resources>
      <resource>
        <directory>../services/target</directory>
        <!-- The issue vanishes if we remove the next line -->
        <filtering>true</filtering>
        <includes>
          <include>**/*.war</include>
        </includes>
      </resource>
    </resources>
  </configuration>
</execution>

So we removed the last line and things started to work. But why? So I’ve moved a bit deeper into investigations.

CopyResourcesMojo was not really interesting. ResourcesMojo was not particularly interested either, except for one call:

mavenResourcesFiltering.filterResources( mavenResourcesExecution );

Interesting, what are they filtering? Moving to another library and we see DefaultMavenResourcesFiltering. Interesting, some magics here:

this.defaultNonFilteredFileExtensions.add( "jpg" );
this.defaultNonFilteredFileExtensions.add( "jpeg" );
this.defaultNonFilteredFileExtensions.add( "gif" );
this.defaultNonFilteredFileExtensions.add( "bmp" );
this.defaultNonFilteredFileExtensions.add( "png" );

So filtering is simply skipped during copy for several types of files. And finally we come to DefaultMavenFileFilter which creates a list of processors and processing files during copy. As a result some symbols were replaced with the others which broke ZIP file structure.

The mystery is uncovered. So what to do? The following things look more reasonable for me:

  1. Use copy-maven-plugin
  2. Remove <filterable> or set it to false unless you really need it during copy.
  3. Exclude unwanted extension in the nonFilteredFileExtensions configuration tag
Advertisements
This entry was posted in Development and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s