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.lindha...@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+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. -- 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.