Eksperymentuję z połączeniem Jacksona i Lomboka. To są moje zajęcia:
package testelombok;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Value;
import lombok.experimental.Wither;
@Value
@Wither
@AllArgsConstructor(onConstructor=@__(@JsonCreator))
public class TestFoo {
@JsonProperty("xoom")
private String x;
private int z;
}
package testelombok;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xebia.jacksonlombok.JacksonLombokAnnotationIntrospector;
import java.io.IOException;
public class TestLombok {
public static void main(String[] args) throws IOException {
TestFoo tf = new TestFoo("a", 5);
System.out.println(tf.withX("b"));
ObjectMapper om = new ObjectMapper().setAnnotationIntrospector(new JacksonLombokAnnotationIntrospector());
System.out.println(om.writeValueAsString(tf));
TestFoo tf2 = om.readValue(om.writeValueAsString(tf), TestFoo.class);
System.out.println(tf2);
}
}
Oto pliki JAR, które dodam do klasy:
Lombok: https://projectlombok.org/downloads/lombok.jar (wersja 1.16.10)
Adnotacje Jacksona: http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.8.2/jackson-annotations-2.8.2.jar
Rdzeń Jacksona: http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.8.2/jackson-core-2.8.2.jar
Jackson databind: http://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.8.2/jackson-databind-2.8.2.jar
Jackson-lombok: http://repo1.maven.org/maven2/io/paradoxical/jackson-lombok/1.1/jackson-lombok-1.1.jar
Kompiluję go z Netbeans (nie sądzę, że jest to naprawdę istotne, ale i tak zgłaszam to, aby było idealnie i wiernie odtwarzalne). Pięć powyższych plików JAR jest przechowywanych w folderze o nazwie „ lib
” wewnątrz folderu projektu (wraz z „ src
”, „ nbproject
”, „ test
” i „ build
”). Dodałem je do Netbeans za pomocą przycisku „ Dodaj JAR / Folder ” we właściwościach projektu i są one wymienione w dokładnej kolejności jak na powyższej liście. Projekt jest standardowym projektem typu „aplikacja Java”.
Ponadto projekt Netbeans jest skonfigurowany tak, aby „ NIE kompilować przy zapisywaniu ”, „ generować informacje o debugowaniu ”, „ raportować przestarzałe interfejsy API ”, „ śledzić zależności java ”, „ przetwarzać adnotacje aktywowane ” i „ przetwarzać adnotacje aktywowane w edytorze ”. W Netbeans nie jest jawnie konfigurowany żaden procesor ani opcja przetwarzania adnotacji. Ponadto -Xlint:all
opcja wiersza polecenia „ ” jest przekazywana w wierszu poleceń kompilatora, a kompilator działa na zewnętrznej maszynie wirtualnej.
Wersja mojego javaca to 1.8.0_72, a moja wersja java to 1.8.0_72-b15. Mój Netbeans to 8.1.
Mój projekt dobrze się kompiluje. Jednak w jej wykonaniu zgłasza wyjątek. Wyjątkiem nie wydaje się być coś, co wygląda na łatwe lub oczywiste do naprawienia. Oto wynik, w tym ślad stosu:
TestFoo(x=b, z=5)
{"z":5,"xoom":"a"}
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Argument #0 of constructor [constructor for testelombok.TestFoo, annotations: {interface java.beans.ConstructorProperties=@java.beans.ConstructorProperties(value=[x, z]), interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
at [Source: {"z":5,"xoom":"a"}; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:296)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:269)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:475)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3890)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3785)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2833)
at testelombok.TestLombok.main(TestLombok.java:14)
Caused by: java.lang.IllegalArgumentException: Argument #0 of constructor [constructor for testelombok.TestFoo, annotations: {interface java.beans.ConstructorProperties=@java.beans.ConstructorProperties(value=[x, z]), interface com.fasterxml.jackson.annotation.JsonCreator=@com.fasterxml.jackson.annotation.JsonCreator(mode=DEFAULT)}] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addDeserializerConstructors(BasicDeserializerFactory.java:511)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:323)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:253)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:219)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:141)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:406)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:352)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 7 more
Próbowałem już losowo grzebać w adnotacjach @Value
i @AllArgsConstructor
, ale nie mogłem tego ulepszyć.
Wyszukałem w Google wyjątek i znalazłem stary raport o błędzie w serwisie Jackson i kolejny, który jest otwarty, ale wydaje się być powiązany z czymś innym . Jednak to nadal nie mówi nic o tym, czym jest ten błąd ani jak go naprawić. Poza tym nie mogłem znaleźć niczego użytecznego, szukając tego gdzie indziej.
Ponieważ to, co próbuję zrobić, to bardzo podstawowe użycie zarówno lomboka, jak i jacksona, wydaje się dziwne, że nie mogłem znaleźć żadnych bardziej przydatnych informacji o tym, jak obejść ten problem. Może coś przegapiłem?
Oprócz powiedzenia „ nie używaj lomboka ” lub „ nie używaj jackson ”, czy ktoś ma jakiś pomysł, jak to rozwiązać?