Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caused by: com.fasterxml.jackson.core.JsonParseException: Invalid length indicator for String: -98 #343

Open
birTiwana opened this issue Nov 15, 2022 · 2 comments
Labels

Comments

@birTiwana
Copy link

birTiwana commented Nov 15, 2022

I have created a very simple avro schema file:

{
   "name":"SampleRecordDto",
   "type":"record",
   "namespace":"com.api.jsonata4java.avro.v1",
   "fields":[
      {
         "name":"name",
         "type":"string"
      }
   ]
}

Then generating a SampleRecordDto file from this using the following avro-maven-plugin.


			<plugin>
				<groupId>org.apache.avro</groupId>
				<artifactId>avro-maven-plugin</artifactId>
				<version>1.8.2</version>
				<executions>
					<execution>
						<phase>generate-sources</phase>
						<goals>
							<goal>schema</goal>
						</goals>
						<configuration>
							<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
							<outputDirectory>${project.build.directory}/generated-sources/avro/</outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>

After then using jackson-dataformat-avro to convert an object of class SampleRecodDto to JSONNode using the following code:

package com.api.jsonata4java.test.expressions;

import com.api.jsonata4java.avro.v1.SampleRecordDto;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.dataformat.avro.AvroMapper;
import com.fasterxml.jackson.dataformat.avro.AvroSchema;
import org.apache.avro.Schema;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;

public class AvroTest {
    private static final AvroMapper avroMapper = new AvroMapper();
    public static void main(String[] args) throws IOException {
        SampleRecordDto sampleRecordDto = SampleRecordDto.newBuilder()
                .setName("apm")
                .build();

        JsonNode jsonNode = decode(sampleRecordDto.getSchema(), sampleRecordDto.toByteBuffer().array());
        System.out.println(jsonNode);

    }

    public  static JsonNode decode(Schema schema, byte[] message) {
        try (InputStream input = new ByteArrayInputStream(message)) {
            return avroMapper.reader(new AvroSchema(schema)).readTree(input);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

But I am running into the following exception:

Exception in thread "main" java.io.UncheckedIOException: com.fasterxml.jackson.core.JsonParseException: Invalid length indicator for String: -98
	at com.api.jsonata4java.test.expressions.AvroTest.decode(AvroTest.java:31)
	at com.api.jsonata4java.test.expressions.AvroTest.main(AvroTest.java:22)
Caused by: com.fasterxml.jackson.core.JsonParseException: Invalid length indicator for String: -98
	at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2418)
	at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:749)
	at com.fasterxml.jackson.dataformat.avro.deser.JacksonAvroParserImpl.decodeString(JacksonAvroParserImpl.java:574)
	at com.fasterxml.jackson.dataformat.avro.deser.JacksonAvroParserImpl.decodeStringToken(JacksonAvroParserImpl.java:565)
	at com.fasterxml.jackson.dataformat.avro.deser.ScalarDecoder$StringReader$FR.readValue(ScalarDecoder.java:317)
	at com.fasterxml.jackson.dataformat.avro.deser.RecordReader$Std.nextToken(RecordReader.java:142)
	at com.fasterxml.jackson.dataformat.avro.deser.AvroParserImpl.nextToken(AvroParserImpl.java:97)
	at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer._deserializeContainerNoRecursion(JsonNodeDeserializer.java:539)
	at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:98)
	at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:23)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
	at com.fasterxml.jackson.databind.ObjectReader._bindAsTree(ObjectReader.java:2149)
	at com.fasterxml.jackson.databind.ObjectReader._bindAndCloseAsTree(ObjectReader.java:2117)
	at com.fasterxml.jackson.databind.ObjectReader.readTree(ObjectReader.java:1794)
	at com.api.jsonata4java.test.expressions.AvroTest.decode(AvroTest.java:29)

Can I please get some help on this?

@cowtowncoder
Copy link
Member

One thing to check, I think, is to ensure that this:

sampleRecordDto.toByteBuffer().array()

returns valid encoded document where content is at 0-offset. ByteBuffer could return backing array that has different offset; so checking what ByteBuffer.arrayOffset() returns would be good -- if it's not 0 there'd be a problem.
In general there is some discrepancy between data being decoded and schema; Avro as a format is very fragile unfortunately (as it thrives to be as compact as possible, little redundancy) and it is very easy to get corrupt data.

Also make sure to use a recent Jackson version; I don't think that is necessarily the problem here but sometimes bugs are reported against very old version and fix exists in newer versions.

@birTiwana
Copy link
Author

I checked and the value ByteBuffer.arrayOffset() is actually 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants