Configuring Apache Zookeeper and HBase in IntelliJ IDEA with Java Client APIs

Maven Dependencies

To work with Zookeeper and HBase in your IntelliJ IDEA project, add the following dependencies to your pom.xml file. Adjust the versions according to your cluster setup.

Zookeeper Client Dependency

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.17.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.6.3</version>
    </dependency>
</dependencies>

HBase Client Dependencies

<dependencies>
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-server</artifactId>
        <version>2.3.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>2.3.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-auth</artifactId>
        <version>3.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-common</artifactId>
        <version>2.3.0</version>
    </dependency>
</dependencies>

HBase Java Client: Basic Operations

The following class demonstrates fundamental DDL and DML operations using the HBase Java API. This implemantation includes connection pooling, table existence checks, CRUD operations, and namespace management.

package com.bigdata.hbase;

import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

/**
 * HBase Java API wrapper providing DDL and DML operations.
 * Supports table management, data manipulation, and namespace operations.
 */
public class HBaseManager {
    
    private static Connection hbaseConnection = null;
    private static Admin hbaseAdmin = null;
    
    private static final String ZOOKEEPER_QUORUM = "node1,node2,node3";
    private static final String ZOOKEEPER_PORT = "2181";
    
    static {
        initializeConnection();
    }
    
    private static void initializeConnection() {
        try {
            Configuration hbaseConfig = HBaseConfiguration.create();
            hbaseConfig.set("hbase.zookeeper.quorum", ZOOKEEPER_QUORUM);
            hbaseConfig.set("hbase.zookeeper.property.clientPort", ZOOKEEPER_PORT);
            
            hbaseConnection = ConnectionFactory.createConnection(hbaseConfig);
            hbaseAdmin = hbaseConnection.getAdmin();
        } catch (IOException e) {
            throw new RuntimeException("Failed to initialize HBase connection", e);
        }
    }
    
    /**
     * Verifies whether a table exists in HBase.
     * @param tableName The name of the table to check
     * @return true if the table exists, false otherwise
     */
    public static boolean tableExists(String tableName) throws IOException {
        return hbaseAdmin.tableExists(TableName.valueOf(tableName));
    }
    
    /**
     * Creates a new table with specified column families.
     * @param tableName The name of the table to create
     * @param columnFamilies Variable number of column family names
     */
    public static void createTable(String tableName, String... columnFamilies) throws IOException {
        if (columnFamilies.length == 0) {
            throw new IllegalArgumentException("At least one column family must be specified");
        }
        
        if (tableExists(tableName)) {
            System.out.println("Table '" + tableName + "' already exists.");
            return;
        }
        
        TableName tn = TableName.valueOf(tableName);
        TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tn);
        
        for (String cf : columnFamilies) {
            ColumnFamilyDescriptor cfDescriptor = ColumnFamilyDescriptorBuilder
                    .newBuilder(Bytes.toBytes(cf))
                    .setMaxVersions(3)
                    .build();
            tableDescriptorBuilder.setColumnFamily(cfDescriptor);
        }
        
        hbaseAdmin.createTable(tableDescriptorBuilder.build());
        System.out.println("Table '" + tableName + "' created successfully.");
    }
    
    /**
     * Removes a table from HBase.
     * @param tableName The name of the table to delete
     */
    public static void dropTable(String tableName) throws IOException {
        if (!tableExists(tableName)) {
            System.out.println("Table '" + tableName + "' does not exist.");
            return;
        }
        
        TableName tn = TableName.valueOf(tableName);
        if (hbaseAdmin.isTableEnabled(tn)) {
            hbaseAdmin.disableTable(tn);
        }
        hbaseAdmin.deleteTable(tn);
        System.out.println("Table '" + tableName + "' deleted successfully.");
    }
    
    /**
     * Creates a new namespace in HBase.
     * @param namespaceName The name of the namespace to create
     */
    public static void createNamespace(String namespaceName) {
        try {
            NamespaceDescriptor nsDescriptor = NamespaceDescriptor.create(namespaceName).build();
            hbaseAdmin.createNamespace(nsDescriptor);
            System.out.println("Namespace '" + namespaceName + "' created successfully.");
        } catch (NamespaceExistException e) {
            System.out.println("Namespace '" + namespaceName + "' already exists.");
        } catch (IOException e) {
            throw new RuntimeException("Failed to create namespace: " + namespaceName, e);
        }
    }
    
    /**
     * Inserts or updates a cell value in the specified table.
     * @param tableName The target table name
     * @param rowKey The row identifier
     * @param columnFamily The column family name
     * @param columnQualifier The column qualifier name
     * @param cellValue The value to store
     */
    public static void upsertCell(String tableName, String rowKey, String columnFamily, 
                                  String columnQualifier, String cellValue) throws IOException {
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Put rowMutation = new Put(Bytes.toBytes(rowKey));
            rowMutation.addColumn(
                Bytes.toBytes(columnFamily),
                Bytes.toBytes(columnQualifier),
                Bytes.toBytes(cellValue)
            );
            table.put(rowMutation);
        }
    }
    
    /**
     * Retrieves a specific row from the table.
     * @param tableName The source table name
     * @param rowKey The row identifier to retrieve
     * @return The Result object containing the retrieved data
     */
    public static Result fetchRow(String tableName, String rowKey) throws IOException {
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Get rowQuery = new Get(Bytes.toBytes(rowKey));
            return table.get(rowQuery);
        }
    }
    
    /**
     * Retrieves a specific cell from a row.
     * @param tableName The source table name
     * @param rowKey The row identifier
     * @param columnFamily The column family
     * @param columnQualifier The column qualifier
     * @return The Result object containing the cell data
     */
    public static Result fetchCell(String tableName, String rowKey, String columnFamily,
                                   String columnQualifier) throws IOException {
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Get cellQuery = new Get(Bytes.toBytes(rowKey));
            cellQuery.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnQualifier));
            return table.get(cellQuery);
        }
    }
    
    /**
     * Scans a table and returns results within a specified row key range.
     * @param tableName The table to scan
     * @param startRow Starting row key (inclusive)
     * @param stopRow Ending row key (exclusive)
     * @return ResultScanner containing matched rows
     */
    public static ResultScanner scanRange(String tableName, String startRow, String stopRow) 
            throws IOException {
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Scan rangeScan = new Scan(Bytes.toBytes(startRow), Bytes.toBytes(stopRow));
            rangeScan.setMaxVersions(1);
            return table.getScanner(rangeScan);
        }
    }
    
    /**
     * Removes a row from the specified table.
     * @param tableName The target table name
     * @param rowKey The row identifier to delete
     */
    public static void deleteRow(String tableName, String rowKey) throws IOException {
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Delete rowDeletion = new Delete(Bytes.toBytes(rowKey));
            table.delete(rowDeletion);
        }
    }
    
    /**
     * Formats and prints cell data from a Result object.
     * @param result The Result object to print
     */
    public static void printResult(Result result) {
        for (Cell cell : result.rawCells()) {
            System.out.printf("Row: %s, Family: %s, Qualifier: %s, Value: %s%n",
                Bytes.toString(CellUtil.cloneRow(cell)),
                Bytes.toString(CellUtil.cloneFamily(cell)),
                Bytes.toString(CellUtil.cloneQualifier(cell)),
                Bytes.toString(CellUtil.cloneValue(cell))
            );
        }
    }
    
    /**
     * Cleans up HBase connection resources.
     */
    public static void shutdown() {
        try {
            if (hbaseAdmin != null) {
                hbaseAdmin.close();
            }
            if (hbaseConnection != null) {
                hbaseConnection.close();
            }
        } catch (IOException e) {
            System.err.println("Error closing HBase connections: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) throws IOException {
        // Example operations
        System.out.println("Checking table existence...");
        System.out.println("Table exists: " + tableExists("user_profile"));
        
        // Create namespace
        createNamespace("analytics");
        
        // Create table with column families
        createTable("user_profile", "demographics", "preferences");
        
        // Insert sample data
        upsertCell("user_profile", "user_1001", "demographics", "name", "John Smith");
        upsertCell("user_profile", "user_1001", "demographics", "age", "32");
        upsertCell("user_profile", "user_1001", "preferences", "theme", "dark");
        
        // Retrieve and display data
        System.out.println("\nFetching single row:");
        Result userData = fetchRow("user_profile", "user_1001");
        printResult(userData);
        
        System.out.println("\nPerforming range scan:");
        try (ResultScanner scanner = scanRange("user_profile", "user_1000", "user_1002")) {
            for (Result row : scanner) {
                printResult(row);
            }
        }
        
        // Cleanup
        shutdown();
    }
}

Thread-Safe HBase Connection Utility

The following implemantation uses ThreadLocal to manage HBase connections, ensuring each thread has its own isolated connection instance. This approach provides better thread safety and connection reuse in multi-threaded environments.

package com.bigdata.hbase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.Optional;

/**
 * Thread-safe HBase utility class using ThreadLocal for connection management.
 * Provides convenient methods for common HBase operations.
 */
public class HBaseConnectionFactory {
    
    private static final ThreadLocal<Connection> connectionRegistry = new ThreadLocal<>();
    private static final String ZOOKEEPER_HOSTS = "node1,node2,node3";
    private static final int ZOOKEEPER_CLIENT_PORT = 2181;
    
    /**
     * Establishes a connection to HBase for the current thread.
     * @return The active HBase connection
     */
    public static Connection getConnection() throws IOException {
        Connection existingConnection = connectionRegistry.get();
        
        if (existingConnection == null || existingConnection.isClosed()) {
            Configuration config = HBaseConfiguration.create();
            config.set("hbase.zookeeper.quorum", ZOOKEEPER_HOSTS);
            config.set("hbase.zookeeper.property.clientPort", String.valueOf(ZOOKEEPER_CLIENT_PORT));
            
            existingConnection = ConnectionFactory.createConnection(config);
            connectionRegistry.set(existingConnection);
        }
        
        return existingConnection;
    }
    
    /**
     * Releases the connection for the current thread.
     */
    public static void releaseConnection() throws IOException {
        Connection conn = connectionRegistry.get();
        if (conn != null) {
            conn.close();
            connectionRegistry.remove();
        }
    }
    
    /**
     * Inserts or updates a row in the specified table.
     */
    public static void putRow(String tableName, String rowKey, String family, 
                              String column, String value) throws IOException {
        try (Connection conn = getConnection();
             Table table = conn.getTable(TableName.valueOf(tableName))) {
            
            Put rowData = new Put(Bytes.toBytes(rowKey));
            rowData.addColumn(Bytes.toBytes(family), Bytes.toBytes(column), 
                            Bytes.toBytes(value));
            table.put(rowData);
        }
    }
    
    /**
     * Creates a table with a single column family.
     */
    public static void createTable(String tableName, String family) throws IOException {
        createTable(tableName, new String[]{family});
    }
    
    /**
     * Creates a table with multiple column families.
     */
    public static void createTable(String tableName, String[] families) throws IOException {
        try (Connection conn = getConnection();
             Admin admin = conn.getAdmin()) {
            
            TableDescriptorBuilder tableBuilder = TableDescriptorBuilder
                    .newBuilder(TableName.valueOf(tableName));
            
            for (String family : families) {
                ColumnFamilyDescriptor colDesc = ColumnFamilyDescriptorBuilder
                        .newBuilder(Bytes.toBytes(family))
                        .setMaxVersions(3)
                        .build();
                tableBuilder.setColumnFamily(colDesc);
            }
            
            admin.createTable(tableBuilder.build());
        }
    }
    
    /**
     * Retrieves a row by its key.
     * @return Optional containing the Result if found, empty otherwise
     */
    public static Optional<Result> getByRowKey(String tableName, String rowKey) 
            throws IOException {
        try (Connection conn = getConnection();
             Table table = conn.getTable(TableName.valueOf(tableName))) {
            
            Get rowQuery = new Get(Bytes.toBytes(rowKey));
            Result result = table.get(rowQuery);
            
            return result.isEmpty() ? Optional.empty() : Optional.of(result);
        }
    }
    
    /**
     * Retrieves a specific column value from a row.
     */
    public static Optional<Result> getColumn(String tableName, String rowKey, 
                                             String family, String column) throws IOException {
        try (Connection conn = getConnection();
             Table table = conn.getTable(TableName.valueOf(tableName))) {
            
            Get columnQuery = new Get(Bytes.toBytes(rowKey));
            columnQuery.addColumn(Bytes.toBytes(family), Bytes.toBytes(column));
            Result result = table.get(columnQuery);
            
            return result.isEmpty() ? Optional.empty() : Optional.of(result);
        }
    }
    
    /**
     * Prints formatted cell data from a Result.
     */
    public static void displayResult(Result result) {
        for (Cell cell : result.rawCells()) {
            System.out.println(String.format(
                "RowKey: %s | Family: %s | Column: %s | Value: %s",
                Bytes.toString(CellUtil.cloneRow(cell)),
                Bytes.toString(CellUtil.cloneFamily(cell)),
                Bytes.toString(CellUtil.cloneQualifier(cell)),
                Bytes.toString(CellUtil.cloneValue(cell))
            ));
        }
    }
    
    /**
     * Removes a table from HBase if it exists.
     */
    public static void deleteTable(String tableName) throws IOException {
        try (Connection conn = getConnection();
             Admin admin = conn.getAdmin()) {
            
            TableName tn = TableName.valueOf(tableName);
            if (admin.tableExists(tn)) {
                if (admin.isTableEnabled(tn)) {
                    admin.disableTable(tn);
                }
                admin.deleteTable(tn);
            }
        }
    }
    
    /**
     * Checks if a table exists in HBase.
     */
    public static boolean tableExists(String tableName) throws IOException {
        try (Connection conn = getConnection();
             Admin admin = conn.getAdmin()) {
            return admin.tableExists(TableName.valueOf(tableName));
        }
    }
}

Comprehensive HBase Utility with Advanced Features

This utility class provides advanced operations including namespace management, filtering capabilities, and comprehensive data access patterns. It demonstrates proper resource management and error handling.

package com.bigdata.hbase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.*;

/**
 * Comprehensive HBase utility class supporting:
 * - Connection lifecycle management
 * - Namespace operations
 * - Table DDL operations
 * - Advanced filtering capabilities
 * - Row scan operations
 */
public class HBaseDataAccessLayer {
    
    private static Configuration hbaseConfig;
    private static Connection hbaseConnection;
    private static Admin hbaseAdmin;
    
    private static final String ROOT_DIR = "hdfs://node1:9000/hbase";
    private static final String ZK_QUORUM = "node1,node2,node3";
    
    /**
     * Initializes HBase connection with specified configuration.
     */
    public static synchronized void connect() {
        if (hbaseConnection == null || hbaseConnection.isClosed()) {
            hbaseConfig = HBaseConfiguration.create();
            hbaseConfig.set("hbase.rootdir", ROOT_DIR);
            
            try {
                hbaseConnection = ConnectionFactory.createConnection(hbaseConfig);
                hbaseAdmin = hbaseConnection.getAdmin();
            } catch (IOException e) {
                throw new RuntimeException("HBase connection initialization failed", e);
            }
        }
    }
    
    /**
     * Closes all HBase resources.
     */
    public static synchronized void disconnect() {
        try {
            if (hbaseAdmin != null) {
                hbaseAdmin.close();
            }
            if (hbaseConnection != null && !hbaseConnection.isClosed()) {
                hbaseConnection.close();
            }
        } catch (IOException e) {
            System.err.println("Error during HBase disconnection: " + e.getMessage());
        }
    }
    
    // ==================== Namespace Operations ====================
    
    /**
     * Creates a new namespace in HBase.
     */
    public static void createNamespace(String namespace) throws IOException {
        connect();
        NamespaceDescriptor nsConfig = NamespaceDescriptor.create(namespace).build();
        hbaseAdmin.createNamespace(nsConfig);
    }
    
    /**
     * Lists all namespaces in the cluster.
     */
    public static List<String> listAllNamespaces() throws IOException {
        connect();
        NamespaceDescriptor[] namespaces = hbaseAdmin.listNamespaceDescriptors();
        List<String> namespaceList = new ArrayList<>();
        
        for (NamespaceDescriptor nd : namespaces) {
            namespaceList.add(nd.getName());
        }
        
        return namespaceList;
    }
    
    /**
     * Lists all tables within a specific namespace.
     */
    public static List<String> listTablesInNamespace(String namespace) throws IOException {
        connect();
        HTableDescriptor[] tables = hbaseAdmin.listTableDescriptorsByNamespace(namespace);
        List<String> tableList = new ArrayList<>();
        
        for (HTableDescriptor table : tables) {
            tableList.add(table.getTableName().getNameAsString());
        }
        
        return tableList;
    }
    
    /**
     * Removes a namespace from HBase.
     */
    public static boolean removeNamespace(String namespace) {
        connect();
        try {
            hbaseAdmin.deleteNamespace(namespace);
            return true;
        } catch (IOException e) {
            System.err.println("Failed to delete namespace: " + e.getMessage());
            return false;
        }
    }
    
    // ==================== Table Operations ====================
    
    /**
     * Creates a table with specified column families.
     */
    public static void createTable(String tableName, String[] columnFamilies) throws IOException {
        connect();
        TableName tn = TableName.valueOf(tableName);
        
        if (hbaseAdmin.tableExists(tn)) {
            System.out.println("Table already exists: " + tableName);
            return;
        }
        
        TableDescriptorBuilder tableBuilder = TableDescriptorBuilder.newBuilder(tn);
        
        for (String cf : columnFamilies) {
            ColumnFamilyDescriptor colFamily = ColumnFamilyDescriptorBuilder
                    .newBuilder(Bytes.toBytes(cf))
                    .setMaxVersions(3)
                    .build();
            tableBuilder.setColumnFamily(colFamily);
        }
        
        hbaseAdmin.createTable(tableBuilder.build());
    }
    
    /**
     * Retrieves column families for a specific table.
     */
    public static List<String> getColumnFamilies(String tableName) throws IOException {
        connect();
        HTableDescriptor tableDesc = hbaseAdmin.getTableDescriptor(
                TableName.valueOf(tableName));
        
        List<String> families = new ArrayList<>();
        for (ColumnFamilyDescriptor cf : tableDesc.getColumnFamilies()) {
            families.add(cf.getNameAsString());
        }
        
        return families;
    }
    
    /**
     * Removes a column family from a table.
     */
    public static boolean removeColumnFamily(String tableName, String familyName) {
        connect();
        try {
            hbaseAdmin.deleteColumn(TableName.valueOf(tableName), 
                    Bytes.toBytes(familyName));
            return true;
        } catch (IOException e) {
            System.err.println("Failed to delete column family: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * Drops a table from HBase.
     */
    public static boolean dropTable(String tableName) {
        connect();
        try {
            TableName tn = TableName.valueOf(tableName);
            
            if (!hbaseAdmin.tableExists(tn)) {
                System.out.println("Table does not exist: " + tableName);
                return false;
            }
            
            if (hbaseAdmin.isTableEnabled(tn)) {
                hbaseAdmin.disableTable(tn);
            }
            hbaseAdmin.deleteTable(tn);
            return true;
        } catch (IOException e) {
            System.err.println("Failed to delete table: " + e.getMessage());
            return false;
        }
    }
    
    // ==================== Data Operations ====================
    
    /**
     * Inserts or updates a cell value.
     */
    public static boolean putCell(String tableName, String rowKey, String family, 
                                  String column, String value) {
        connect();
        
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Put rowData = new Put(Bytes.toBytes(rowKey));
            rowData.addColumn(Bytes.toBytes(family), Bytes.toBytes(column), 
                            Bytes.toBytes(value));
            table.put(rowData);
            return true;
        } catch (IOException e) {
            System.err.println("Failed to insert data: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * Deletes a row from the table.
     */
    public static boolean deleteRow(String tableName, String rowKey) {
        connect();
        
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Delete rowDelete = new Delete(Bytes.toBytes(rowKey));
            table.delete(rowDelete);
            return true;
        } catch (IOException e) {
            System.err.println("Failed to delete row: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * Retrieves a complete row by its key.
     */
    public static void getRow(String tableName, String rowKey, String family, 
                              String column) throws IOException {
        connect();
        
        try (Table table = hbaseConnection.getTable(TableName.valueOf(tableName))) {
            Get rowQuery = new Get(Bytes.toBytes(rowKey));
            
            if (family != null && column != null) {
                rowQuery.addColumn(Bytes.toBytes(family), Bytes.toBytes(column));
            }
            
            Result result = table.get(rowQuery);
            
            if (result.isEmpty()) {
                System.out.println("No data found for row: " + rowKey);
                return;
            }
            
            for (Cell cell : result.rawCells()) {
                System.out.println(String.format(
                    "%s:%s.%s = %s",
                    Bytes.toString(CellUtil.cloneRow(cell)),
                    Bytes.toString(CellUtil.cloneFamily(cell)),
                    Bytes.toString(CellUtil.cloneQualifier(cell)),
                    Bytes.toString(CellUtil.cloneValue(cell))
                ));
            }
        }
    }
    
    /**
     * Performs a full table scan.
     * @return Iterator over Result objects
     */
    public static Iterator<Result> scanTable(String tableName) throws IOException {
        connect();
        
        Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
        Scan fullScan = new Scan();
        return table.getScanner(fullScan).iterator();
    }
    
    /**
     * Creates a single column value filter.
     */
    public static SingleColumnValueFilter createColumnFilter(
            String family, String qualifier, CompareFilter.CompareOp operator, 
            String value, boolean filterIfMissing) {
        
        SingleColumnValueFilter filter = new SingleColumnValueFilter(
            Bytes.toBytes(family),
            Bytes.toBytes(qualifier),
            operator,
            Bytes.toBytes(value)
        );
        filter.setFilterIfMissing(filterIfMissing);
        return filter;
    }
    
    /**
     * Applies a filter list to scan results.
     * @param tableName The table to scan
     * @param operator FilterList.Operator (MUST_PASS_ALL or MUST_PASS_ONE)
     * @param filters Array of filters to apply
     * @return Iterator of filtered results
     */
    public static Iterator<Result> filterScan(String tableName, 
                                              FilterList.Operator operator,
                                              SingleColumnValueFilter... filters) 
            throws IOException {
        
        connect();
        
        FilterList filterList = new FilterList(operator);
        for (SingleColumnValueFilter filter : filters) {
            filterList.addFilter(filter);
        }
        
        Scan filteredScan = new Scan();
        filteredScan.setFilter(filterList);
        
        Table table = hbaseConnection.getTable(TableName.valueOf(tableName));
        return table.getScanner(filteredScan).iterator();
    }
    
    /**
     * Displays results from a Result iterator.
     */
    public static void displayResults(Iterator<Result> results) {
        while (results.hasNext()) {
            Result result = results.next();
            
            for (Cell cell : result.rawCells()) {
                System.out.println(String.format(
                    "%s:%s.%s = %s",
                    Bytes.toString(CellUtil.cloneRow(cell)),
                    Bytes.toString(CellUtil.cloneFamily(cell)),
                    Bytes.toString(CellUtil.cloneQualifier(cell)),
                    Bytes.toString(CellUtil.cloneValue(cell))
                ));
            }
            System.out.println("---");
        }
    }
    
    public static void main(String[] args) throws IOException {
        // Initialize connection
        connect();
        
        // Create sample table
        String tableName = "product_inventory";
        String[] columnFamilies = {"details", "pricing", "stock"};
        
        createTable(tableName, columnFamilies);
        
        // Insert sample data
        putCell(tableName, "SKU_001", "details", "name", "Wireless Headphones");
        putCell(tableName, "SKU_001", "details", "brand", "AudioTech");
        putCell(tableName, "SKU_001", "pricing", "retail", "149.99");
        putCell(tableName, "SKU_001", "stock", "quantity", "250");
        
        putCell(tableName, "SKU_002", "details", "name", "USB-C Cable");
        putCell(tableName, "SKU_002", "pricing", "retail", "19.99");
        putCell(tableName, "SKU_002", "stock", "quantity", "1000");
        
        // Retrieve and display data
        System.out.println("Retrieving product details:");
        getRow(tableName, "SKU_001", null, null);
        
        System.out.println("\nFull table scan:");
        displayResults(scanTable(tableName));
        
        System.out.println("\nFiltered results (stock > 500):");
        SingleColumnValueFilter stockFilter = createColumnFilter(
            "stock", "quantity", CompareFilter.CompareOp.GREATER, "500", true);
        
        Iterator<Result> filteredResults = filterScan(tableName, 
                FilterList.Operator.MUST_PASS_ALL, stockFilter);
        displayResults(filteredResults);
        
        // Cleanup
        disconnect();
    }
}

Configuration Notes

When connecting to a distributed HBase cluster, ensure your hbase-site.xml contains the appropriate Zookeeper quorum configuration. The Java client should be able to reach all Zookeeper nodes specified in the quorum list.

Key configuration properties include:

  • hbase.zookeeper.quorum: Comma-separated list of Zookeeper hostnames
  • hbase.zookeeper.property.clientPort: Zookeeper client port (default: 2181)
  • hbase.rootdir: HBase root directory in HDFS

For production deployments, consider using connection timeout settings and appropriate retry policies to handle network partition scenarios gracefully.

Tags: Apache HBase Apache Zookeeper IntelliJ IDEA java Maven

Posted on Wed, 21 Oct 2026 16:43:30 +0000 by kutyadog