dlecan/play2-war-plugin — pull request #215 by kustra (2014-01-11 09:36:57+00:00)
Title: java.util.zip.ZipException when explodedJar := true on multiproject setup

The pull request fixes the following issue for Play 2.1.x:

> play war
[info] Loading project definition from D:\dev\myproject\project

This project uses Play 2.1.3!
Update the Play sbt-plugin version to 2.1.4 (usually in project/plugins.sbt)

[info] Loading project definition from D:\dev\myproject\modules\admin\project
[info] Loading project definition from D:\dev\myproject\modules\common\project
[info] Loading project definition from D:\dev\myproject\modules\web\project
[info] Set current project to myproject (in build file:/D:/dev/myproject/)
[info] Wrote D:\dev\myproject\modules\common\target\scala-2.10\common_2.10-2.2.pom
[info] Wrote D:\dev\myproject\modules\web\target\scala-2.10\web_2.10-2.2.pom
[info] Wrote D:\dev\myproject\modules\admin\target\scala-2.10\admin_2.10-2.2.pom
[info] Wrote D:\dev\myproject\target\scala-2.10\myproject_2.10-2.2.pom
[info] Build WAR package for servlet container: 2.5
[info] Packaging D:\dev\myproject\target\myproject-2.2.war ...
[info] Main artifacts 'common_2.10-2.2.jar web_2.10-2.2.jar admin_2.10-2.2.jar myproject_2.10-2.2.jar' will be packaged exploded
[info] WEB-INF/web.xml found.
java.util.zip.ZipException: duplicate entry: WEB-INF/classes/META-INF/MANIFEST.MF
at java.util.zip.ZipOutputStream.putNextEntry(Unknown Source)
at java.util.jar.JarOutputStream.putNextEntry(Unknown Source)
at sbt.IO$.addFileEntry$1(IO.scala:441)
at sbt.IO$$anonfun$sbt$IO$$writeZip$2.apply(IO.scala:450)
at sbt.IO$$anonfun$sbt$IO$$writeZip$2.apply(IO.scala:450)
at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:60)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)
at sbt.IO$.sbt$IO$$writeZip(IO.scala:450)
at sbt.IO$$anonfun$archive$1.apply(IO.scala:403)
at sbt.IO$$anonfun$archive$1.apply(IO.scala:401)
at sbt.IO$$anonfun$withZipOutput$1.apply(IO.scala:496)
at sbt.IO$$anonfun$withZipOutput$1.apply(IO.scala:482)
at sbt.Using.apply(Using.scala:25)
at sbt.IO$.withZipOutput(IO.scala:482)
at sbt.IO$.archive(IO.scala:401)
at sbt.IO$.jar(IO.scala:384)
at com.github.play2war.plugin.Play2WarCommands$$anonfun$1.apply(Play2WarCommands.scala:204)
at com.github.play2war.plugin.Play2WarCommands$$anonfun$1.apply(Play2WarCommands.scala:55)
at sbt.Scoped$$anonfun$hf14$1.apply(Structure.scala:590)
at sbt.Scoped$$anonfun$hf14$1.apply(Structure.scala:590)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:49)
at sbt.Scoped$Reduced$$anonfun$combine$1$$anonfun$apply$12.apply(Structure.scala:311)
at sbt.Scoped$Reduced$$anonfun$combine$1$$anonfun$apply$12.apply(Structure.scala:311)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:41)
at sbt.std.Transform$$anon$5.work(System.scala:71)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:232)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:232)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
at sbt.Execute.work(Execute.scala:238)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:232)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:232)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
[error] (myproject/*:war) java.util.zip.ZipException: duplicate entry: WEB-INF/classes/META-INF/MANIFEST.MF
[error] Total time: 19 s, completed 2014.01.11. 8:14:22

I checked the file list generated by the plugin that's passed to the IO.jar(...) call. It had 4 entries like this, one for each subproject and one for the parent:

(D:\dev\myproject\target\exploded\META-INF\MANIFEST.MF,WEB-INF/classes/META-INF\MANIFEST.MF)

Additionally, any files that are on the same classpath are duplicated in the file list, too. I understand that such files will not be accessible at runtime, but they can still be useful, e.g. an empty application.conf file should exist in all subprojects as various tools use its presence to recognize the project as a Play project.