pinpoint-apm/pinpoint · error · OracleConnectionStringException
Syntax error. lookAheadToken is null
Error message
Syntax error. lookAheadToken is null
What it means
parseKeyValue() loops on tokenizer.lookAheadToken(); when it returns null the token stream ran out before a value, key start '(' or key end ')' was seen, so the recursive-descent parser hit abnormal termination and throws. This is a truncated descriptor: the grammar expects more tokens than the input provides.
Source
Thrown at agent-module/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/parser/OracleNetConnectionDescriptorParser.java:110
// start
this.tokenizer.checkStartToken();
// key
Token literalToken = this.tokenizer.getLiteralToken();
KeyValue.Builder keyValue = new KeyValue.Builder(literalToken.getToken());
// =
this.tokenizer.checkEqualToken();
// value compare reduce
boolean nonTerminalValue = false;
while(true) {
final Token token = this.tokenizer.lookAheadToken();
if (token == null) {
// Abnormal termination.
throw new OracleConnectionStringException("Syntax error. lookAheadToken is null");
}
if (token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_KEY_START) {
nonTerminalValue = true;
KeyValue child = parseKeyValue();
keyValue.addKeyValueList(child);
// if next token is ')', value is completed.
Token endCheck = this.tokenizer.lookAheadToken();
if (endCheck == OracleNetConnectionDescriptorTokenizer.TOKEN_KEY_END_OBJECT) {
this.tokenizer.nextPosition();
return keyValue.build();
}
} else if(token.getType() == OracleNetConnectionDescriptorTokenizer.TYPE_LITERAL) {
if (nonTerminalValue) {
throw new OracleConnectionStringException("Syntax error. expected token:'(' or ')' :" + token.getToken());
}
// We already have checked current token by lookAheadToken(). Proceed to next token.
this.tokenizer.nextPosition();View on GitHub (pinned to 744c3d3075)
Solutions
- Restore the missing value/closing structure so every (KEY=VALUE) pair is complete and balanced
- Compare the URL against the original tnsnames.ora entry and re-copy it intact
- Enable quoting of the descriptor in config files (YAML/single quotes) so special characters aren't stripped
- Add a startup validation step that calls the parser on the configured URL and fails fast with the full string logged
Example fix
// before String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db)(PORT=1521))(CONNECT_DATA"; // truncated // after String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=svc)))";
Defensive patterns
Strategy: validation
Validate before calling
static boolean isCompleteDescriptor(String url) {
if (url == null) return false;
String d = url.substring(url.indexOf('@') + 1);
return d.startsWith("(") && d.endsWith(")") && isBalanced(d);
} Try / catch
try {
parser.parse(url);
} catch (OracleConnectionStringException e) {
log.error("Oracle descriptor truncated (missing value or ')'): {}", url, e);
throw new ConfigurationException("Incomplete oracle connection descriptor", e);
} Prevention
- Never split descriptor URLs across config lines or variables
- Quote the full descriptor in YAML/properties so no characters are stripped
- Re-copy long descriptors from tnsnames.ora instead of hand-trimming
When it happens
Trigger: A descriptor where a key's value section is missing entirely, e.g. '(KEY=)' followed by end-of-input, or '(CONNECT_DATA' ending the string — lookAheadToken() exhausts the stream inside the while(true) loop.
Common situations: Copy-paste truncation of a long tnsnames entry; config templating that dropped everything after a variable; an editor or YAML parser stripping the trailing ')' characters or quoting the value away.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- parse error. token is null. Expected token='='
- description node not found
- description_list node not found
- invalid oracle jdbc url. expected token:(thin or oci) url:<u
- parsing error. expected token:'EOF' token:null
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/f2cf0c7ce6ab6f9d.
Report an issue: GitHub.