You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by iv...@apache.org on 2012/06/19 12:58:17 UTC

svn commit: r1351651 - in /zookeeper/bookkeeper/trunk: ./ bookkeeper-server/ bookkeeper-server/src/test/java/org/apache/bookkeeper/test/ compat-deps/ compat-deps/bookkeeper-server-compat-4.0.0/ compat-deps/bookkeeper-server-compat-4.1.0/

Author: ivank
Date: Tue Jun 19 10:58:16 2012
New Revision: 1351651

URL: http://svn.apache.org/viewvc?rev=1351651&view=rev
Log:
BOOKKEEPER-292: Test backward compatibility automatically between versions. (ivank)

Added:
    zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/TestBackwardCompat.java
    zookeeper/bookkeeper/trunk/compat-deps/
    zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.0.0/
    zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.0.0/pom.xml
    zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.1.0/
    zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.1.0/pom.xml
    zookeeper/bookkeeper/trunk/compat-deps/pom.xml
Modified:
    zookeeper/bookkeeper/trunk/CHANGES.txt
    zookeeper/bookkeeper/trunk/bookkeeper-server/pom.xml
    zookeeper/bookkeeper/trunk/pom.xml

Modified: zookeeper/bookkeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/CHANGES.txt?rev=1351651&r1=1351650&r2=1351651&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/CHANGES.txt (original)
+++ zookeeper/bookkeeper/trunk/CHANGES.txt Tue Jun 19 10:58:16 2012
@@ -16,6 +16,8 @@ Trunk (unreleased changes)
 
       BOOKKEEPER-298: We run with preferIPv4Stack in the scripts but not in the tests (ivank)
 
+      BOOKKEEPER-292: Test backward compatibility automatically between versions. (ivank)
+
       bookkeeper-server:
 
         BOOKKEEPER-183: Provide tools to read/check data files in bookie server (sijie via ivank)

Modified: zookeeper/bookkeeper/trunk/bookkeeper-server/pom.xml
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/pom.xml?rev=1351651&r1=1351650&r2=1351651&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/pom.xml (original)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/pom.xml Tue Jun 19 10:58:16 2012
@@ -116,6 +116,18 @@
 	</exclusion>
       </exclusions>
     </dependency>
+    <dependency>
+      <groupId>org.apache.bookkeeper</groupId>
+      <artifactId>bookkeeper-server-compat400</artifactId>
+      <version>4.0.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.bookkeeper</groupId>
+      <artifactId>bookkeeper-server-compat410</artifactId>
+      <version>4.1.0</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>

Added: zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/TestBackwardCompat.java
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/TestBackwardCompat.java?rev=1351651&view=auto
==============================================================================
--- zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/TestBackwardCompat.java (added)
+++ zookeeper/bookkeeper/trunk/bookkeeper-server/src/test/java/org/apache/bookkeeper/test/TestBackwardCompat.java Tue Jun 19 10:58:16 2012
@@ -0,0 +1,506 @@
+/**
+ *
+ * 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.bookkeeper.test;
+
+import java.io.File;
+
+import java.util.Enumeration;
+import java.util.Arrays;
+import java.net.InetAddress;
+
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.After;
+import static org.junit.Assert.*;
+
+import org.apache.bookkeeper.bookie.FileSystemUpgrade;
+
+public class TestBackwardCompat {
+    private static ZooKeeperUtil zkUtil = new ZooKeeperUtil();;
+    private static int nextPort = 3181;
+    private static byte[] ENTRY_DATA = "ThisIsAnEntry".getBytes();
+
+    static void waitUp(int port) throws Exception {
+        while(zkUtil.getZooKeeperClient().exists(
+                      "/ledgers/available/" + InetAddress.getLocalHost().getHostAddress() + ":" + port,
+                      false) == null) {
+            Thread.sleep(500);
+        }
+    }
+    @Before
+    public void startZooKeeperServer() throws Exception {
+        zkUtil.startServer();
+    }
+
+    @After
+    public void stopZooKeeperServer() throws Exception {
+        zkUtil.killServer();
+    }
+
+    /**
+     * Version 4.0.0 classes
+     */
+    static class Server400 {
+        org.apache.bk_v4_0_0.bookkeeper.conf.ServerConfiguration conf;
+        org.apache.bk_v4_0_0.bookkeeper.proto.BookieServer server = null;
+
+        Server400(File journalDir, File ledgerDir, int port) throws Exception {
+            conf = new org.apache.bk_v4_0_0.bookkeeper.conf.ServerConfiguration();
+            conf.setBookiePort(port);
+            conf.setZkServers(zkUtil.getZooKeeperConnectString());
+            conf.setJournalDirName(journalDir.getPath());
+            conf.setLedgerDirNames(new String[] { ledgerDir.getPath() });
+        }
+
+        void start() throws Exception {
+            server = new org.apache.bk_v4_0_0.bookkeeper.proto.BookieServer(conf);
+            server.start();
+            waitUp(conf.getBookiePort());
+        }
+
+        org.apache.bk_v4_0_0.bookkeeper.conf.ServerConfiguration getConf() {
+            return conf;
+        }
+
+        void stop() throws Exception {
+            if (server != null) {
+                server.shutdown();
+            }
+        }
+    }
+
+    static class Ledger400 {
+        org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper bk;
+        org.apache.bk_v4_0_0.bookkeeper.client.LedgerHandle lh;
+
+        private Ledger400(org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper bk,
+                          org.apache.bk_v4_0_0.bookkeeper.client.LedgerHandle lh) {
+            this.bk = bk;
+            this.lh = lh;
+        }
+
+        static Ledger400 newLedger() throws Exception {
+            org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper newbk
+                = new org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper(zkUtil.getZooKeeperConnectString());
+            org.apache.bk_v4_0_0.bookkeeper.client.LedgerHandle newlh
+                = newbk.createLedger(1, 1,
+                                  org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper.DigestType.CRC32,
+                                  "foobar".getBytes());
+            return new Ledger400(newbk, newlh);
+        }
+
+        static Ledger400 openLedger(long id) throws Exception {
+            org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper newbk
+                = new org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper(zkUtil.getZooKeeperConnectString());
+            org.apache.bk_v4_0_0.bookkeeper.client.LedgerHandle newlh
+                = newbk.openLedger(id,
+                                org.apache.bk_v4_0_0.bookkeeper.client.BookKeeper.DigestType.CRC32,
+                                "foobar".getBytes());
+            return new Ledger400(newbk, newlh);
+        }
+
+        long getId() {
+            return lh.getId();
+        }
+
+        void write100() throws Exception {
+            for (int i = 0; i < 100; i++) {
+                lh.addEntry(ENTRY_DATA);
+            }
+        }
+
+        long readAll() throws Exception {
+            long count = 0;
+            Enumeration<org.apache.bk_v4_0_0.bookkeeper.client.LedgerEntry> entries
+                = lh.readEntries(0, lh.getLastAddConfirmed());
+            while (entries.hasMoreElements()) {
+                assertTrue("entry data doesn't match",
+                           Arrays.equals(entries.nextElement().getEntry(), ENTRY_DATA));
+                count++;
+            }
+            return count;
+        }
+
+        void close() throws Exception {
+            if (lh != null) {
+                lh.close();
+            }
+            if (bk != null) {
+                bk.close();
+            }
+        }
+    }
+
+    /**
+     * Version 4.1.0 classes
+     */
+    static class Server410 {
+        org.apache.bk_v4_1_0.bookkeeper.conf.ServerConfiguration conf;
+        org.apache.bk_v4_1_0.bookkeeper.proto.BookieServer server = null;
+
+        Server410(File journalDir, File ledgerDir, int port) throws Exception {
+            conf = new org.apache.bk_v4_1_0.bookkeeper.conf.ServerConfiguration();
+            conf.setBookiePort(port);
+            conf.setZkServers(zkUtil.getZooKeeperConnectString());
+            conf.setJournalDirName(journalDir.getPath());
+            conf.setLedgerDirNames(new String[] { ledgerDir.getPath() });
+        }
+
+        void start() throws Exception {
+            server = new org.apache.bk_v4_1_0.bookkeeper.proto.BookieServer(conf);
+            server.start();
+            waitUp(conf.getBookiePort());
+        }
+
+        org.apache.bk_v4_1_0.bookkeeper.conf.ServerConfiguration getConf() {
+            return conf;
+        }
+
+        void stop() throws Exception {
+            if (server != null) {
+                server.shutdown();
+            }
+        }
+    }
+
+    static class Ledger410 {
+        org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper bk;
+        org.apache.bk_v4_1_0.bookkeeper.client.LedgerHandle lh;
+
+        private Ledger410(org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper bk,
+                          org.apache.bk_v4_1_0.bookkeeper.client.LedgerHandle lh) {
+            this.bk = bk;
+            this.lh = lh;
+        }
+
+        static Ledger410 newLedger() throws Exception {
+            org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper newbk
+                = new org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper(zkUtil.getZooKeeperConnectString());
+            org.apache.bk_v4_1_0.bookkeeper.client.LedgerHandle newlh
+                = newbk.createLedger(1, 1,
+                                  org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper.DigestType.CRC32,
+                                  "foobar".getBytes());
+            return new Ledger410(newbk, newlh);
+        }
+
+        static Ledger410 openLedger(long id) throws Exception {
+            org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper newbk
+                = new org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper(zkUtil.getZooKeeperConnectString());
+            org.apache.bk_v4_1_0.bookkeeper.client.LedgerHandle newlh
+                = newbk.openLedger(id,
+                                org.apache.bk_v4_1_0.bookkeeper.client.BookKeeper.DigestType.CRC32,
+                                "foobar".getBytes());
+            return new Ledger410(newbk, newlh);
+        }
+
+        long getId() {
+            return lh.getId();
+        }
+
+        void write100() throws Exception {
+            for (int i = 0; i < 100; i++) {
+                lh.addEntry(ENTRY_DATA);
+            }
+        }
+
+        long readAll() throws Exception {
+            long count = 0;
+            Enumeration<org.apache.bk_v4_1_0.bookkeeper.client.LedgerEntry> entries
+                = lh.readEntries(0, lh.getLastAddConfirmed());
+            while (entries.hasMoreElements()) {
+                assertTrue("entry data doesn't match",
+                           Arrays.equals(entries.nextElement().getEntry(), ENTRY_DATA));
+                count++;
+            }
+            return count;
+        }
+
+        void close() throws Exception {
+            if (lh != null) {
+                lh.close();
+            }
+            if (bk != null) {
+                bk.close();
+            }
+        }
+    }
+
+    /**
+     * Current verion classes
+     */
+    static class ServerCurrent {
+        org.apache.bookkeeper.conf.ServerConfiguration conf;
+        org.apache.bookkeeper.proto.BookieServer server = null;
+
+        ServerCurrent(File journalDir, File ledgerDir, int port) throws Exception {
+            conf = new org.apache.bookkeeper.conf.ServerConfiguration();
+            conf.setBookiePort(port);
+            conf.setZkServers(zkUtil.getZooKeeperConnectString());
+            conf.setJournalDirName(journalDir.getPath());
+            conf.setLedgerDirNames(new String[] { ledgerDir.getPath() });
+        }
+
+        void start() throws Exception {
+            server = new org.apache.bookkeeper.proto.BookieServer(conf);
+            server.start();
+            waitUp(conf.getBookiePort());
+        }
+
+        org.apache.bookkeeper.conf.ServerConfiguration getConf() {
+            return conf;
+        }
+
+        void stop() throws Exception {
+            if (server != null) {
+                server.shutdown();
+            }
+        }
+    }
+
+    static class LedgerCurrent {
+        org.apache.bookkeeper.client.BookKeeper bk;
+        org.apache.bookkeeper.client.LedgerHandle lh;
+
+        private LedgerCurrent(org.apache.bookkeeper.client.BookKeeper bk,
+                              org.apache.bookkeeper.client.LedgerHandle lh) {
+            this.bk = bk;
+            this.lh = lh;
+        }
+
+        static LedgerCurrent newLedger() throws Exception {
+            org.apache.bookkeeper.client.BookKeeper newbk
+                = new org.apache.bookkeeper.client.BookKeeper(zkUtil.getZooKeeperConnectString());
+            org.apache.bookkeeper.client.LedgerHandle newlh
+                = newbk.createLedger(1, 1,
+                                     org.apache.bookkeeper.client.BookKeeper.DigestType.CRC32,
+                                     "foobar".getBytes());
+            return new LedgerCurrent(newbk, newlh);
+        }
+
+        static LedgerCurrent openLedger(long id) throws Exception {
+            org.apache.bookkeeper.client.BookKeeper newbk
+                = new org.apache.bookkeeper.client.BookKeeper(zkUtil.getZooKeeperConnectString());
+            org.apache.bookkeeper.client.LedgerHandle newlh
+                = newbk.openLedger(id,
+                                org.apache.bookkeeper.client.BookKeeper.DigestType.CRC32,
+                                "foobar".getBytes());
+            return new LedgerCurrent(newbk, newlh);
+        }
+
+        long getId() {
+            return lh.getId();
+        }
+
+        void write100() throws Exception {
+            for (int i = 0; i < 100; i++) {
+                lh.addEntry(ENTRY_DATA);
+            }
+        }
+
+        long readAll() throws Exception {
+            long count = 0;
+            Enumeration<org.apache.bookkeeper.client.LedgerEntry> entries
+                = lh.readEntries(0, lh.getLastAddConfirmed());
+            while (entries.hasMoreElements()) {
+                assertTrue("entry data doesn't match",
+                           Arrays.equals(entries.nextElement().getEntry(), ENTRY_DATA));
+                count++;
+            }
+            return count;
+        }
+
+        void close() throws Exception {
+            if (lh != null) {
+                lh.close();
+            }
+            if (bk != null) {
+                bk.close();
+            }
+        }
+    }
+
+    /**
+     * Test compatability between version 4.0.0 and the current version.
+     * Incompatabilities are:
+     *  - Current client will not be able to talk to 4.0.0 server.
+     *  - 4.0.0 client will not be able to fence ledgers on current server.
+     *  - Current server won't start with 4.0.0 server directories without upgrade.
+     */
+    @Test
+    public void testCompat400() throws Exception {
+        File journalDir = File.createTempFile("bookie", "journal");
+        journalDir.delete();
+        journalDir.mkdir();
+        File ledgerDir = File.createTempFile("bookie", "ledger");
+        ledgerDir.delete();
+        ledgerDir.mkdir();
+
+        int port = nextPort++;
+        // start server, upgrade
+        Server400 s400 = new Server400(journalDir, ledgerDir, port);
+        s400.start();
+
+        Ledger400 l400 = Ledger400.newLedger();
+        l400.write100();
+        long oldLedgerId = l400.getId();
+        l400.close();
+
+        // Check that current client isn't able to write to old server
+        LedgerCurrent lcur = LedgerCurrent.newLedger();
+        try {
+            lcur.write100();
+            fail("Current shouldn't be able to write to 4.0.0 server");
+        } catch (Exception e) {
+        }
+        lcur.close();
+
+        s400.stop();
+
+        // Start the current server, will require a filesystem upgrade
+        ServerCurrent scur = new ServerCurrent(journalDir, ledgerDir, port);
+        try {
+            scur.start();
+            fail("Shouldn't be able to start without directory upgrade");
+        } catch (Exception e) {
+        }
+        FileSystemUpgrade.upgrade(scur.getConf());
+
+        scur.start();
+
+        // check that old client can read its old ledgers on new server
+        l400 = Ledger400.openLedger(oldLedgerId);
+        assertEquals(100, l400.readAll());
+        l400.close();
+
+        // check that old client can create ledgers on new server
+        l400 = Ledger400.newLedger();
+        l400.write100();
+        l400.close();
+
+        // check that current client can read old ledger
+        lcur = LedgerCurrent.openLedger(oldLedgerId);
+        assertEquals(100, lcur.readAll());
+        lcur.close();
+
+        // check that old client can read current client's ledgers
+        lcur = LedgerCurrent.openLedger(oldLedgerId);
+        assertEquals(100, lcur.readAll());
+        lcur.close();
+
+        // check that old client can not fence a current client
+        // due to lack of password
+        lcur = LedgerCurrent.newLedger();
+        lcur.write100();
+        long fenceLedgerId = lcur.getId();
+        try {
+            l400 = Ledger400.openLedger(fenceLedgerId);
+            fail("Shouldn't be able to open ledger");
+        } catch (Exception e) {
+            // correct behaviour
+        }
+        lcur.write100();
+        try {
+            // Unfortunately, as the 4.0.0 client doesn't know that it should
+            // be checking for a password. It puts the ledger metadata in recover
+            // mode. This means we're not able to close, as our metadata znode is
+            // out of date
+            lcur.close();
+
+            fail("Shouldn't be able to close cleanly");
+        } catch (Exception e) {
+        }
+        lcur = LedgerCurrent.openLedger(fenceLedgerId);
+        assertEquals(200, lcur.readAll());
+        lcur.close();
+
+        scur.stop();
+    }
+
+    /**
+     * Test compatability between version 4.1.0 and the current version.
+     * Should be 100% compatible.
+     */
+    @Test
+    public void testCompat410() throws Exception {
+        File journalDir = File.createTempFile("bookie", "journal");
+        journalDir.delete();
+        journalDir.mkdir();
+        File ledgerDir = File.createTempFile("bookie", "ledger");
+        ledgerDir.delete();
+        ledgerDir.mkdir();
+
+        int port = nextPort++;
+        // start server, upgrade
+        Server410 s410 = new Server410(journalDir, ledgerDir, port);
+        s410.start();
+
+        Ledger410 l410 = Ledger410.newLedger();
+        l410.write100();
+        long oldLedgerId = l410.getId();
+        l410.close();
+
+        // Check that current client can to write to old server
+        LedgerCurrent lcur = LedgerCurrent.newLedger();
+        lcur.write100();
+        lcur.close();
+
+        s410.stop();
+
+        // Start the current server, will not require a filesystem upgrade
+        ServerCurrent scur = new ServerCurrent(journalDir, ledgerDir, port);
+        scur.start();
+
+        // check that old client can read its old ledgers on new server
+        l410 = Ledger410.openLedger(oldLedgerId);
+        assertEquals(100, l410.readAll());
+        l410.close();
+
+        // check that old client can create ledgers on new server
+        l410 = Ledger410.newLedger();
+        l410.write100();
+        l410.close();
+
+        // check that current client can read old ledger
+        lcur = LedgerCurrent.openLedger(oldLedgerId);
+        assertEquals(100, lcur.readAll());
+        lcur.close();
+
+        // check that old client can read current client's ledgers
+        lcur = LedgerCurrent.openLedger(oldLedgerId);
+        assertEquals(100, lcur.readAll());
+        lcur.close();
+
+        // check that old client can fence a current client
+        // due to lack of password
+        lcur = LedgerCurrent.newLedger();
+        lcur.write100();
+        long fenceLedgerId = lcur.getId();
+        l410 = Ledger410.openLedger(fenceLedgerId);
+        try {
+            lcur.write100();
+            fail("Fencing should have prevented this write");
+        } catch (Exception e) {
+        }
+        assertEquals(100, l410.readAll());
+
+        scur.stop();
+    }
+}
\ No newline at end of file

Added: zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.0.0/pom.xml
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.0.0/pom.xml?rev=1351651&view=auto
==============================================================================
--- zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.0.0/pom.xml (added)
+++ zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.0.0/pom.xml Tue Jun 19 10:58:16 2012
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<!--
+   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 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>compat-deps</artifactId>
+    <groupId>org.apache.bookkeeper</groupId>
+    <version>4.2.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.bookkeeper</groupId>
+  <artifactId>bookkeeper-server-compat400</artifactId>
+  <version>4.0.0</version>
+  <name>bookkeeper-server-compat400</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.bookkeeper</groupId>
+      <artifactId>bookkeeper-server</artifactId>
+      <version>4.0.0</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <createDependencyReducedPom>false</createDependencyReducedPom>
+              <artifactSet>
+                <includes>
+                  <include>org.apache.*:*</include>
+                  <include>org.jboss.*:*</include>
+                  <include>commons-*:*</include>
+                </includes>
+                <excludes>
+                  <exclude>commons-beanutils*:commons-beanutils*</exclude>
+                </excludes>
+              </artifactSet>
+              <relocations>
+                <relocation>
+                  <pattern>org.apache</pattern>
+                  <shadedPattern>org.apache.bk_v4_0_0</shadedPattern>
+                  <excludes>
+                    <exclude>org.apache.log4j</exclude>
+                  </excludes>
+                </relocation>
+                <relocation>
+                  <pattern>org.jboss</pattern>
+                  <shadedPattern>org.jboss.bk_v4_0_0</shadedPattern>
+                </relocation>
+              </relocations>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file

Added: zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.1.0/pom.xml
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.1.0/pom.xml?rev=1351651&view=auto
==============================================================================
--- zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.1.0/pom.xml (added)
+++ zookeeper/bookkeeper/trunk/compat-deps/bookkeeper-server-compat-4.1.0/pom.xml Tue Jun 19 10:58:16 2012
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<!--
+   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 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>compat-deps</artifactId>
+    <groupId>org.apache.bookkeeper</groupId>
+    <version>4.2.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.bookkeeper</groupId>
+  <artifactId>bookkeeper-server-compat410</artifactId>
+  <version>4.1.0</version>
+  <name>bookkeeper-server-compat410</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.bookkeeper</groupId>
+      <artifactId>bookkeeper-server</artifactId>
+      <version>4.1.0</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <createDependencyReducedPom>false</createDependencyReducedPom>
+              <artifactSet>
+                <includes>
+                  <include>org.apache.*:*</include>
+                  <include>org.jboss.*:*</include>
+                  <include>commons-*:*</include>
+                </includes>
+                <excludes>
+                  <exclude>commons-beanutils*:commons-beanutils*</exclude>
+                </excludes>
+              </artifactSet>
+              <relocations>
+                <relocation>
+                  <pattern>org.apache.commons</pattern>
+                  <shadedPattern>org.apache.bk_v4_1_0.commons</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.apache.bookkeeper</pattern>
+                  <shadedPattern>org.apache.bk_v4_1_0.bookkeeper</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.apache.zookeeper</pattern>
+                  <shadedPattern>org.apache.bk_v4_1_0.bookkeeper</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.apache.jute</pattern>
+                  <shadedPattern>org.apache.bk_v4_1_0.jute</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.jboss</pattern>
+                  <shadedPattern>org.jboss.bk_v4_1_0</shadedPattern>
+                </relocation>
+              </relocations>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file

Added: zookeeper/bookkeeper/trunk/compat-deps/pom.xml
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/compat-deps/pom.xml?rev=1351651&view=auto
==============================================================================
--- zookeeper/bookkeeper/trunk/compat-deps/pom.xml (added)
+++ zookeeper/bookkeeper/trunk/compat-deps/pom.xml Tue Jun 19 10:58:16 2012
@@ -0,0 +1,41 @@
+<!--
+   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/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>bookkeeper</artifactId>
+    <groupId>org.apache.bookkeeper</groupId>
+    <version>4.2.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.bookkeeper</groupId>
+  <version>4.2.0-SNAPSHOT</version>
+  <artifactId>compat-deps</artifactId>
+  <packaging>pom</packaging>
+  <name>compability dependencies</name>
+  <modules>
+    <module>bookkeeper-server-compat-4.0.0</module>
+    <module>bookkeeper-server-compat-4.1.0</module>
+  </modules>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+  </properties>
+</project>
\ No newline at end of file

Modified: zookeeper/bookkeeper/trunk/pom.xml
URL: http://svn.apache.org/viewvc/zookeeper/bookkeeper/trunk/pom.xml?rev=1351651&r1=1351650&r2=1351651&view=diff
==============================================================================
--- zookeeper/bookkeeper/trunk/pom.xml (original)
+++ zookeeper/bookkeeper/trunk/pom.xml Tue Jun 19 10:58:16 2012
@@ -31,6 +31,7 @@
   <packaging>pom</packaging>
   <name>bookkeeper</name>
   <modules>
+    <module>compat-deps</module>
     <module>hedwig-client</module>
     <module>hedwig-server</module>
     <module>hedwig-protocol</module>