Configuration
B-PIPE, SAPI, failover servers, TLS, ZFP, SOCKS5, auth, timeouts, pools, sharding, and logging.
Java quickstart
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.
| Entry point | Returns | When the session starts |
|---|---|---|
Xbbg.configure(config) or Xbbg.configure(host, port) | EngineConfig | On 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() | Engine | Immediately, blocking the calling thread via Xbbg.await(Engine.connect(...)) until sessions are up |
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.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.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.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.@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).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");
}
}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:
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);
}
}
}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:
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));
}
}Subscription implements Iterable<Tick> and AutoCloseable. Closing the subscription (or exiting a try-with-resources block) unsubscribes cleanly:
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;
}
}
}
}
}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:
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");
}
});
}
}
}Engine and Bloomberg failures throw unchecked BlpException subclasses. Note that BlpLimitException extends BlpRequestException, so catch BlpLimitException before BlpRequestException:
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 class | BlpErrorKind | Raised for |
|---|---|---|
BlpException | — | Abstract base class of every engine and Bloomberg exception; exposes kind(), code(), bloombergRequestId(), and bloombergRequestIds(). |
BlpSessionException | SESSION | Session startup, connection, service-open, and worker failures. |
BlpRequestException | REQUEST | Bloomberg request failures and onDelayed = DelayedPolicy.RAISE; exposes service(), operation(), and requestId(). |
BlpLimitException | LIMIT | Bloomberg capacity and usage limit responses (LIMIT, DAILY_CAPACITY_REACHED); extends BlpRequestException. |
BlpValidationException | VALIDATION | Invalid configuration, request, or subscription input; exposes element() and suggestion(). |
BlpTimeoutException | TIMEOUT | Request or identity timeouts (requestTimeoutMs); exposes requestId(). |
BlpSubscriptionDataLossException | DATALOSS | Terminal subscription data loss (code() is "DATALOSS"); exposes topic() and detail(). |
BlpInternalException | INTERNAL | Engine-internal, provisioning network/integrity, or native contract failures. |
BlpapiNotFoundException | SDK_NOT_FOUND | No 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.
B-PIPE, SAPI, failover servers, TLS, ZFP, SOCKS5, auth, timeouts, pools, sharding, and logging.
Table, Column, RowsResult, Arrow IPC, and Arrow Java vectors.
Real-time subscriptions, boards, gap-aware deliveries, and XbbgFlow.
Higher-level fixed income, futures, CDX, ETF, auction, and entitlement workflows.