[GRADLE-2886] The war plugin in 1.7 now places WEB-INF ahead of META-INF, causing issues with OSGi containers Created: 12/Sep/13  Updated: 28/Oct/13  Resolved: 08/Oct/13

Status: Resolved
Project: Gradle
Affects Version/s: None
Fix Version/s: 1.9-rc-1

Type: Bug
Reporter: Gradle Forums Assignee: Benjamin Muschko
Resolution: Fixed Votes: 0

Attachments: Text File GRADLE-2886.patch     File GRADLE-2886.patch.v2     File GRADLE-2886.patch.v3     File GRADLE-2886.patch.v4    
Issue Links:
dependent by GRADLE-2926 Generation of application.xml broken ... Resolved


There was a change made to War.groovy in 1.7. In 1.6, the constructor had the following:
webInf = copyAction.rootSpec.addChild().into('WEB-INF')

In 1.7 this was changed to:
webInf = copyAction.rootSpec.addFirst().into('WEB-INF')

This now places the WEB-INF folder ahead of META-INF in the bundle. This breaks OSGi containers, which expect the META-INF and MANIFEST.MF to be the first 2 entries in the bundle.

Comment by Gradle Forums [ 12/Sep/13 ]

Are you sure? This sounds like a crazy assumption.

Comment by Gradle Forums [ 12/Sep/13 ]

Java's jar tool has always placed the manifest first, and most if not all frameworks expect this. OSGi bundles and war files are both extensions of jar files. Was there a reason the WEB-INF was placed first? I know of no requirement for this by any standard, framework, or container, so it should do no harm reverting this change.

Comment by Gradle Forums [ 12/Sep/13 ]

BTW the java.util.jar.JarInputStream and JarOutputStream classes also expect this.

Comment by Gradle Forums [ 12/Sep/13 ]

I don't know why the change was made, but it's likely there was some reason. That said, if it's wrong, it needs to be fixed.

Comment by Gradle Forums [ 12/Sep/13 ]

I noticed that this was not fixed in 1.8 RC1. Are there any plans to address this?

Comment by Gradle Forums [ 12/Sep/13 ]

Please consider this bug from the oracle java bug database.

JDK-5046178 : JarInputStream doesn't return Manifest object

The bug is not going to be fixed, so gradles behavior WILL cause trouble. I was already hit by it.

Comment by Gradle Forums [ 12/Sep/13 ]

Why do you think that this issue isn't going to be fixed? Also, the issue only seems to apply to indexed Jar files. Are you creating such an index yourself? Unless I'm missing something, Gradle has no built-in support for creating a Jar index.

Comment by Gradle Forums [ 12/Sep/13 ]

I think he was just wondering, if it's going to be fixed.

But why do you think that this is just an issue with indexed jars? JarInputStream fails to read the manifest file from a war that was created with gradle. It doesn't matter if it is indexed or not. And who knows in which java tools or apps JarInputStream is used...

BTW: I hate it to argue for this issue. Why on earth is this fact not part of the jar spec? If it is a requirement for a jar that the manifest is the first file of a jar it should be in the spec.

But still, I think gradle should try to simulate the official jar tool as good as possible. And the jar tool enforces that the manifest file is the first file.

Comment by Gradle Forums [ 12/Sep/13 ]

> But why do you think that this is just an issue with indexed jars?

I misinterpreted the issue description. Turns out that creating an indexed Jar is sufficient but not necessary for this problem to occur.

Comment by Gradle Forums [ 12/Sep/13 ]

Yes, any war file created by Gradle 1.7 (and later at this point) will not produce jars consistent with the jar tool in the JDK. Did you ever discover why the change was made in 1.7? It was a very small change that is easily reverted, but with large consequences. If you are producing war files not consistent with the jar tool, it seems like there should be a good reason for it.

Comment by Bryan [ 16/Sep/13 ]

Attached is a patch that reverts a change made in Gradle 1.7. This patch will retain the order of the META-INF when generating war and ear files.

Comment by Bryan [ 16/Sep/13 ]

I forgot to mention, the patch is against 1.8-rc-1.

Comment by Bryan [ 16/Sep/13 ]

I'll need to submit another patch as an ear plugin test is failing. I'll do that a bit later today.

Comment by Bryan [ 16/Sep/13 ]

New patch. This patch updates one ear plugin integration test also. The patch reverts to Gradle 1.6 behavior.

I discovered why this change was made, and it is related to GRADLE-2171. The change was by Kyle Mahan (kyle.mahan@gmail.com). Files were placed first ahead of the META-INF in order to preserve precedence of "WEB-INF" and "lib" when duplicatesStrategy is set to "exclude". This bug is really a regression introduced by changes made for GRADLE-2171.

By reverting to Gradle 1.6, files added with the "into" closure will take precedence when resolving duplicate conflicts. I modified the EarPluginIntegrationTest to reflect this expectation.

Comment by Bryan [ 16/Sep/13 ]

Patch v3. I similarly altered the WarTaskIntegrationTest. I also added a check to EarPluginIntegrationTest and WarTaskIntegrationTest to ensure the manifest is placed as JarInputStream expects (first, or second after META-INF).

Comment by Bryan [ 16/Sep/13 ]

Patch v4. Added check for manifest placement to JarIntegrationTest.

Comment by Bryan [ 17/Sep/13 ]

FYI, these patches are obsolete, I generated a pull request on GitHub.

Comment by Bryan [ 28/Oct/13 ]

I tested 1.9-rc-2 in my environment and this appears to be fixed.

Generated at Wed Jun 30 12:34:06 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.