Skip to content

Java quickstart

From install to first Bloomberg data.

Connect, request reference, historical, bulk, intraday, and BQL data, compose asynchronous futures, stream real-time ticks, and handle typed errors with io.github.underloam:xbbg.

WARNING

Every request needs a reachable Bloomberg endpoint and entitlements for the data requested. The examples use a Desktop API session on localhost:8194.

Choose how to connect ​

Entry pointReturnsWhen the session starts
Xbbg.configure(config) or Xbbg.configure(host, port)EngineConfigOn the first Blp.* or Xbbg.engine() call, asynchronously on native worker threads
Engine.connect(config) or Xbbg.connect(config)CompletableFuture<Engine>Immediately, asynchronously on native worker threads
Engine.open(config), Engine.open(host, port), or Engine.open()EngineImmediately, blocking the calling thread via Xbbg.await(Engine.connect(...)) until sessions are up
  • The static methods on Blp (Blp.bdp, Blp.bdh, Blp.bds, Blp.bdib, Blp.bdtick, Blp.delayStatus, Blp.subscribe, ...) run on a process-wide shared engine configured with Xbbg.configure(...). Without Xbbg.configure(...), the shared engine connects to localhost:8194 on first use.
  • Engine implements AutoCloseable. Dedicated Engine instances (Engine.open(...) or Engine.connect(...)) also expose bql, beqs, bsrch, bta, bflds, fieldInfo, fieldSearch, blkp, bport, bcurves, bgovts, generic request, schema introspection, entitlement checks, and analytics recipes.
  • Every network operation returns a CompletableFuture. Xbbg.await(future) blocks for the result and rethrows the underlying unchecked BlpException (or IllegalArgumentException) directly rather than wrapping it in CompletionException. Because native calls never block inside a JNI frame, calling Xbbg.await(...) on a Java 21+ virtual thread unmounts the virtual thread without pinning its carrier.

Reference, historical, and bulk data ​

java
import io.github.underloam.xbbg.BdhOptions;
import io.github.underloam.xbbg.BdsOptions;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.EngineConfig;
import io.github.underloam.xbbg.KeyColumn;
import io.github.underloam.xbbg.Overrides;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.Row;
import io.github.underloam.xbbg.table.Table;
import java.time.LocalDate;
import java.util.Arrays;

public class RefHistBulkExample {
  public static void main(String[] args) {
    Xbbg.configure(
        EngineConfig.builder()
            .host("localhost")
            .port(8194)
            .keyColumn(KeyColumn.SECURITY)
            .build());

    // Reference data (BDP)
    Table ref =
        Xbbg.await(
            Blp.bdp(
                Arrays.asList("AAPL US Equity", "MSFT US Equity"),
                Arrays.asList("PX_LAST", "SECURITY_NAME")));
    for (Row row : ref) {
      System.out.println(
          row.getString("security")
              + " "
              + row.getString("field")
              + " = "
              + row.get("value"));
    }

    // Historical data (BDH) with java.time LocalDate options
    Table hist =
        Xbbg.await(
            Blp.bdh(
                "SPX Index",
                Arrays.asList("PX_LAST", "PX_VOLUME"),
                BdhOptions.builder()
                    .start(LocalDate.of(2024, 1, 1))
                    .end(LocalDate.of(2024, 12, 31))
                    .build()));

    // Bulk data (BDS) with a Bloomberg field override
    Table dividends =
        Xbbg.await(
            Blp.bds(
                "AAPL US Equity",
                "DVD_Hist_All",
                BdsOptions.builder()
                    .overrides(Overrides.of("DVD_Start_Dt", LocalDate.of(2024, 1, 1)))
                    .build()));

    System.out.println("Historical rows: " + hist.numRows() + ", Dividend rows: " + dividends.numRows());
  }
}
  • Blp methods accept either a single String or a Collection<String> for tickers and fields. On Engine, bdp, bdh, and bds take Collection<String> for both.
  • By default, results name the security identifier column ticker, which is deprecated because it collides with Bloomberg's TICKER field when names are case-folded. Set .keyColumn(KeyColumn.SECURITY) on EngineConfig.builder() to use security now.
  • Unlike @xbbg/core, the Java API does not duplicate methods under a* prefixes (abdp, abdh, abdib, abdtick). Instead, every method returns a CompletableFuture, and date/interval parameters are set on the immutable option builders (BdhOptions, BdibOptions, BdtickOptions, BdsOptions).

Intraday bars and ticks ​

java
import io.github.underloam.xbbg.BdibOptions;
import io.github.underloam.xbbg.BdtickOptions;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.Table;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;

public class IntradayExample {
  public static void main(String[] args) {
    // 5-minute TRADE bars over a window in New York time
    Table bars =
        Xbbg.await(
            Blp.bdib(
                "AAPL US Equity",
                BdibOptions.builder()
                    .start(LocalDateTime.of(2024, 12, 2, 9, 30))
                    .end(LocalDateTime.of(2024, 12, 2, 16, 0))
                    .interval(5)
                    .requestTz("America/New_York")
                    .build()));

    // Full calendar day of 5-minute bars (equivalent to JS blp.abdib(ticker, dt, 5))
    Table fullDayBars =
        Xbbg.await(
            Blp.bdib(
                "AAPL US Equity",
                BdibOptions.builder()
                    .day(LocalDate.of(2024, 12, 2))
                    .interval(5)
                    .requestTz("America/New_York")
                    .build()));

    // Intraday ticks for TRADE, BID, and ASK
    Table ticks =
        Xbbg.await(
            Blp.bdtick(
                "AAPL US Equity",
                BdtickOptions.builder()
                    .start("2024-12-02T09:30:00")
                    .end("2024-12-02T09:35:00")
                    .eventTypes(Arrays.asList("TRADE", "BID", "ASK"))
                    .includeConditionCodes(true)
                    .requestTz("America/New_York")
                    .build()));

    System.out.println(bars.numRows() + " bars, " + fullDayBars.numRows() + " full-day bars, " + ticks.numRows() + " ticks");
  }
}

Explicit Engine and BQL ​

Use try (Engine engine = Engine.open(config)) (or Engine.connect(config) for non-blocking startup) when you want an isolated engine lifecycle or need bql, beqs, bsrch, bta, field/schema introspection, or analytics recipes:

java
import io.github.underloam.xbbg.BdpOptions;
import io.github.underloam.xbbg.BqlOptions;
import io.github.underloam.xbbg.Engine;
import io.github.underloam.xbbg.EngineConfig;
import io.github.underloam.xbbg.Format;
import io.github.underloam.xbbg.KeyColumn;
import io.github.underloam.xbbg.Overrides;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.Table;
import java.util.Arrays;
import java.util.Collections;

public class EngineAndBqlExample {
  public static void main(String[] args) {
    EngineConfig config =
        EngineConfig.builder()
            .host("localhost")
            .port(8194)
            .keyColumn(KeyColumn.SECURITY)
            .build();

    try (Engine engine = Engine.open(config)) {
      // BDP with global and per-security overrides
      Overrides overrides =
          Overrides.of("EQY_FUND_CRNCY", "USD")
              .forSecurity("AAPL US Equity", Overrides.of("EQY_FUND_CRNCY", "EUR"))
              .forSecurity("MSFT US Equity", Overrides.of("EQY_FUND_CRNCY", "JPY"));

      Table ref =
          Xbbg.await(
              engine.bdp(
                  Arrays.asList("AAPL US Equity", "MSFT US Equity"),
                  Collections.singletonList("CRNCY_ADJ_PX_LAST"),
                  BdpOptions.builder()
                      .overrides(overrides)
                      .format(Format.SEMI_LONG)
                      .build()));

      // Bloomberg Query Language (BQL)
      Table bql =
          Xbbg.await(
              engine.bql(
                  "get(px_last) for('AAPL US Equity')",
                  BqlOptions.builder().appName("portfolio-service").build()));

      // Field metadata search
      Table fields = Xbbg.await(engine.fieldSearch("vwap"));

      System.out.println(ref + " / " + bql + " / " + fields);
    }
  }
}

Asynchronous CompletableFuture composition ​

Every request and recipe method returns a CompletableFuture that completes on Xbbg.callbackExecutor(). You can run independent requests concurrently and combine them without blocking threads:

java
import io.github.underloam.xbbg.BdhOptions;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.Table;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;

public class AsyncExample {
  public static void main(String[] args) {
    CompletableFuture<Table> refFuture =
        Blp.bdp(Arrays.asList("AAPL US Equity", "MSFT US Equity"), "PX_LAST");

    CompletableFuture<Table> histFuture =
        Blp.bdh(
            "SPX Index",
            "PX_LAST",
            BdhOptions.builder().start("2024-01-01").end("2024-12-31").build());

    CompletableFuture<String> summary =
        refFuture.thenCombine(
            histFuture,
            (ref, hist) -> "Ref rows=" + ref.numRows() + ", Hist rows=" + hist.numRows());

    System.out.println(Xbbg.await(summary));
  }
}

Real-time subscriptions ​

Subscription implements Iterable<Tick> and AutoCloseable. Closing the subscription (or exiting a try-with-resources block) unsubscribes cleanly:

java
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.subscription.FieldHandle;
import io.github.underloam.xbbg.subscription.Subscription;
import io.github.underloam.xbbg.subscription.Tick;
import java.util.Arrays;

public class SubscribeExample {
  public static void main(String[] args) {
    try (Subscription sub =
        Xbbg.await(
            Blp.subscribe(
                Arrays.asList("AAPL US Equity", "MSFT US Equity"),
                Arrays.asList("LAST_PRICE", "BID", "ASK")))) {
      FieldHandle lastPrice = sub.field("LAST_PRICE");
      int count = 0;
      for (Tick tick : sub) {
        if (tick.has(lastPrice)) {
          System.out.println(
              tick.topic()
                  + " @ "
                  + tick.timestampUs()
                  + " LAST_PRICE="
                  + tick.getDouble(lastPrice));
        }
        if (++count >= 10) {
          break;
        }
      }
    }
  }
}

Java 17+ add-on (io.github.underloam:xbbg-jdk17) ​

With io.github.underloam:xbbg-jdk17, you can route callbacks onto virtual threads (Java 21+), publish subscriptions as java.util.concurrent.Flow.Publishers, and use sealed interfaces (TickValue, DeliveryView, ErrorKind) for exhaustive pattern matching:

java
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.jdk17.ErrorKind;
import io.github.underloam.xbbg.jdk17.Errors;
import io.github.underloam.xbbg.jdk17.TickValue;
import io.github.underloam.xbbg.jdk17.TickValues;
import io.github.underloam.xbbg.jdk17.VirtualThreads;
import io.github.underloam.xbbg.jdk17.XbbgFlow;
import io.github.underloam.xbbg.subscription.Subscription;
import io.github.underloam.xbbg.subscription.Tick;
import java.util.Arrays;
import java.util.concurrent.Flow;

public class Jdk17QuickstartExample {
  public static void main(String[] args) {
    // Complete xbbg futures on virtual threads when running on Java 21+
    VirtualThreads.useForCallbacks();

    try (Subscription sub =
        Xbbg.await(
            Blp.subscribe(
                Arrays.asList("AAPL US Equity"),
                Arrays.asList("LAST_PRICE", "BID", "ASK")))) {
      Flow.Publisher<Tick> publisher = XbbgFlow.ticks(sub);
      publisher.subscribe(
          new Flow.Subscriber<Tick>() {
            private Flow.Subscription subscription;

            @Override
            public void onSubscribe(Flow.Subscription s) {
              this.subscription = s;
              s.request(1);
            }

            @Override
            public void onNext(Tick tick) {
              TickValues.get(tick, "LAST_PRICE")
                  .ifPresent(
                      val -> {
                        if (val instanceof TickValue.DoubleValue d) {
                          System.out.println(tick.topic() + " price=" + d.value());
                        } else if (val instanceof TickValue.Cleared) {
                          System.out.println(tick.topic() + " price cleared");
                        }
                      });
              subscription.cancel();
            }

            @Override
            public void onError(Throwable throwable) {
              ErrorKind kind = Errors.classify(throwable);
              System.err.println("Stream failed: " + kind);
            }

            @Override
            public void onComplete() {
              System.out.println("Stream completed");
            }
          });
    }
  }
}

Handle errors ​

Engine and Bloomberg failures throw unchecked BlpException subclasses. Note that BlpLimitException extends BlpRequestException, so catch BlpLimitException before BlpRequestException:

java
import io.github.underloam.xbbg.BlpException;
import io.github.underloam.xbbg.BlpLimitException;
import io.github.underloam.xbbg.BlpRequestException;
import io.github.underloam.xbbg.BlpSessionException;
import io.github.underloam.xbbg.BlpTimeoutException;
import io.github.underloam.xbbg.BlpValidationException;
import io.github.underloam.xbbg.Engine;
import io.github.underloam.xbbg.EngineConfig;
import io.github.underloam.xbbg.Xbbg;
import java.util.Collections;

public class ErrorHandlingExample {
  public static void main(String[] args) {
    EngineConfig config = EngineConfig.builder().requestTimeoutMs(60_000).build();

    try (Engine engine = Engine.open(config)) {
      Xbbg.await(
          engine.bdp(
              Collections.singletonList("AAPL US Equity"),
              Collections.singletonList("PX_LAST")));
    } catch (BlpLimitException e) {
      System.err.println("Capacity limit reached: " + e.getMessage());
    } catch (BlpRequestException e) {
      System.err.println(
          "Request failed: service="
              + e.service().orElse("")
              + " op="
              + e.operation().orElse("")
              + " code="
              + e.code()
              + " supportIds="
              + e.bloombergRequestIds());
    } catch (BlpTimeoutException e) {
      System.err.println("Timed out: " + e.bloombergRequestIds());
    } catch (BlpValidationException e) {
      System.err.println(
          "Invalid input: element=" + e.element().orElse("") + " suggestion=" + e.suggestion().orElse(""));
    } catch (BlpSessionException e) {
      System.err.println("Session error: " + e.getMessage());
    } catch (BlpException e) {
      System.err.println(e.kind() + " [" + e.code() + "]: " + e.getMessage());
    }
  }
}
Exception classBlpErrorKindRaised for
BlpException—Abstract base class of every engine and Bloomberg exception; exposes kind(), code(), bloombergRequestId(), and bloombergRequestIds().
BlpSessionExceptionSESSIONSession startup, connection, service-open, and worker failures.
BlpRequestExceptionREQUESTBloomberg request failures and onDelayed = DelayedPolicy.RAISE; exposes service(), operation(), and requestId().
BlpLimitExceptionLIMITBloomberg capacity and usage limit responses (LIMIT, DAILY_CAPACITY_REACHED); extends BlpRequestException.
BlpValidationExceptionVALIDATIONInvalid configuration, request, or subscription input; exposes element() and suggestion().
BlpTimeoutExceptionTIMEOUTRequest or identity timeouts (requestTimeoutMs); exposes requestId().
BlpSubscriptionDataLossExceptionDATALOSSTerminal subscription data loss (code() is "DATALOSS"); exposes topic() and detail().
BlpInternalExceptionINTERNALEngine-internal, provisioning network/integrity, or native contract failures.
BlpapiNotFoundExceptionSDK_NOT_FOUNDNo usable Bloomberg C++ SDK runtime library was found or provisioned.

Caller argument mistakes caught in Java before calling the engine throw NullPointerException or IllegalArgumentException. Using a closed Engine or Subscription throws IllegalStateException, and cancelled operations throw CancellationException.

Next steps ​

Configuration

B-PIPE, SAPI, failover servers, TLS, ZFP, SOCKS5, auth, timeouts, pools, sharding, and logging.

Output Formats

Table, Column, RowsResult, Arrow IPC, and Arrow Java vectors.

Streaming

Real-time subscriptions, boards, gap-aware deliveries, and XbbgFlow.

Recipes

Higher-level fixed income, futures, CDX, ETF, auction, and entitlement workflows.

xbbg is independent open-source software and is not affiliated with, endorsed by, sponsored by, or approved by Bloomberg Finance L.P.