You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2018/08/29 00:34:53 UTC

svn commit: r1839519 - in /jackrabbit/commons/filevault-package-maven-plugin/trunk: ./ src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ src/test/resources/test-project...

Author: tripod
Date: Wed Aug 29 00:34:53 2018
New Revision: 1839519

URL: http://svn.apache.org/viewvc?rev=1839519&view=rev
Log:
JCRVLT-272 analyze-classes mojo can fail with "Access denied" for multi-module projects (closes #10)

Added:
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/AnalyzeClassesMultiModuleIT.java
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/pom.xml
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/java/
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/java/some/
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/java/some/SomeClass.java
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/b/
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/b/pom.xml
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/pom.xml
Modified:
    jackrabbit/commons/filevault-package-maven-plugin/trunk/.ratignore
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportPackageBuilder.java
    jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java

Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/.ratignore
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/.ratignore?rev=1839519&r1=1839518&r2=1839519&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/.ratignore (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/.ratignore Wed Aug 29 00:34:53 2018
@@ -3,4 +3,6 @@ src/test/resources/test-projects/**/*.tx
 src/test/resources/test-projects/**/*.xml
 src/test/resources/test-projects/**/.vlt
 src/test/resources/test-projects/**/.vltignore
-src/test/resources/test-projects/**/.dummy
\ No newline at end of file
+src/test/resources/test-projects/**/.dummy
+src/test/resources/test-projects/**/*.lst
+src/test/resources/test-projects/**/*.MF
\ No newline at end of file

Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportPackageBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportPackageBuilder.java?rev=1839519&r1=1839518&r2=1839519&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportPackageBuilder.java (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ImportPackageBuilder.java Wed Aug 29 00:34:53 2018
@@ -17,14 +17,18 @@
 package org.apache.jackrabbit.filevault.maven.packaging.impl;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -35,6 +39,7 @@ import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DependencyResolutionRequiredException;
@@ -54,6 +59,9 @@ import aQute.bnd.osgi.Processor;
 import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;
 import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;
 
+import static org.apache.commons.io.FileUtils.listFiles;
+import static org.apache.commons.io.FilenameUtils.normalize;
+
 /**
  * The import package builder is used to analyze the classes and dependencies of the project and calculate the
  * import-package statement for this package.
@@ -474,8 +482,13 @@ public class ImportPackageBuilder {
 
         private BundleInfo(Artifact artifact) throws IOException {
             id = artifact.getId();
-            JarFile jar = new JarFile(artifact.getFile());
-            Manifest manifest = jar.getManifest();
+            File file = artifact.getFile();
+
+            // In case of an internal dependency in a multi-module project, the dependency may be represented by a directory
+            // rather than a JAR file if the maven lifecycle phase does not include binding the JAR file to the dependency.
+            Dependency dependency = file.isDirectory() ? new DirectoryDependency(file) : new JarBasedDependency(file);
+
+            Manifest manifest = dependency.getManifest();
             String exportPackages = manifest == null ? null : manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE);
             if (exportPackages != null) {
                 for (Map.Entry<String, Attrs> entry : new Parameters(exportPackages).entrySet()) {
@@ -484,7 +497,69 @@ public class ImportPackageBuilder {
                     packageVersions.put(entry.getKey(), version == null ? "" : version);
                 }
             } else {
-                // scan the jar and associate the version
+                // scan the class files and associate the version
+                for (String path : dependency.getClassFiles()) {
+                    // skip internal / impl
+                    if (path.contains("/impl/") || path.contains("/internal/")) {
+                        continue;
+                    }
+                    path = StringUtils.chomp(path, "/");
+                    if (path.charAt(0) == '/') {
+                        path = path.substring(1);
+                    }
+                    String packageName = path.replaceAll("/", ".");
+                    packageVersions.put(packageName, "");
+                }
+            }
+        }
+
+        public String getId() {
+            return id;
+        }
+    }
+
+    private interface Dependency {
+
+        /**
+         * Returns the Manifest of the dependency.
+         * @return the Manifest.
+         */
+        @Nullable
+        Manifest getManifest() throws IOException;
+
+        /**
+         * Returns the paths representing .class files in their java package directory with *nix-style path separators,
+         * e.g. {@code /some/package/name/ClassFile.class}.
+         * @return the paths.
+         */
+        @Nonnull
+        Collection<String> getClassFiles() throws IOException;
+    }
+
+    /**
+     * Represents the JAR file of an {@link Artifact} dependency.
+     */
+    private static class JarBasedDependency implements Dependency {
+
+        private final File file;
+
+        private JarBasedDependency(File file) {
+            this.file = file;
+        }
+
+        @Override
+        @Nullable
+        public Manifest getManifest() throws IOException {
+            try (JarFile jarFile = new JarFile(this.file)) {
+                return jarFile.getManifest();
+            }
+        }
+
+        @Override
+        @Nonnull
+        public Collection<String> getClassFiles() throws IOException {
+            List<String> fileNames = new LinkedList<>();
+            try (JarFile jar = new JarFile(this.file)) {
                 Enumeration<JarEntry> entries = jar.entries();
                 while (entries.hasMoreElements()) {
                     JarEntry e = entries.nextElement();
@@ -493,24 +568,53 @@ public class ImportPackageBuilder {
                     }
                     String path = e.getName();
                     if (path.endsWith(".class")) {
-                        // skip internal / impl
-                        if (path.contains("/impl/") || path.contains("/internal/")) {
-                            continue;
-                        }
-                        path = StringUtils.chomp(path, "/");
-                        if (path.charAt(0) == '/') {
-                            path = path.substring(1);
-                        }
-                        String packageName = path.replaceAll("/", ".");
-                        packageVersions.put(packageName, "");
+                        fileNames.add(path);
                     }
                 }
             }
-            jar.close();
+
+            return fileNames;
         }
+    }
 
-        public String getId() {
-            return id;
+    /**
+     * Represents an {@link Artifact} dependency to another module of a multi-module setup
+     * which may point to the target/classes directory of the module rather than a jar file.
+     */
+    private static class DirectoryDependency implements Dependency {
+
+        private final File directory;
+
+        private DirectoryDependency(File directory) {
+            this.directory = directory;
+        }
+
+        @Override
+        @Nullable
+        public Manifest getManifest() throws IOException {
+            File manifest = new File(this.directory, "META-INF/MANIFEST.MF");
+            if (!manifest.exists()) {
+                return null;
+            }
+            try (InputStream in = new FileInputStream(manifest)) {
+                return new Manifest(in);
+            }
+        }
+
+        @Override
+        @Nonnull
+        public Collection<String> getClassFiles() throws IOException {
+            Collection<File> files = listFiles(this.directory, new String[]{"class"}, true);
+            String basePath = this.directory.getCanonicalPath();
+            Collection<String> fileNames = new ArrayList<>(files.size());
+            for (File file : files) {
+                // Use the relative file path as the the path segments will be used
+                // to calculate the package name.
+                String relativePath = file.getCanonicalPath().substring(basePath.length());
+                // The path may contain platform-specific paths that must be normalized to unix paths.
+                fileNames.add(normalize(relativePath, true));
+            }
+            return fileNames;
         }
     }
 

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/AnalyzeClassesMultiModuleIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/AnalyzeClassesMultiModuleIT.java?rev=1839519&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/AnalyzeClassesMultiModuleIT.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/AnalyzeClassesMultiModuleIT.java Wed Aug 29 00:34:53 2018
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.filevault.maven.packaging.it;
+
+import org.junit.Test;
+
+public class AnalyzeClassesMultiModuleIT {
+
+    /**
+     * Tests that the analyze classes module succeeds when run on
+     * inter-module dependencies in a multi-module setup.
+     */
+    @Test
+    public void multi_module_build_succeeds() throws Exception {
+        new ProjectBuilder()
+                .setTestProjectDir("/analyze-classes-multimodule")
+                .setTestGoals("clean", "test")
+                .setVerifyPackageContents(false)
+                .build();
+    }
+}

Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java?rev=1839519&r1=1839518&r2=1839519&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/ProjectBuilder.java Wed Aug 29 00:34:53 2018
@@ -98,6 +98,8 @@ public class ProjectBuilder {
 
     private boolean buildExpectedToFail;
 
+    private boolean verifyPackageContents = true;
+
     public ProjectBuilder() {
         testProjectsRoot = new File(TEST_PROJECTS_ROOT);
         testProperties = new Properties();
@@ -179,6 +181,11 @@ public class ProjectBuilder {
         return this;
     }
 
+    public ProjectBuilder setVerifyPackageContents(boolean verifyPackageContents) {
+        this.verifyPackageContents = verifyPackageContents;
+        return this;
+    }
+
     public ProjectBuilder setProperty(String name, String value) {
         testProperties.put(name, value);
         return this;
@@ -202,6 +209,10 @@ public class ProjectBuilder {
             verifier.resetStreams();
         }
 
+        if (!verifyPackageContents) {
+            return this;
+        }
+
         assertTrue("Project generates package file", testPackageFile.exists());
 
         // read zip
@@ -266,7 +277,7 @@ public class ProjectBuilder {
         }
         Collections.sort(entries);
         result = StringUtils.join(entries.iterator(), "\n");
-        assertEquals("Manifest", expected, result);
+        assertEquals("Manifest", normalizeWhitespace(expected), normalizeWhitespace(result));
         return this;
     }
 
@@ -294,7 +305,7 @@ public class ProjectBuilder {
             assertNotNull("package has a filter.xml", entry);
             String result = IOUtil.toString(zip.getInputStream(entry), "utf-8");
             String expected = FileUtils.fileRead(expectedFilterFile);
-            assertEquals("filter.xml is correct", expected, result);
+            assertEquals("filter.xml is correct", normalizeWhitespace(expected), normalizeWhitespace(result));
         }
         return this;
     }
@@ -312,4 +323,11 @@ public class ProjectBuilder {
         }
         return buf.toString();
     }
+
+    /**
+     * Eliminates differences in line separators when executing tests on different platform (*nix / windows)
+     */
+    private String normalizeWhitespace(String s) {
+        return s.replaceAll("[\r\n]+", "\n");
+    }
 }

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/pom.xml?rev=1839519&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/pom.xml (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/pom.xml Wed Aug 29 00:34:53 2018
@@ -0,0 +1,40 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<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>
+    <parent>
+        <groupId>org.apache.jackrabbit.filevault</groupId>
+        <artifactId>package-plugin-test-pkg-parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>package-plugin-test-pkg-artifact</artifactId>
+    <packaging>bundle</packaging>
+
+    <name>Packaging test bundle artifact</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>3.5.0</version>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/java/some/SomeClass.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/java/some/SomeClass.java?rev=1839519&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/java/some/SomeClass.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/a/src/main/java/some/SomeClass.java Wed Aug 29 00:34:53 2018
@@ -0,0 +1,19 @@
+package some;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+public class SomeClass {}
\ No newline at end of file

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/b/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/b/pom.xml?rev=1839519&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/b/pom.xml (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/b/pom.xml Wed Aug 29 00:34:53 2018
@@ -0,0 +1,60 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<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>
+
+    <parent>
+        <groupId>org.apache.jackrabbit.filevault</groupId>
+        <artifactId>package-plugin-test-pkg-parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>package-plugin-test-pkg</artifactId>
+    <packaging>content-package</packaging>
+    <name>Packaging test</name>
+
+    <build>
+        <plugins>
+            <!-- content package plugin -->
+            <plugin>
+                <groupId>org.apache.jackrabbit</groupId>
+                <artifactId>filevault-package-maven-plugin</artifactId>
+                <version>1.0.2-SNAPSHOT</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <failOnEmptyFilter>false</failOnEmptyFilter>
+                    <embeddeds>
+                        <embedded>
+                            <groupId>${project.groupId}</groupId>
+                            <artifactId>package-plugin-test-pkg-artifact</artifactId>
+                            <target>/libs/install</target>
+                        </embedded>
+                    </embeddeds>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>package-plugin-test-pkg-artifact</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/pom.xml?rev=1839519&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/pom.xml (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/test/resources/test-projects/analyze-classes-multimodule/pom.xml Wed Aug 29 00:34:53 2018
@@ -0,0 +1,32 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<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>
+
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <groupId>org.apache.jackrabbit.filevault</groupId>
+    <artifactId>package-plugin-test-pkg-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>Parent</name>
+    <modules>
+        <module>a</module>
+        <module>b</module>
+    </modules>
+</project>