dev@glassfish.java.net

Re: Maven-built deployment plans confuse DeploymentPlanArchive and break asadmin deploy --deploymentplan.

From: Owen Jacobson <owen.jacobson_at_grimoire.ca>
Date: Thu, 2 Sep 2010 21:58:04 -0400

Hi again.

I explored a couple of alternatives for addressing this, without reaching a satisfying solution. Attached are two patches to deployment/common (against the 3.0.1-b22 tag).

deployment-plan-archive-ignores-meta-inf.patch is probably the better of the two alternatives: the patch causes DeploymentPlanArchive.entries() to skip the deployment plan JAR's META-INF dir entirely, which prevents any files there from being copied to the deployed application. This is a very simple solution, and it appears to work well with the simple cases, but I'd worry about people relying on deployment plans to place important runtime configuration in their application (SPI services/ entries, extra Spring XML files, config files, &c) having their use cases broken.

deployment-plan-archive-includes-meta-inf.patch takes the opposite approach: it avoids path-mangling any entries that are already in META-INF, and tries to return entries without de-mangling them first. This has its own worrying side effects: in the case of signed JARs, the deployment plan's signing data will be copied into the app, potentially overwriting any signing data that went with the original application; similarly, with Maven metadata, both my application's own Maven metadata and the deployment plan's Maven metadata end up in the application.

While I was fiddling with this, I may have uncovered another bug... Is account.war.sun-web.xml in the deployment plan supposed to be copied into account_war/WEB-INF/sun-web.xml ? Because it's not, and as far as I can tell my container adjustments are not being applied to any of my nested web applications inside my EAR - only to the EAR itself.

-o




On 2010-09-02, at 10:01 AM, Hong Zhang wrote:

> Hi, Owen
> Thanks for sharing your experience with us on this (with detailed information on how to reproduce, and how to workaround etc)!
> Yes, this code need to be more robust in dealing with unexpected files from META-INF. I have filed issue
> https://glassfish.dev.java.net/issues/show_bug.cgi?id=13235
> to track the problem. We will get it fixed!
> Thanks,
>
> - Hong Owen Jacobson wrote:
>> (I mistakenly sent this to dev_at_glassfish.org <mailto:dev_at_glassfish.org> first -- apologies if this comes through twice.)
>>
>> Hi there,
>>
>> I just solved something that's been blocking me for a couple of days, and I thought you guys might appreciate knowing about it. First, a reproduction case:
>>
>> 1. Build a deployment plan archive (per http://docs.sun.com/app/docs/doc/820-7693/gijyb?l=en&a=view <http://docs.sun.com/app/docs/doc/820-7693/gijyb?l=en&a=view>) with Maven. The following POM will do:
>>
>> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
>> <modelVersion>4.0.0</modelVersion>
>>
>> <groupId>com.example.glassfish</groupId>
>> <artifactId>deployment-plan</artifactId>
>> <version>1.0-SNAPSHOT</version>
>> </project>
>>
>> 2. Note the contents of the deployment plan. In my case:
>>
>> $ jar tf test-environment-1.0-SNAPSHOT.jar META-INF/
>> META-INF/MANIFEST.MF
>> account.war.sun-web.xml
>> root.war.sun-web.xml
>> sun-application.xml
>> META-INF/maven/
>> META-INF/maven/ca.grimoire/
>> META-INF/maven/ca.grimoire/test-environment/
>> META-INF/maven/ca.grimoire/test-environment/pom.xml
>> META-INF/maven/ca.grimoire/test-environment/pom.properties
>>
>> 3. Try to deploy an application with this deployment plan.
>>
>> Under Glassfish 3.0.1, the deploy command fails with
>>
>> $ bin/asadmin deploy \
>> --deploymentplan test-environment-1.0-SNAPSHOT.jar \
>> ~/Development/grimoire/grimoire/target/grimoire-1.0-SNAPSHOT.ear
>> com.sun.enterprise.admin.cli.CommandException: remote failure: Exception while deploying the app : java.lang.NullPointerException
>>
>> and in the logs, the following stack trace:
>>
>> [#|2010-08-30T19:58:30.661-0400|SEVERE|glassfish3.0.1|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=21;_ThreadName=Thread-1;|Exception while deploying the app
>> java.lang.NullPointerException
>> at com.sun.enterprise.util.shared.ArchivistUtils.copyWithoutClose(ArchivistUtils.java:58)
>> at com.sun.enterprise.deployment.archivist.Archivist.copyJarElements(Archivist.java:1469)
>> at com.sun.enterprise.deployment.archivist.Archivist.copyInto(Archivist.java:1670)
>>
>> I've reproduced the Archivist.copyJarElements here, with annotations:
>>
>> protected void copyJarElements(ReadableArchive in, WritableArchive out, Vector ignoreList)
>> throws IOException {
>>
>> /* entries is generated *by in* -oj */
>> Enumeration entries = in.entries();
>> /* ... */
>> if (entries != null) {
>> for (; entries.hasMoreElements();) {
>> String anEntry = (String) entries.nextElement();
>> if (ignoreList == null || !ignoreList.contains(anEntry)) {
>> InputStream is = in.getEntry(anEntry);
>> OutputStream os = out.putNextEntry(anEntry);
>> /* Oops! 'is' is null here, so copyWithoutClose NPEs out. -oj */
>> ArchivistUtils.copyWithoutClose(is, os);
>> is.close();
>> out.closeEntry();
>> }
>> }
>> }
>> }
>>
>> Digging around a bit lead me to com.sun.enterprise.deployment.deploy.shared.DeploymentPlanArchive, the ReadableArchive implementation that handles deployment plans. The entries() and getEntry() methods contain some medium-hairy code designed to munge paths like foo.jar.sun-ejb.xml, and designed specifically to ignore META-INF/MANIFEST.MF. However, Maven's extra archive metadata confuses it in such a way that entries() includes Entry objects for pom.xml and pom.properties, but getEntry() will return null for those entries.
>>
>> I think this is a bug, but I don't know what the right fix is. It's easy to work around, though: telling maven not to include Maven descriptors in the resulting JAR is simple:
>>
>> <plugin>
>> <artifactId>maven-jar-plugin</artifactId>
>>
>> <configuration>
>> <archive>
>> <addMavenDescriptor>false</addMavenDescriptor>
>> </archive>
>> </configuration>
>> </plugin>
>>
>> and, absent those two files (and their containing directories), asadmin deploy is quite happy.
>>
>> Maybe getEntries() should ignore unexpected files in META-INF? I suspect something like this will happen if you sign your deployment plan, too.
>>
>> -o
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>