{"record":{"id":"7390cab0246b65ce","repo":"pinpoint-apm/pinpoint","slug":"parsing-error-expected-token-eof-token-eof","errorCode":null,"errorMessage":"parsing error. expected token:'EOF' token:<eof>","messagePattern":"parsing error\\. expected token:'EOF' token:<eof>","errorType":"validation","errorClass":"OracleConnectionStringException","httpStatus":null,"severity":"error","filePath":"agent-module/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/parser/OracleNetConnectionDescriptorParser.java","lineNumber":72,"sourceCode":"\n        // skip thin string\n        this.tokenizer.setPosition(position);\n\n        this.tokenizer.parse();\n        KeyValue<?> keyValue = parseKeyValue();\n\n        checkEof();\n\n        return keyValue;\n    }\n\n    private void checkEof() {\n        Token eof = this.tokenizer.nextToken();\n        if (eof == null) {\n            throw new OracleConnectionStringException(\"parsing error. expected token:'EOF' token:null\");\n        }\n        if (eof != OracleNetConnectionDescriptorTokenizer.TOKEN_EOF_OBJECT) {\n            throw new OracleConnectionStringException(\"parsing error. expected token:'EOF' token:\" + eof);\n        }\n    }\n\n    public DriverType getDriverType() {\n        return driverType;\n    }\n\n    private int nextPosition(String driverUrl) {\n        final int thinLength = driverUrl.length();\n        if (normalizedUrl.startsWith(\":@\", thinLength)) {\n            return thinLength + 2;\n        } else if(normalizedUrl.startsWith(\"@\", thinLength)) {\n            return thinLength + 1;\n        } else {\n            throw new OracleConnectionStringException(\"invalid oracle jdbc url:\" + driverUrl);\n        }\n    }\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/plugins/oracle-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/oracle/parser/OracleNetConnectionDescriptorParser.java#L54-L90","documentation":"After the parser consumes the descriptor structure, checkEof() requires the next token to be the singleton EOF token object. Here a real token ('<eof>'-like trailing content, i.e. leftover characters after the balanced descriptor) remains, so the parser throws. The descriptor parses but has trailing garbage after it.","triggerScenarios":"Parsing a driver URL that contains extra characters after a syntactically complete (DESCRIPTION=...) descriptor — checkEof() sees token != TOKEN_EOF_OBJECT and throws with the offending token text.","commonSituations":"Appending parameters like ?internal_logon=sysdba or stray whitespace/comments inside the descriptor; concatenating two descriptors; YAML/config quoting leaving stray brackets or quotes after the last ')'.","solutions":["Remove any characters after the final closing ')' of the connection descriptor","Move extra parameters out of the descriptor — pass them as separate connection properties (Properties object) instead","If whitespace/newlines are present, trim and normalize the URL before passing it to the driver","Validate the URL by running it through the parser or a connection test in a staging config first"],"exampleFix":"// before\nString url = \"jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=svc)))extra\";\n// after\nString url = \"jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=svc)))\";","handlingStrategy":"validation","validationCode":"// after '(' balance check, ensure nothing trails the descriptor\nstatic boolean hasTrailingGarbage(String url) {\n    int idx = url.lastIndexOf(')');\n    return idx != -1 && idx != url.length() - 1;\n}\n// reject when hasTrailingGarbage(jdbcUrl) is true","typeGuard":"boolean isCleanDescriptor(String url) {\n    return url != null && url.startsWith(\"jdbc:oracle:thin:@(\") && url.trim().endsWith(\")\");\n}","tryCatchPattern":"try {\n    parseDescriptor(url);\n} catch (OracleConnectionStringException e) {\n    log.error(\"Oracle descriptor has trailing content after final ')': {}\", url, e);\n    throw new ConfigurationException(\"Trailing characters in jdbc url\", e);\n}","preventionTips":["Trim the URL and ensure it ends exactly at the final ')'","Pass extra parameters (credentials, options) as Properties, not appended URL text","Quote descriptor strings properly in YAML/properties files so nothing extra leaks in"],"tags":["jdbc","oracle","url-parsing","trailing-content"],"backgroundTag":"invalid-url-format","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}