Quickstart
First requests, options, and error handling.
Output formats
A Backend<T> chooses the Java result container; a Format chooses the column layout of reference and historical results. Every request, recipe, and latest() snapshot accepts a backend.
Backend<T>) Every request, recipe, and Subscription#latest(Backend) method has an overload that returns a Table by default, and an overload that takes a Backend<T> and returns T:
| Backend | Return type T | Metadata | Description |
|---|---|---|---|
Backend.TABLE (default) | Table | Implements ResultMetadataView | Immutable columnar table backed by canonical little-endian Arrow buffers, decoded lazily on access. |
Backend.ROWS | RowsResult | Implements ResultMetadataView | Unmodifiable List<Map<String, Object>> (one map per row in column order) plus columnNames() and ResultMetadataView. |
Backend.IPC_STREAM | byte[] | In Arrow IPC schema metadata | Raw Arrow IPC stream bytes (also returned by engine.requestRaw(RequestSpec)). |
Backend.IPC_FILE | byte[] | In Arrow IPC schema metadata | Raw Arrow IPC file bytes (also returned by engine.requestIpcFile(RequestSpec)). |
Backend.map(base, name, mapper) | T | Preserved if T keeps it | Custom backend derived by applying mapper to base on the callback executor. |
ArrowBackends.vectorSchemaRoot(allocator) | VectorSchemaRoot | In root.getSchema().getCustomMetadata() | Apache Arrow Java VectorSchemaRoot (io.github.underloam:xbbg-jdk17); caller must close() the returned root. |
import io.github.underloam.xbbg.Backend;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.RowsResult;
import io.github.underloam.xbbg.table.Table;
import java.util.Map;
public class BackendsExample {
public static void main(String[] args) {
// Default: columnar Table
Table table = Xbbg.await(Blp.bdp("AAPL US Equity", "PX_LAST"));
System.out.println("Table rows: " + table.numRows());
// Row maps with metadata
RowsResult rows = Xbbg.await(Blp.bdp("AAPL US Equity", "PX_LAST", Backend.ROWS));
for (Map<String, Object> row : rows) {
System.out.println(row.get("value"));
}
// Raw Arrow IPC stream bytes
byte[] ipcStream = Xbbg.await(Blp.bdp("AAPL US Equity", "PX_LAST", Backend.IPC_STREAM));
System.out.println("IPC stream bytes: " + ipcStream.length);
}
}Table, Column, and Row Table Table implements Iterable<Row> and ResultMetadataView:
numRows(), numColumns(), columns(), columnNames(), hasColumn(name), findColumn(name) (Optional<Column>), column(index), and column(name) (throws IllegalArgumentException if absent).row(index) returns a lightweight Row view, for (Row row : table) iterates over rows, and toRows() materializes a RowsResult.Column and DataType Each Column exposes its name(), physical type() (DataType), optional timezone() (for timestamp columns), nullable(), size(), nullCount(), and toList().
Column / Row method | Applicable DataTypes | Null behavior |
|---|---|---|
isNull(row) / row.isNull(col) | Any | Returns true when the cell is null |
get(row) / row.get(col) | Any | Returns null when null; otherwise boxed Boolean, Byte/Short/Integer/Long (INT8..INT64), Short/Integer/Long/BigInteger (UINT8..UINT64), Float/Double, String, byte[], LocalDate, LocalTime, Instant (zoned timestamp), or LocalDateTime (unzoned timestamp) |
getBoolean(row) | BOOL | Throws IllegalStateException if null |
getInt(row) | INT8, INT16, INT32, UINT8, UINT16, DATE32, TIME32_S, TIME32_MS | Throws IllegalStateException if null |
getLong(row) | All integer, date, time, and timestamp types | Throws IllegalStateException if null |
getFloat(row) | FLOAT32, INT8, INT16, UINT8, UINT16 | Throws IllegalStateException if null |
getDouble(row) | All float and integer types | Throws IllegalStateException if null |
getString(row) | UTF8, LARGE_UTF8 | Returns null when null |
getBytes(row) | BINARY, LARGE_BINARY, UTF8, LARGE_UTF8 | Returns null when null |
getLocalDate(row) | DATE32, DATE64 | Returns null when null |
getLocalTime(row) | TIME32_S, TIME32_MS, TIME64_US, TIME64_NS | Returns null when null |
getInstant(row) | TIMESTAMP_S, TIMESTAMP_MS, TIMESTAMP_US, TIMESTAMP_NS | Returns null when null (unzoned timestamps are read as UTC) |
getZonedDateTime(row) | TIMESTAMP_* | Returns null when null (uses column's timezone(), or UTC if unzoned) |
getLocalDateTime(row) | TIMESTAMP_* | Returns null when null (wall-clock time in column's zone, or as stored if unzoned) |
import io.github.underloam.xbbg.BdhOptions;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Format;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.Column;
import io.github.underloam.xbbg.table.Row;
import io.github.underloam.xbbg.table.Table;
import java.util.Arrays;
public class TableIterationExample {
public static void main(String[] args) {
Table hist =
Xbbg.await(
Blp.bdh(
"SPX Index",
Arrays.asList("PX_LAST", "PX_VOLUME"),
BdhOptions.builder()
.start("2024-01-01")
.end("2024-01-31")
.format(Format.SEMI_LONG)
.build()));
// Column-oriented access (check isNull before primitive getters)
Column dates = hist.column("date");
Column pxLast = hist.column("PX_LAST");
for (int i = 0; i < hist.numRows(); i++) {
if (!pxLast.isNull(i)) {
System.out.println(dates.getLocalDate(i) + ": " + pxLast.getDouble(i));
}
}
// Row-oriented iteration
for (Row row : hist) {
Double close = row.isNull("PX_LAST") ? null : row.getDouble("PX_LAST");
System.out.println(row.getLocalDate("date") + " -> " + close);
}
}
}io.github.underloam:xbbg-jdk17) With io.github.underloam:xbbg-jdk17 and org.apache.arrow:arrow-vector plus an Arrow BufferAllocator (RootAllocator from arrow-memory-unsafe or arrow-memory-netty) on the class path, you can either receive VectorSchemaRoot directly as a request/recipe/delivery backend or convert an existing Table:
ArrowBackends.vectorSchemaRoot(BufferAllocator): reads the native Arrow IPC stream directly into a VectorSchemaRoot, transferring the first batch's buffers without copying and preserving schema custom metadata.ArrowTables.toVectorSchemaRoot(Table, BufferAllocator): copies an xbbg Table into a new VectorSchemaRoot with the same column names, Arrow types, timestamp time zones, nullability, and schema metadata.WARNING
The caller owns every VectorSchemaRoot returned by ArrowBackends.vectorSchemaRoot(...) or ArrowTables.toVectorSchemaRoot(...) and must close it before closing the BufferAllocator. On Java 17+, start the JVM with --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED.
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.jdk17.ArrowBackends;
import io.github.underloam.xbbg.jdk17.ArrowTables;
import io.github.underloam.xbbg.table.Table;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.VectorSchemaRoot;
public class ArrowInteropExample {
public static void main(String[] args) {
try (BufferAllocator allocator = new RootAllocator()) {
// 1. Stream directly into a VectorSchemaRoot via ArrowBackends
try (VectorSchemaRoot root =
Xbbg.await(
Blp.bdp(
"IBM US Equity",
"PX_LAST",
ArrowBackends.vectorSchemaRoot(allocator)))) {
System.out.println("Direct VectorSchemaRoot rows: " + root.getRowCount());
System.out.println("Schema: " + root.getSchema());
}
// 2. Or convert an existing xbbg Table into a VectorSchemaRoot
Table table = Xbbg.await(Blp.bdp("IBM US Equity", "PX_LAST"));
try (VectorSchemaRoot converted = ArrowTables.toVectorSchemaRoot(table, allocator)) {
System.out.println("Converted VectorSchemaRoot rows: " + converted.getRowCount());
}
}
}
}Format) Format controls the column layout of reference-data (bdp) and historical-data (bdh) results:
| Enum constant | Wire value | Columns |
|---|---|---|
Format.LONG (default) | "long" | ticker, field, value (all values formatted as text) |
Format.LONG_TYPED | "long_typed" | ticker, field, value_f64, value_i64, value_str, value_bool, value_date, value_ts, value_time |
Format.LONG_WITH_METADATA | "long_metadata" | ticker, field, value, dtype (text values plus each value's Arrow type name) |
Format.SEMI_LONG | "semi_long" | One row per security (bdp) or per security and date (bdh), one typed column per requested field |
With EngineConfig.Builder#keyColumn(KeyColumn.SECURITY), the first column is named security instead of the deprecated ticker default. Only bdp and bdh accept non-default formats; other operations reject format with BlpValidationException.
ResultMetadataView and ResultMetadata) Both Table and RowsResult implement ResultMetadataView, which exposes decoded response diagnostics directly on the result (and via result.resultMetadata()):
| Method | Return type | Present when |
|---|---|---|
metadata() | Map<String, String> | Always (raw Arrow schema metadata) |
bloombergRequestId() | Optional<String> | The result came from a single Bloomberg request and the SDK assigned a support RequestId |
bloombergRequestIds() | List<String> | Sorted, deduplicated list of all SDK-assigned RequestIds contributing to the result |
eidData() | Optional<Map<String, List<Integer>>> | returnEids(true) was set on bdp, bds, bdh, bdib, or bdtick |
delayed() | Optional<Map<String, DelayedDataInfo>> | onDelayed(...) (DelayedPolicy.WARN or IGNORE) was set and the delayed check ran |
securityErrors() | Optional<Map<String, BloombergMetadataError>> | includeSecurityErrors(true) was set and Bloomberg reported security errors |
fieldExceptions() | Optional<Map<String, List<BloombergFieldException>>> | Bloomberg reported per-security field exceptions |
fieldErrors() | Optional<Map<String, BloombergFieldError>> | fieldInfo, bflds, or FieldInfoRequest asked for field IDs that Bloomberg refused |
typeMisses() | Optional<Map<String, Long>> | Non-null values could not be converted to their column's declared Arrow type |
import io.github.underloam.xbbg.BdpOptions;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.DelayedPolicy;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.BloombergFieldException;
import io.github.underloam.xbbg.table.DelayedDataInfo;
import io.github.underloam.xbbg.table.Table;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class ResultMetadataExample {
public static void main(String[] args) {
Table ref =
Xbbg.await(
Blp.bdp(
Arrays.asList("VOD LN Equity", "AAPL US Equity"),
Arrays.asList("PX_LAST"),
BdpOptions.builder()
.returnEids(true)
.includeSecurityErrors(true)
.onDelayed(DelayedPolicy.IGNORE)
.build()));
System.out.println("Support RequestIds: " + ref.bloombergRequestIds());
ref.eidData()
.ifPresent(
eids -> System.out.println("Entitlement IDs: " + eids));
ref.delayed()
.ifPresent(
(Map<String, DelayedDataInfo> delayedMap) ->
delayedMap.forEach(
(sec, info) ->
System.out.println(
sec
+ " delayed="
+ info.delayed()
+ " minutes="
+ info.delayMinutes())));
ref.fieldExceptions()
.ifPresent(
(Map<String, List<BloombergFieldException>> exceptions) ->
System.out.println("Field exceptions: " + exceptions));
}
}Dates) Option builders and recipe methods accept dates and datetimes either as strings or as java.time.TemporalAccessor instances (LocalDate, LocalDateTime, OffsetDateTime, ZonedDateTime, Instant). The public Dates utility applies the same formatting rules:
| Method | Accepted inputs | Output |
|---|---|---|
Dates.formatDate(String) | "YYYYMMDD", "YYYY-MM-DD", "YYYY/MM/DD", or ISO 8601 datetime | "YYYYMMDD" (or null when null/blank) |
Dates.formatDate(TemporalAccessor) | LocalDate, LocalDateTime, OffsetDateTime, ZonedDateTime (uses own calendar date), Instant (uses UTC date) | "YYYYMMDD" |
Dates.formatDate(java.util.Date) | java.util.Date (UTC date) or java.sql.Date (local date) | "YYYYMMDD" |
Dates.formatDateTime(String) | "YYYYMMDD" (-> YYYY-MM-DDT00:00:00) or ISO 8601 datetime string (keeps naive strings naive) | ISO 8601 string |
Dates.formatDateTime(TemporalAccessor) | LocalDateTime (naive), LocalDate (T00:00:00), ZonedDateTime / OffsetDateTime (with offset), Instant (UTC with .SSS and Z) | ISO 8601 string |
Dates.formatDateTime(java.util.Date) | java.util.Date | UTC ISO 8601 string with milliseconds |
Month/day-ambiguous strings such as "01/17/2024" throw IllegalArgumentException before any request is sent.
First requests, options, and error handling.
Scalar Ticks, ArrowSubscription tables, and DeliveryStream envelopes.
Analytics workflows returning Table or any Backend<T>.
Every class in io.github.underloam.xbbg.table and io.github.underloam.xbbg.jdk17.