influxdata / influxdata/influxdb-java

InfluxDBResultMapper throws ClassCastException with MessagePack Response Format

Open
#624 1 comment 2 reactions 1 assignee View on GitHub

@fmachado is already working on this.

Since Jan 4, 2020.

kind/bug
Dominant language
Java
Stars
1.2k
Forks
469
PR merge metrics
No merged PRs in 30d

Description

I'm using InfluxDB and telegraf to monitor machine memory, then I encounted a ClassCastException.
The query in InfluxDB returns:

select last(available_percent) as available_percent, total from mem
name: mem
time          available_percent total
----          ----------------- -----
1569324120000 85.13442402872242 3954188288

According to https://github.com/influxdata/telegraf/tree/master/plugins/inputs/mem, total is an integer and available_percent is a float, so I create a class as follows:

@Measurement(name = "mem")
public class Mem {
    @Column(name = "time")
    private Instant time;
    @Column(name = "total")
    private long total;
    @Column(name = "available_percent")
    private double availablePercent;

    // getter and setter ommitted

After connected to InfluxDB with MessagePack response format, I execute the query.

public class InfluxDBTest {
    private static final String DATABASE = "telegraf";

    private static InfluxDB establishConnection() {
        InfluxDB influxDB = new InfluxDBImpl("http://172.16.172.100:8086", null, null, new OkHttpClient.Builder(),
                InfluxDB.ResponseFormat.MSGPACK);
        influxDB.setDatabase(DATABASE);
        influxDB.setLogLevel(InfluxDB.LogLevel.FULL);
        influxDB.disableBatch();
        return influxDB;
    }

    public static void main(String[] args) {
        InfluxDB influxDB = establishConnection();
        QueryResult queryResult = influxDB.query(
                new Query("select last(available_percent) as available_percent, total from mem"));
        InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
        List<Mem> mems = resultMapper.toPOJO(queryResult, Mem.class, TimeUnit.MILLISECONDS);
        System.out.println(mems);
    }
}

Then an exception was thrown as follows:

Exception in thread "main" org.influxdb.InfluxDBMapperException: Class 'com.suntao.model.Mem' field 'total' was defined with a different field type and caused a ClassCastException. The correct type is 'java.lang.Long' (current field value: '3954188288').
	at org.influxdb.impl.InfluxDBResultMapper.setFieldValue(InfluxDBResultMapper.java:327)
	at org.influxdb.impl.InfluxDBResultMapper.parseSeriesAs(InfluxDBResultMapper.java:266)
	at org.influxdb.impl.InfluxDBResultMapper.lambda$null$2(InfluxDBResultMapper.java:179)

I tried to debug, then I found it seemed that the value deserialized from MessagePack is of type Long, and the field in class is also of type long, but fieldValueForPrimitivesModified or fieldValueForPrimitiveWrappersModified method all want to cast the returned value as Double, which caused the exception.

Project settings are as follows:

  • influxdb-java 2.15
  • InfluxDB 1.7.8
  • Java 1.8.192

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.