dev@glassfish.java.net

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

From: Hong Zhang <hong.hz.zhang_at_oracle.com>
Date: Thu, 02 Sep 2010 10:01:05 -0400

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