title: Does Jackson Without Annotations Absolutely Require Setters?
body: <p>I'm using Jackson 1.6.4 and Java JDK 6.</p>
  
  <p>I don't want to use Jackson annotations; I want to have immutable Java objects without setters.</p>
  
  <p>The two requirements appear to conflict.  </p>
  
  <p>If I add private setters deserialization works fine.</p>
  
  <p>I'm trying to not resort to private setters for my immutable objects - I'm stubborn that way.</p>
  
  <p>I'm in the process of trying a custom implementation of VisibilityChecker to allow ANY field access.</p>
  
  <p>But if anyone has some advice or lessons learned they can share I'd appreciate hearing them.</p>
  
  <p>UPDATE: It's working.</p>
  
  <p>Builder pattern, private constructor - a la Bloch "Effective Java".</p>
  
  <p>It took setting deserialization configuration and visibility, but now it's good to go.</p>
  
  <pre><code>public class JsonMapper
  {
     private static final int INITIAL_SIZE = 2048;
     /** See http://wiki.fasterxml.com/JacksonBestPracticeThreadSafety?highlight=(\bCategoryJackson\b) */
     private static ObjectMapper mapper;
  
     static
     {
        mapper = new ObjectMapper();
  
        mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
        SerializationConfig serializationConfig = mapper.getSerializationConfig();
        serializationConfig.setDateFormat(Person.DEFAULT_FORMATTER);
  
        mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        DeserializationConfig deserializationConfig = mapper.getDeserializationConfig();
        deserializationConfig.setDateFormat(Person.DEFAULT_FORMATTER);
        deserializationConfig.enable(DeserializationConfig.Feature.AUTO_DETECT_FIELDS);
        mapper.setVisibilityChecker(VisibilityChecker.Std.defaultInstance().withFieldVisibility(JsonAutoDetect.Visibility.ANY));
     }
  
     public static &lt;T&gt; String serialize(T o) throws IOException
     {
        StringWriter sw = new StringWriter(INITIAL_SIZE);
        mapper.writeValue(sw, o);
  
        return sw.toString();
     }
  
     public static &lt;T&gt; T deserialize(String source, Class&lt;T&gt; targetClass) throws IOException
     {
        ByteArrayInputStream stream = new ByteArrayInputStream(source.getBytes());
        TreeTraversingParser treeTraversingParser = new TreeTraversingParser(mapper.readTree(stream));
        treeTraversingParser.setCodec(mapper);
  
        return treeTraversingParser.readValueAs(targetClass);
     }
  }
  </code></pre>