Hi Michael,

Sorry for the late response. I haven't looked into this any further so far. 
You can ask us to update the Jackson dependency in the course of which we 
would have to look into this in more detail. For that, go to the Camunda 
JIRA: https://app.camunda.com/jira/browse/CAM

Cheers,
Thorben

Am Mittwoch, 9. August 2017 22:41:30 UTC+2 schrieb Michael Nielson:
>
> Hi Thorben, were you able to find a solution to the problem? I'm running 
> into the same issue trying to run camunda in an application with 
> dependencies on Jackson 2.8 and not having a lot of luck.
>
> On Friday, February 3, 2017 at 3:59:25 AM UTC-7, thorben....@camunda.com 
> wrote:
>>
>> Hi Tatu,
>>
>> Thanks for your response and good to know that I am using something that 
>> isn't intended to be used :)
>>
>> I'll elaborate a little bit on my actual use case and then ask some 
>> follow-up questions.
>>
>> My use case is: I'd like to have code that takes instances of classes 
>> implementing java.util.List, serializes them as JSON and stores the JSON 
>> along with the instances type name such that I can deserialize the list at 
>> a later point in time. I'd like the JSON to contain as little type-metadata 
>> as possible. For a regular java.util.ArrayList I use this code:
>>
>> List<?> someList = ..;
>> String typeName;
>> if (!someList.isEmpty()) {
>>   Object firstElement = list.get(0);
>>   typeName = typeFactory.constructCollectionType(someList.getClass(), 
>> firstElement);
>> }
>> else
>> {
>>   typeName = typeFactory.constructType(someList.getClass()); // or could 
>> simply use Class#getName
>> }
>>
>> This code circumvents the type erasure problem. Of course it has the 
>> limitations that it cannot deal with lists that contain instances of 
>> different classes or lists that contain lists again. These limitations are 
>> ok for my use case.
>>
>> For deserialization, I use the aforementioned `constructFromCanonical()`. 
>>
>> With jackson-databind 2.6.3, this code works fine for both instances of 
>> java.util.ArrayList or classes like WrapperList in my first post. With 
>> Jackson 2.8.6 this approach fails for WrapperList.
>>
>> Now my questions would be:
>>
>> 1. Can my use case (serialization of JSON, serialization of type, 
>> avoiding type information in JSON) be solved with Jackson end-user features?
>> 2. If no to 1), would I have to lift the restriction of avoiding type 
>> information in the JSON?
>> 3. If in general yes to 1), what would be the end-user way to get from a 
>> canonical type string and JSON back to a deserialized object?
>>
>> Cheers,
>> Thorben
>>
>> Am Donnerstag, 2. Februar 2017 17:21:32 UTC+1 schrieb Tatu Saloranta:
>>>
>>> Ok, code has a few problems. 
>>>
>>> First: method `constructFromCanonical()` really isn't meant to be 
>>> end-user functionality. 
>>> Maybe Javadocs should make this clear, but it is not something I was 
>>> planning to be used by anything but core Jackson functionality. I can 
>>> sort of see why it might seem useful, but there is one big problem 
>>> using it for persisting generic type... 
>>>
>>> The problem is this: all instances of generic types, at runtime, are 
>>> subject to type erasure. 
>>> So you will not be able to obtain any more information than actual 
>>> underlying `Class<?>`. 
>>> This being the case you might as well just access `class.getName()` 
>>> and use that. 
>>> This is different from programmatically constructed `JavaType` 
>>> instances which can and do retain generic type information; but this 
>>> comes from property type (and class super type) declarations. 
>>>
>>> So use of: 
>>>
>>>  JavaType type = typeFactory.constructType(list.getClass()); 
>>>
>>> tends not to work as expected: none of generic types are preserved. 
>>>
>>> In this case it is also possible that canonical name handling isn't 
>>> working like it should (maybe worth filing a bug for), since it should 
>>> always be possible to read back canonical name you created. 
>>> However, I don't think it would work for your use case: it can not be 
>>> any better than simply serializing name of the `Class` you have, due 
>>> to type erasure. 
>>>
>>> Going back to persisting type externally: you should either serialize 
>>> simple class name (safest), or, if you absolutely need generic typing, 
>>> programmatically construct generic type using `TypeFactory`, and then 
>>> get canonical name. 
>>>
>>> I hope this helps, 
>>>
>>> -+ Tatu +- 
>>>
>>>
>>> On Tue, Jan 31, 2017 at 2:18 AM,  <thorben....@camunda.com> wrote: 
>>> > Hi, 
>>> > 
>>> > Jackson-databind version: 2.8.6 
>>> > 
>>> > I have a class that implements java.util.List with a compile-time 
>>> defined 
>>> > generic type, e.g. 
>>> > 
>>> > public static class WrapperList implements List<Byte> 
>>> > { 
>>> >    // delegate to methods of a wrapped ArrayList 
>>> > } 
>>> > 
>>> > Now I want to use TypeFactory to create a canonical String 
>>> representation of 
>>> > that type that I can persist and later use for (de-)serialization, 
>>> e.g. 
>>> > 
>>> > WrapperList list = new WrapperList(); 
>>> > list.add((byte) 10); 
>>> > 
>>> > ObjectMapper mapper = new ObjectMapper(); 
>>> > TypeFactory typeFactory = mapper.getTypeFactory(); 
>>> > JavaType type = typeFactory.constructType(list.getClass()); 
>>> > String canonicalTypeName = type.toCanonical(); 
>>> > 
>>> > This results in canonicalTypeName being 
>>> > org.camunda.bpm.Main$WrapperList<java.lang.Byte>. However, calling 
>>> > 
>>> > typeFactory.constructFromCanonical(canonicalTypeName); 
>>> > 
>>> > results in the following exception: 
>>> > 
>>> > Exception in thread "main" java.lang.IllegalArgumentException: Can not 
>>> > create TypeBindings for class org.camunda.bpm.Main$WrapperList with 1 
>>> type 
>>> > parameter: class expects 0 
>>> >     at 
>>> > 
>>> com.fasterxml.jackson.databind.type.TypeBindings.create(TypeBindings.java:125)
>>>  
>>>
>>> >     at 
>>> > 
>>> com.fasterxml.jackson.databind.type.TypeBindings.create(TypeBindings.java:95)
>>>  
>>>
>>> >     at 
>>> > 
>>> com.fasterxml.jackson.databind.type.TypeBindings.create(TypeBindings.java:86)
>>>  
>>>
>>> >     at 
>>> > 
>>> com.fasterxml.jackson.databind.type.TypeParser.parseType(TypeParser.java:54)
>>>  
>>>
>>> >     at 
>>> > 
>>> com.fasterxml.jackson.databind.type.TypeParser.parse(TypeParser.java:33) 
>>> >     at 
>>> > 
>>> com.fasterxml.jackson.databind.type.TypeFactory.constructFromCanonical(TypeFactory.java:544)
>>>  
>>>
>>> >     at com.example.Main.main(Main.java:42) 
>>> > 
>>> > Am I using the wrong method for creating the JavaType in this case? 
>>> > 
>>> > Cheers, 
>>> > Thorben 
>>> > 
>>> > PS: Here's the full code example for reference: 
>>> > 
>>> > package com.example; 
>>> > 
>>> > import java.io.IOException; 
>>> > import java.util.ArrayList; 
>>> > import java.util.Collection; 
>>> > import java.util.Iterator; 
>>> > import java.util.List; 
>>> > import java.util.ListIterator; 
>>> > 
>>> > import com.fasterxml.jackson.databind.JavaType; 
>>> > import com.fasterxml.jackson.databind.ObjectMapper; 
>>> > import com.fasterxml.jackson.databind.type.TypeFactory; 
>>> > 
>>> > public class Main { 
>>> > 
>>> >   public static void main(String[] args) throws IOException { 
>>> >     WrapperList list = new WrapperList(); 
>>> >     list.add((byte) 10); 
>>> > 
>>> >     ObjectMapper mapper = new ObjectMapper(); 
>>> >     TypeFactory typeFactory = mapper.getTypeFactory(); 
>>> >     JavaType type = typeFactory.constructType(list.getClass()); 
>>> >     System.out.println(type.toCanonical()); 
>>> > 
>>> >     JavaType reconstructedType = 
>>> > typeFactory.constructFromCanonical(type.toCanonical()); 
>>> >   } 
>>> > 
>>> >   public static class WrapperList implements List<Byte> 
>>> >   { 
>>> >     protected List<Byte> innerList = new ArrayList<Byte>(); 
>>> > 
>>> >     public int size() { 
>>> >       return innerList.size(); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean isEmpty() { 
>>> >       return innerList.isEmpty(); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean contains(Object o) { 
>>> >       return innerList.contains(o); 
>>> >     } 
>>> > 
>>> > 
>>> >     public Iterator<Byte> iterator() { 
>>> >       return innerList.iterator(); 
>>> >     } 
>>> > 
>>> > 
>>> >     public Object[] toArray() { 
>>> >       return innerList.toArray(); 
>>> >     } 
>>> > 
>>> > 
>>> >     public <T> T[] toArray(T[] a) { 
>>> >       return innerList.toArray(a); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean add(Byte e) { 
>>> >       return innerList.add(e); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean remove(Object o) { 
>>> >       return innerList.remove(o); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean containsAll(Collection<?> c) { 
>>> >       return innerList.containsAll(c); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean addAll(Collection<? extends Byte> c) { 
>>> >       return innerList.addAll(c); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean addAll(int index, Collection<? extends Byte> c) { 
>>> >       return innerList.addAll(index, c); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean removeAll(Collection<?> c) { 
>>> >       return innerList.removeAll(c); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean retainAll(Collection<?> c) { 
>>> >       return innerList.retainAll(c); 
>>> >     } 
>>> > 
>>> > 
>>> >     public void clear() { 
>>> >       innerList.clear(); 
>>> >     } 
>>> > 
>>> > 
>>> >     public boolean equals(Object o) { 
>>> >       return innerList.equals(o); 
>>> >     } 
>>> > 
>>> > 
>>> >     public int hashCode() { 
>>> >       return innerList.hashCode(); 
>>> >     } 
>>> > 
>>> > 
>>> >     public Byte get(int index) { 
>>> >       return innerList.get(index); 
>>> >     } 
>>> > 
>>> > 
>>> >     public Byte set(int index, Byte element) { 
>>> >       return innerList.set(index, element); 
>>> >     } 
>>> > 
>>> > 
>>> >     public void add(int index, Byte element) { 
>>> >       innerList.add(index, element); 
>>> >     } 
>>> > 
>>> > 
>>> >     public Byte remove(int index) { 
>>> >       return innerList.remove(index); 
>>> >     } 
>>> > 
>>> >     public int indexOf(Object o) { 
>>> >       return innerList.indexOf(o); 
>>> >     } 
>>> > 
>>> > 
>>> >     public int lastIndexOf(Object o) { 
>>> >       return innerList.lastIndexOf(o); 
>>> >     } 
>>> > 
>>> > 
>>> >     public ListIterator<Byte> listIterator() { 
>>> >       return innerList.listIterator(); 
>>> >     } 
>>> > 
>>> > 
>>> >     public ListIterator<Byte> listIterator(int index) { 
>>> >       return innerList.listIterator(index); 
>>> >     } 
>>> > 
>>> > 
>>> >     public List<Byte> subList(int fromIndex, int toIndex) { 
>>> >       return innerList.subList(fromIndex, toIndex); 
>>> >     } 
>>> >   } 
>>> > 
>>> > } 
>>> > 
>>> > -- 
>>> > You received this message because you are subscribed to the Google 
>>> Groups 
>>> > "jackson-user" group. 
>>> > To unsubscribe from this group and stop receiving emails from it, send 
>>> an 
>>> > email to jackson-user...@googlegroups.com. 
>>> > To post to this group, send email to jackso...@googlegroups.com. 
>>> > For more options, visit https://groups.google.com/d/optout. 
>>>
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jackson-user+unsubscr...@googlegroups.com.
To post to this group, send email to jackson-user@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to