hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From la...@apache.org
Subject svn commit: r1511545 - in /hbase/branches/0.94/src: docbkx/ main/java/org/apache/hadoop/hbase/client/ test/java/org/apache/hadoop/hbase/client/
Date Wed, 07 Aug 2013 23:58:28 GMT
Author: larsh
Date: Wed Aug  7 23:58:28 2013
New Revision: 1511545

URL: http://svn.apache.org/r1511545
Log:
HBASE-6580 Deprecate HTablePool in favor of HConnection.getTable(...)

Modified:
    hbase/branches/0.94/src/docbkx/book.xml
    hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnection.java
    hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
    hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java
    hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/HConnectionTestingUtility.java
    hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
    hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java
    hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHConnection.java

Modified: hbase/branches/0.94/src/docbkx/book.xml
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/docbkx/book.xml?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/docbkx/book.xml (original)
+++ hbase/branches/0.94/src/docbkx/book.xml Wed Aug  7 23:58:28 2013
@@ -1516,11 +1516,14 @@ HTable table2 = new HTable(conf2, "myTab
             </para>
             <para>
                 Another solution is to precreate an <classname>HConnection</classname>
using
-                <programlisting>HConnectionManager.createConnection(Configuration)</programlisting>
as
-                well as an <classname>ExecutorService</classname>; then use the
-                <programlisting>HTable(byte[], HConnection, ExecutorService)</programlisting>
-                constructor to create <classname>HTable</classname> instances
on demand.
-                This construction is very lightweight and resources are controlled/shared
if you go this route.
+                <programlisting>// Create a connection to the cluster.
+HConnection connection = HConnectionManager.createConnection(Configuration);
+HTableInterface table = connection.getTable("myTable");
+// use table as needed, the table returned is lightweight
+table.close();
+// use the connection for other access to the cluster
+connection.close();</programlisting>
+                Constructing HTableInterface implementation is very lightweight and resources
are controlled/shared if you go this route.
             </para>
           </section>
    	  </section>

Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnection.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnection.java?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnection.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnection.java Wed
Aug  7 23:58:28 2013
@@ -64,6 +64,60 @@ public interface HConnection extends Abo
   public Configuration getConfiguration();
 
   /**
+   * Retrieve an HTableInterface implementation for access to a table.
+   * The returned HTableInterface is not thread safe, a new instance should
+   * be created for each using thread.
+   * This is a lightweight operation, pooling or caching of the returned HTableInterface
+   * is neither required nor desired.
+   * Note that the HConnection needs to be unmanaged
+   * (created with {@link HConnectionManager#createConnection(Configuration)}).
+   * @param tableName
+   * @return an HTable to use for interactions with this table
+   */
+  public HTableInterface getTable(String tableName) throws IOException;
+
+  /**
+   * Retrieve an HTableInterface implementation for access to a table.
+   * The returned HTableInterface is not thread safe, a new instance should
+   * be created for each using thread.
+   * This is a lightweight operation, pooling or caching of the returned HTableInterface
+   * is neither required nor desired.
+   * Note that the HConnection needs to be unmanaged
+   * (created with {@link HConnectionManager#createConnection(Configuration)}).
+   * @param tableName
+   * @return an HTable to use for interactions with this table
+   */
+  public HTableInterface getTable(byte[] tableName) throws IOException;
+
+  /**
+   * Retrieve an HTableInterface implementation for access to a table.
+   * The returned HTableInterface is not thread safe, a new instance should
+   * be created for each using thread.
+   * This is a lightweight operation, pooling or caching of the returned HTableInterface
+   * is neither required nor desired.
+   * Note that the HConnection needs to be unmanaged
+   * (created with {@link HConnectionManager#createConnection(Configuration)}).
+   * @param tableName
+   * @param pool The thread pool to use for batch operations, null to use a default pool.
+   * @return an HTable to use for interactions with this table
+   */
+  public HTableInterface getTable(String tableName, ExecutorService pool)  throws IOException;
+
+  /**
+   * Retrieve an HTableInterface implementation for access to a table.
+   * The returned HTableInterface is not thread safe, a new instance should
+   * be created for each using thread.
+   * This is a lightweight operation, pooling or caching of the returned HTableInterface
+   * is neither required nor desired.
+   * Note that the HConnection needs to be unmanaged
+   * (created with {@link HConnectionManager#createConnection(Configuration)}).
+   * @param tableName
+   * @param pool The thread pool to use for batch operations, null to use a default pool.
+   * @return an HTable to use for interactions with this table
+   */
+  public HTableInterface getTable(byte[] tableName, ExecutorService pool)  throws IOException;
+
+  /**
    * Retrieve ZooKeeperWatcher used by this connection.
    * @return ZooKeeperWatcher handle being used by the connection.
    * @throws IOException if a remote or network exception occurs

Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
(original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
Wed Aug  7 23:58:28 2013
@@ -41,6 +41,9 @@ import java.util.concurrent.CopyOnWriteA
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -75,6 +78,7 @@ import org.apache.hadoop.hbase.util.Addr
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.hadoop.hbase.util.SoftValueSortedMap;
+import org.apache.hadoop.hbase.util.Threads;
 import org.apache.hadoop.hbase.util.Writables;
 import org.apache.hadoop.hbase.zookeeper.ClusterId;
 import org.apache.hadoop.hbase.zookeeper.RootRegionTracker;
@@ -85,8 +89,22 @@ import org.apache.hadoop.ipc.RemoteExcep
 import org.apache.zookeeper.KeeperException;
 
 /**
- * A non-instantiable class that manages {@link HConnection}s.
- * This class has a static Map of {@link HConnection} instances keyed by
+ * A non-instantiable class that manages creation of {@link HConnection}s.
+ * <p>The simplest way to use this class is by using {@link #createConnection(Configuration)}.
+ * This creates a new {@link HConnection} that is managed by the caller.
+ * From this {@link HConnection} {@link HTableInterface} implementations are retrieved 
+ * with {@link HConnection#getTable(byte[])}. Example:
+ * <pre>
+ * {@code
+ * HConnection connection = HConnectionManager.createConnection(config);
+ * HTableInterface table = connection.getTable("table1");
+ * // use the table as needed, for a single operation and a single thread
+ * table.close();
+ * connection.close();
+ * }
+ * </pre>
+ * <p>The following logic and API will be removed in the future:
+ * <p>This class has a static Map of {@link HConnection} instances keyed by
  * {@link Configuration}; all invocations of {@link #getConnection(Configuration)}
  * that pass the same {@link Configuration} instance will be returned the same
  * {@link  HConnection} instance (Adding properties to a Configuration
@@ -182,11 +200,11 @@ public class HConnectionManager {
     synchronized (HBASE_INSTANCES) {
       HConnectionImplementation connection = HBASE_INSTANCES.get(connectionKey);
       if (connection == null) {
-        connection = new HConnectionImplementation(conf, true);
+        connection = new HConnectionImplementation(conf, true, null);
         HBASE_INSTANCES.put(connectionKey, connection);
       } else if (connection.isClosed()) {
         HConnectionManager.deleteConnection(connectionKey, true);
-        connection = new HConnectionImplementation(conf, true);
+        connection = new HConnectionImplementation(conf, true, null);
         HBASE_INSTANCES.put(connectionKey, connection);
       }
       connection.incCount();
@@ -197,16 +215,31 @@ public class HConnectionManager {
   /**
    * Create a new HConnection instance using the passed <code>conf</code>
    * instance.
-   * Note: This bypasses the usual HConnection life cycle management!
-   * Use this with caution, the caller is responsible for closing the
-   * created connection.
+   * Note: This bypasses the usual HConnection life cycle management.
+   * The caller is responsible for calling {@link HConnection#close()}
+   * on the returned connection instance.
+   *
+   * This is the recommended way to create HConnections.
+   * {@code
+   * HConnection connection = HConnectionManager.createConnection(conf);
+   * HTableInterface table = connection.getTable("mytable");
+   * table.get(...);
+   * ...
+   * table.close();
+   * connection.close();
+   * }
    * @param conf configuration
    * @return HConnection object for <code>conf</code>
    * @throws ZooKeeperConnectionException
    */
   public static HConnection createConnection(Configuration conf)
   throws ZooKeeperConnectionException {
-    return new HConnectionImplementation(conf, false);
+    return new HConnectionImplementation(conf, false, null);
+  }
+
+  public static HConnection createConnection(Configuration conf, ExecutorService pool)
+      throws IOException {
+    return new HConnectionImplementation(conf, false, pool);
   }
 
   /**
@@ -235,6 +268,7 @@ public class HConnectionManager {
    *          configuration whose identity is used to find {@link HConnection}
    *          instance.
    */
+  @Deprecated
   public static void deleteConnection(Configuration conf) {
     deleteConnection(new HConnectionKey(conf), false);
   }
@@ -264,6 +298,7 @@ public class HConnectionManager {
    * Delete information for all connections.
    * @throws IOException
    */
+  @Deprecated
   public static void deleteAllConnections() {
     synchronized (HBASE_INSTANCES) {
       Set<HConnectionKey> connectionKeys = new HashSet<HConnectionKey>();
@@ -275,6 +310,7 @@ public class HConnectionManager {
     }
   }
 
+  @Deprecated
   private static void deleteConnection(HConnection connection, boolean staleConnection) {
     synchronized (HBASE_INSTANCES) {
       for (Entry<HConnectionKey, HConnectionImplementation> connectionEntry : HBASE_INSTANCES
@@ -287,6 +323,7 @@ public class HConnectionManager {
     }
   }
 
+  @Deprecated
   private static void deleteConnection(HConnectionKey connectionKey,
       boolean staleConnection) {
     synchronized (HBASE_INSTANCES) {
@@ -533,6 +570,11 @@ public class HConnectionManager {
 	
     private final Object resetLock = new Object();
 
+    // thread executor shared by all HTableInterface instances created
+    // by this connection
+    private volatile ExecutorService batchPool = null;
+    private volatile boolean cleanupPool = false;
+
     private final Configuration conf;
 
     private RpcEngine rpcEngine;
@@ -573,9 +615,10 @@ public class HConnectionManager {
      * @param conf Configuration object
      */
     @SuppressWarnings("unchecked")
-    public HConnectionImplementation(Configuration conf, boolean managed)
+    public HConnectionImplementation(Configuration conf, boolean managed, ExecutorService
pool)
     throws ZooKeeperConnectionException {
       this.conf = conf;
+      this.batchPool = pool;
       this.managed = managed;
       String serverClassName = conf.get(HConstants.REGION_SERVER_CLASS,
         HConstants.DEFAULT_REGION_SERVER_CLASS);
@@ -605,6 +648,67 @@ public class HConnectionManager {
       this.resetting = false;
     }
 
+    @Override
+    public HTableInterface getTable(String tableName) throws IOException {
+      return getTable(Bytes.toBytes(tableName));
+    }
+
+    @Override
+    public HTableInterface getTable(byte[] tableName) throws IOException {
+      return getTable(tableName, getBatchPool());
+    }
+
+    @Override
+    public HTableInterface getTable(String tableName, ExecutorService pool) throws IOException
{
+      return getTable(Bytes.toBytes(tableName), pool);
+    }
+
+    @Override
+    public HTableInterface getTable(byte[] tableName, ExecutorService pool) throws IOException
{
+      if (managed) {
+        throw new IOException("The connection has to be unmanaged.");
+      }
+      return new HTable(tableName, this, pool);
+    }
+
+    private ExecutorService getBatchPool() {
+      if (batchPool == null) {
+        // shared HTable thread executor not yet initialized
+        synchronized (this) {
+          if (batchPool == null) {
+            int maxThreads = conf.getInt("hbase.hconnection.threads.max", Integer.MAX_VALUE);
+            if (maxThreads == 0) {
+              maxThreads = Runtime.getRuntime().availableProcessors();
+            }
+            long keepAliveTime = conf.getLong("hbase.hconnection.threads.keepalivetime",
60);
+            this.batchPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
+                maxThreads, keepAliveTime, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
+                Threads.newDaemonThreadFactory("hbase-connection-shared-executor"));
+            ((ThreadPoolExecutor) this.batchPool).allowCoreThreadTimeOut(true);
+          }
+          this.cleanupPool = true;
+        }
+      }
+      return this.batchPool;
+    }
+
+    protected ExecutorService getCurrentBatchPool() {
+      return batchPool;
+    }
+
+    private void shutdownBatchPool() {
+      if (this.cleanupPool && this.batchPool != null && !this.batchPool.isShutdown())
{
+        this.batchPool.shutdown();
+        try {
+          if (!this.batchPool.awaitTermination(10, TimeUnit.SECONDS)) {
+            this.batchPool.shutdownNow();
+          }
+        } catch (InterruptedException e) {
+          this.batchPool.shutdownNow();
+        }
+      }
+    }
+
     private synchronized void ensureZookeeperTrackers()
         throws ZooKeeperConnectionException {
       // initialize zookeeper and master address manager
@@ -1814,6 +1918,7 @@ public class HConnectionManager {
       if (this.closed) {
         return;
       }
+      shutdownBatchPool();
       master = null;
 
       this.servers.clear();

Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java Wed Aug
 7 23:58:28 2013
@@ -56,6 +56,7 @@ import org.apache.hadoop.hbase.util.Pool
  * <p>
  * Pool will manage its own connections to the cluster. See
  * {@link HConnectionManager}.
+ * @deprecated Use {@link HConnection#getTable(String)} instead.
  */
 public class HTablePool implements Closeable {
   private final PoolMap<String, HTableInterface> tables;

Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/HConnectionTestingUtility.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/HConnectionTestingUtility.java?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/HConnectionTestingUtility.java
(original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/HConnectionTestingUtility.java
Wed Aug  7 23:58:28 2013
@@ -129,7 +129,7 @@ public class HConnectionTestingUtility {
       HConnectionImplementation connection =
         HConnectionManager.HBASE_INSTANCES.get(connectionKey);
       if (connection == null) {
-        connection = Mockito.spy(new HConnectionImplementation(conf, true));
+        connection = Mockito.spy(new HConnectionImplementation(conf, true, null));
         HConnectionManager.HBASE_INSTANCES.put(connectionKey, connection);
       }
       return connection;

Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
(original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
Wed Aug  7 23:58:28 2013
@@ -3901,12 +3901,7 @@ public class TestFromClientSide {
   HTable createUnmangedHConnectionHTable(final byte [] tableName) throws IOException {
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
     HConnection conn = HConnectionManager.createConnection(TEST_UTIL.getConfiguration());
-    ExecutorService pool = new ThreadPoolExecutor(1, Integer.MAX_VALUE,
-      60, TimeUnit.SECONDS,
-      new SynchronousQueue<Runnable>(),
-      Threads.newDaemonThreadFactory("test-from-client-table"));
-    ((ThreadPoolExecutor)pool).allowCoreThreadTimeOut(true);
-    return new HTable(tableName, conn, pool);
+    return (HTable)conn.getTable(tableName);
   }
 
   /**

Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java (original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java Wed Aug
 7 23:58:28 2013
@@ -25,12 +25,14 @@ import static org.junit.Assert.assertNul
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.IOException;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -130,6 +132,61 @@ public class TestHCM {
   }
   
   @Test
+  public void testClusterConnection() throws IOException {
+    ThreadPoolExecutor otherPool = new ThreadPoolExecutor(1, 1, 5, TimeUnit.SECONDS,
+        new SynchronousQueue<Runnable>(), Threads.newDaemonThreadFactory("test-hcm"));
+
+    HConnection con1 = HConnectionManager.createConnection(TEST_UTIL.getConfiguration());
+    HConnection con2 = HConnectionManager.createConnection(TEST_UTIL.getConfiguration(),
otherPool);
+    // make sure the internally created ExecutorService is the one passed
+    assertTrue(otherPool == ((HConnectionImplementation) con2).getCurrentBatchPool());
+
+    String tableName = "testClusterConnection";
+    TEST_UTIL.createTable(tableName.getBytes(), FAM_NAM).close();
+    HTable t = (HTable) con1.getTable(tableName, otherPool);
+    // make sure passing a pool to the getTable does not trigger creation of an
+    // internal pool
+    assertNull("Internal Thread pool should be null",
+        ((HConnectionImplementation) con1).getCurrentBatchPool());
+    // table should use the pool passed
+    assertTrue(otherPool == t.getPool());
+    t.close();
+
+    t = (HTable) con2.getTable(tableName);
+    // table should use the connectin's internal pool
+    assertTrue(otherPool == t.getPool());
+    t.close();
+
+    t = (HTable) con2.getTable(Bytes.toBytes(tableName));
+    // try other API too
+    assertTrue(otherPool == t.getPool());
+    t.close();
+
+    t = (HTable) con1.getTable(tableName);
+    ExecutorService pool = ((HConnectionImplementation) con1).getCurrentBatchPool();
+    // make sure an internal pool was created
+    assertNotNull("An internal Thread pool should have been created", pool);
+    // and that the table is using it
+    assertTrue(t.getPool() == pool);
+    t.close();
+
+    t = (HTable) con1.getTable(tableName);
+    // still using the *same* internal pool
+    assertTrue(t.getPool() == pool);
+    t.close();
+
+    con1.close();
+    // if the pool was created on demand it should be closed upon connectin
+    // close
+    assertTrue(pool.isShutdown());
+
+    con2.close();
+    // if the pool is passed, it is not closed
+    assertFalse(otherPool.isShutdown());
+    otherPool.shutdownNow();
+  }
+  
+  @Test
   public void abortingHConnectionRemovesItselfFromHCM() throws Exception {
     // Save off current HConnections
     Map<HConnectionKey, HConnectionImplementation> oldHBaseInstances = 
@@ -180,20 +237,16 @@ public class TestHCM {
   public void testConnectionManagement() throws Exception{
     TEST_UTIL.createTable(TABLE_NAME1, FAM_NAM);
     HConnection conn = HConnectionManager.createConnection(TEST_UTIL.getConfiguration());
-    ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 10,
-        60, TimeUnit.SECONDS,
-        new SynchronousQueue<Runnable>(),
-        Threads.newDaemonThreadFactory("test-hcm-table"));
 
-    HTable table = new HTable(TABLE_NAME1, conn, pool);
+    HTableInterface table = conn.getTable(TABLE_NAME1);
     table.close();
     assertFalse(conn.isClosed());
-    assertFalse(pool.isShutdown());
-    table = new HTable(TEST_UTIL.getConfiguration(), TABLE_NAME1, pool);
+    assertFalse(((HTable)table).getPool().isShutdown());
+    table = conn.getTable(TABLE_NAME1);
     table.close();
-    assertFalse(pool.isShutdown());
+    assertFalse(((HTable)table).getPool().isShutdown());
     conn.close();
-    pool.shutdownNow();
+    assertTrue(((HTable)table).getPool().isShutdown());
   }
 
   /**

Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHConnection.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHConnection.java?rev=1511545&r1=1511544&r2=1511545&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHConnection.java
(original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/client/TestHConnection.java
Wed Aug  7 23:58:28 2013
@@ -83,7 +83,7 @@ public class TestHConnection {
 
   class HConnectionRaceTester extends HConnectionImplementation {
     public HConnectionRaceTester(Configuration configuration, boolean managed) throws ZooKeeperConnectionException
{
-      super(configuration, managed);
+      super(configuration, managed, null);
     }
 
     /**



Mime
View raw message