• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.deser;
2 
3 import java.io.IOException;
4 
5 import com.fasterxml.jackson.core.JsonParser;
6 import com.fasterxml.jackson.core.JsonProcessingException;
7 import com.fasterxml.jackson.databind.*;
8 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9 
10 /**
11  * Testing for NPE due to race condition.
12  */
13 public class TestConcurrency extends BaseMapTest
14 {
15     /*
16     /**********************************************
17     /* Helper beans
18     /**********************************************
19      */
20 
21     @JsonDeserialize(using=CustomBeanDeserializer.class)
22     static class Bean
23     {
24         public int value = 42;
25     }
26 
27     /*
28     /**********************************************
29     /* Helper classes
30     /**********************************************
31      */
32 
33     /**
34      * Dummy deserializer used for verifying that partially handled (i.e. not yet
35      * resolved) deserializers are not allowed to be used.
36      */
37     static class CustomBeanDeserializer
38         extends JsonDeserializer<Bean>
39         implements ResolvableDeserializer
40     {
41         protected volatile boolean resolved = false;
42 
43         @Override
deserialize(JsonParser jp, DeserializationContext ctxt)44         public Bean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
45         {
46             if (!resolved) {
47                 throw new IOException("Deserializer not yet completely resolved");
48             }
49             Bean b = new Bean();
50             b.value = 13;
51             return b;
52         }
53 
54         @Override
resolve(DeserializationContext ctxt)55         public void resolve(DeserializationContext ctxt) throws JsonMappingException
56         {
57             try {
58                 Thread.sleep(100L);
59             } catch (Exception e) { }
60             resolved = true;
61         }
62     }
63 
64     /*
65     /**********************************************
66     /* Unit tests
67     /**********************************************
68      */
69 
testDeserializerResolution()70     public void testDeserializerResolution() throws Exception
71     {
72         /* Let's repeat couple of times, just to be sure; thread timing is not
73          * exact science; plus caching plays a role too
74          */
75         final String JSON = "{\"value\":42}";
76 
77         for (int i = 0; i < 5; ++i) {
78             final ObjectMapper mapper = new ObjectMapper();
79             Runnable r = new Runnable() {
80                 @Override
81                 public void run() {
82                     try {
83                         /*Bean b =*/ mapper.readValue(JSON, Bean.class);
84                     } catch (Exception e) { }
85                 }
86             };
87             Thread t = new Thread(r);
88             t.start();
89             // then let it proceed
90             Thread.sleep(10L);
91             // and try the same...
92             Bean b = mapper.readValue(JSON, Bean.class);
93             // note: funny deserializer, mangles data.. :)
94             assertEquals(13, b.value);
95             t.join();
96         }
97     }
98 }
99