package com.fasterxml.jackson.databind.deser;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
/**
* Testing for [JACKSON-237] (NPE due to race condition)
*/
public class TestConcurrency extends BaseMapTest
{
/*
/**********************************************
/* Helper beans
/**********************************************
*/
@JsonDeserialize(using=BeanDeserializer.class)
static class Bean
{
public int value = 42;
}
/*
/**********************************************
/* Helper classes
/**********************************************
*/
/**
* Dummy deserializer used for verifying that partially handled (i.e. not yet
* resolved) deserializers are not allowed to be used.
*/
static class BeanDeserializer
extends JsonDeserializer<Bean>
implements ResolvableDeserializer
{
protected volatile boolean resolved = false;
@Override
public Bean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
{
if (!resolved) {
throw new IOException("Deserializer not yet completely resolved");
}
Bean b = new Bean();
b.value = 13;
return b;
}
@Override
public void resolve(DeserializationContext ctxt) throws JsonMappingException
{
try {
Thread.sleep(100L);
} catch (Exception e) { }
resolved = true;
}
}
/*
/**********************************************
/* Unit tests
/**********************************************
*/
public void testDeserializerResolution() throws Exception
{
/* Let's repeat couple of times, just to be sure; thread timing is not
* exact science; plus caching plays a role too
*/
final String JSON = "{\"value\":42}";
for (int i = 0; i < 5; ++i) {
final ObjectMapper mapper = new ObjectMapper();
Runnable r = new Runnable() {
@Override
public void run() {
try {
/*Bean b =*/ mapper.readValue(JSON, Bean.class);
} catch (Exception e) { }
}
};
Thread t = new Thread(r);
t.start();
// then let it proceed
Thread.sleep(10L);
// and try the same...
Bean b = mapper.readValue(JSON, Bean.class);
// note: funny deserializer, mangles data.. :)
assertEquals(13, b.value);
t.join();
}
}
}