[jdbc-v2] User-Agent wraps detected frameworks in double parentheses: ((apache.spark))
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 70/100
Piste de recherche
Le double groupement vient de deux endroits dans jdbc-v2 : Driver.FrameworksDetection.getFrameworksDetected() dans jdbc-v2/src/main/java/com/clickhouse/jdbc/Driver.java entoure chaque nom de parenthèses, et ConnectionImpl dans jdbc-v2 entoure à nouveau le résultat concaténé. Supprime l'encadrement par nom uniquement dans la copie jdbc-v2, et laisse DriverV1.FrameworksDetection inchangé dans jdbc-v1. C'est terminé lorsqu'une pile contenant org.apache.spark produit un seul groupe comme (apache.spark), et qu'une pile sans framework ne produit toujours aucun groupe. Un test dans un package org.apache.spark doit d'abord réinitialiser le champ statique frameworksDetected.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Description
When jdbc-v2 detects a framework on the call stack (apache.spark, apache.flink, apache.nifi), it adds the framework names to the User-Agent header inside two levels of parentheses:
jdbc-v2/0.12.0-rc1-SNAPSHOT ((apache.spark)) clickhouse-java-v2/0.12.0-rc1-SNAPSHOT (Linux; jvm:17.0.20.1) Apache-HttpClient/5.6.4
With two frameworks on the stack, each name gets its own inner group:
jdbc-v2/0.12.0-rc1-SNAPSHOT ((apache.flink); (apache.spark)) clickhouse-java-v2/0.12.0-rc1-SNAPSHOT (Linux; jvm:17.0.20.1) Apache-HttpClient/5.6.4
Nested comments are valid HTTP (RFC 9110), so requests do not fail. But the header is read by tools that parse system.query_log.http_user_agent (see #2775), and a single comment group is the shape that the rest of the header uses.
Root cause
Two places add parentheses:
Driver.FrameworksDetection.getFrameworksDetected()wraps each name:inferredFrameworks.add(String.format("(%s)", framework)), then joins with"; ".
https://github.com/ClickHouse/clickhouse-java/blob/5392b642e5ca0375a77b8cc0f15b29b97a8f772f/jdbc-v2/src/main/java/com/clickhouse/jdbc/Driver.java#L50-L55ConnectionImplwraps the result again:clientName += " (" + detectedFrameworks + ")".
https://github.com/ClickHouse/clickhouse-java/blob/5392b642e5ca0375a77b8cc0f15b29b97a8f772f/jdbc-v2/src/main/java/com/clickhouse/jdbc/ConnectionImpl.java#L101-L107
FrameworksDetection is the same code as DriverV1.FrameworksDetection in jdbc-v1. jdbc-v1 appends the result directly to the product name, with no outer group, so there the inner parentheses are the only group:
https://github.com/ClickHouse/clickhouse-java/blob/5392b642e5ca0375a77b8cc0f15b29b97a8f772f/clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/internal/ClickHouseConnectionImpl.java#L287-L291
jdbc-v2 kept the per-name parentheses and added an outer group, so the names are wrapped twice.
Suggested fix
In jdbc-v2 only, remove one level. For example, add the plain name in Driver.FrameworksDetection (inferredFrameworks.add(framework)) and keep the outer group in ConnectionImpl. Result:
- one framework:
jdbc-v2/<v> (apache.spark) clickhouse-java-v2/<v> ... - two frameworks:
jdbc-v2/<v> (apache.flink; apache.spark) clickhouse-java-v2/<v> ...
Cases that must not change:
- No framework on the stack: no group (today:
jdbc-v2/<v> clickhouse-java-v2/<v> ...). - jdbc-v1 (
DriverV1.FrameworksDetection): it has no outer group, so it needs its per-name parentheses.
A unit test can call Driver.FrameworksDetection.getFrameworksDetected() from a class in an org.apache.spark.* package. The result is cached in a static field, so the test must reset FrameworksDetection.frameworksDetected (package-private) first.
Related: #3213 (open) changes the client-v2 part of the header to the standard format for #3202. It does not change the jdbc-v2 framework group and says this is a separate issue. A maintainer could also decide to move the frameworks into the new client_metadata key/value pairs. That changes the jdbc-v2 output and needs a key name, so it is a design decision, not part of this bug.
Steps to reproduce
- Put a class in a package whose name contains
apache.spark(for exampleorg.apache.spark.repro) and open a jdbc-v2 connection from it. - Run a query that has a unique marker, then
SYSTEM FLUSH LOGS. - Read
http_user_agentfor that query fromsystem.query_log.
Error Log or Exception StackTrace
No exception. Observed http_user_agent values (one JVM per row, because detection result is cached per JVM):
[spark on stack] jdbc-v2/0.12.0-rc1-SNAPSHOT ((apache.spark)) clickhouse-java-v2/0.12.0-rc1-SNAPSHOT (Linux; jvm:17.0.20.1) Apache-HttpClient/5.6.4
[spark, client_name=my-app/1.0] my-app/1.0 jdbc-v2/0.12.0-rc1-SNAPSHOT ((apache.spark)) clickhouse-java-v2/0.12.0-rc1-SNAPSHOT (Linux; jvm:17.0.20.1) Apache-HttpClient/5.6.4
[spark -> flink on stack] jdbc-v2/0.12.0-rc1-SNAPSHOT ((apache.flink); (apache.spark)) clickhouse-java-v2/0.12.0-rc1-SNAPSHOT (Linux; jvm:17.0.20.1) Apache-HttpClient/5.6.4
[no framework on stack] jdbc-v2/0.12.0-rc1-SNAPSHOT clickhouse-java-v2/0.12.0-rc1-SNAPSHOT (Linux; jvm:17.0.20.1) Apache-HttpClient/5.6.4
Expected Behaviour
One comment group with the framework names:
jdbc-v2/0.12.0-rc1-SNAPSHOT (apache.spark) clickhouse-java-v2/0.12.0-rc1-SNAPSHOT ...
jdbc-v2/0.12.0-rc1-SNAPSHOT (apache.flink; apache.spark) clickhouse-java-v2/0.12.0-rc1-SNAPSHOT ...
Code Example
package org.apache.spark.repro; // "apache.spark" in the stack trace triggers detection
import java.sql.*;
import java.util.*;
public class SparkApp {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.setProperty("user", "default");
p.setProperty("password", "<password>");
String marker = "ua_probe_" + UUID.randomUUID().toString().replace("-", "");
try (Connection c = new com.clickhouse.jdbc.Driver().connect("jdbc:clickhouse://localhost:8123/default", p);
Statement s = c.createStatement()) {
s.executeQuery("SELECT '" + marker + "'").close();
s.execute("SYSTEM FLUSH LOGS");
try (ResultSet rs = s.executeQuery("SELECT http_user_agent FROM system.query_log"
+ " WHERE type = 'QueryFinish' AND query LIKE '%" + marker + "%'"
+ " AND query NOT LIKE '%query_log%' LIMIT 1")) {
rs.next();
System.out.println(rs.getString(1));
// prints: jdbc-v2/<v> ((apache.spark)) clickhouse-java-v2/<v> (...)
}
}
}
}
For the two-framework case, call the same code from a class in org.apache.flink.repro that SparkApp calls.
Configuration
Client Configuration
// defaults; framework detection is enabled by default
Environment
- Cloud
- Client version: jdbc-v2
0.12.0-rc1-SNAPSHOT, built frommainat 5392b642e5ca0375a77b8cc0f15b29b97a8f772f - Language version: Java 17.0.20.1
- OS: Linux
ClickHouse Server
- ClickHouse Server version: 26.9.1.1629
- ClickHouse Server non-default settings, if any: none relevant
CREATE TABLEstatements for tables involved: none (SELECT '<marker>'only)
Found by automated analysis (Polyglot AI) while working on #3202. Verified by running the code above against a live ClickHouse server, not only by reading the code.
- Langage dominant
- Java
- Étoiles
- 1.6k
- Forks
- 640
- Merge moyen
- 1 j 13 h
- PR mergées (30 j)
- 41
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de ClickHouse/clickhouse-java
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
ClickHouse/clickhouse-java#3212 ·
Les mainteneurs répondent en général sous 1 jour
-
bug client-api-v2 test
Difficulté 2/5 1-3 heures Accessibilité débutants 92/100
ClickHouse/clickhouse-java#3076 ·
Les mainteneurs répondent en général sous 1 jour
-
area:sql-parser bug client-v1
Difficulté 1/5 1-3 heures Accessibilité débutants 92/100
ClickHouse/clickhouse-java#3066 ·
Les mainteneurs répondent en général sous 1 jour
-
bug client-api-v2 jdbc-v2
Difficulté 1/5 1-3 heures Accessibilité débutants 78/100
ClickHouse/clickhouse-java#2957 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
bug client-v1 wontfix
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
ClickHouse/clickhouse-java#2895 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de ClickHouse/clickhouse-java
Issues similaires
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 90/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
apache/rocketmq-dashboard#6896 ·
Les mainteneurs répondent en général sous 3 jours
-
Difficulté 2/5 1-3 heures Accessibilité débutants 67/100
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
OpenIntegrationEngine/engine#496 ·
Les mainteneurs répondent en général sous 1 jour
-
enhancement good first issue
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
SasanLabs/VulnerableApp#836 ·
Les mainteneurs répondent en général sous 1 jour