2016-09-08 3 views
13

Ich experimentiere mit Jackson und Lombok. Das sind meine Klassen:Ich kann nicht machen, dass Jackson und Lombok zusammenarbeiten

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([email protected]__(@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); 
    } 

} 

Das sind die JAR-Dateien, die ich hinzufüge, in die classpth:

ich es mit Netbeans bin kompilieren (ich glaube nicht, dass dies wirklich relevant ist, aber ich berichte diese trotzdem, um es perfekt und genau reproduzierbar zu machen). Die fünf obigen JARs befinden sich in einem Ordner namens "lib" innerhalb des Projektordners (zusammen mit "src", "nbproject", "test" und "build"). Ich habe sie zu Netbeans über die Schaltfläche "Add JAR/Folder" in den Projekteigenschaften hinzugefügt und sie sind in der genauen Reihenfolge wie die obige Liste aufgeführt. Das Projekt ist ein Standardprojekt vom Typ "Java-Anwendung".

Ferner wird das Netbeans-Projekt konfiguriert "kompilieren auf nicht retten", "erzeugen info Debuggen", "Bericht APIs als veraltet", "Spur java Abhängigkeiten", "activacte Annotation processing "und" activacte annotation processing im Editor ". In Netbeans ist keine Annotationsprozessor- oder Annotationsverarbeitungsoption explizit konfiguriert. Außerdem wird die Befehlszeilenoption "-Xlint:all" in der Compilerbefehlszeile übergeben und der Compiler wird auf einer externen VM ausgeführt.

Meine Version von javac ist 1.8.0_72 und meine Version von Java ist 1.8.0_72-b15. Meine Netbeans ist 8.1.

Mein Projekt kompiliert gut. Es löst jedoch eine Ausnahme in seiner Ausführung aus. Die Ausnahme scheint nichts zu sein, das leicht oder offensichtlich reparierbar aussieht. Hier ist die Ausgabe, einschließlich der Stacktrace:

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 [email protected]es(value=[x, z]), interface [email protected]son.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 [email protected]es(value=[x, z]), interface [email protected]son.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 

Ich habe bereits versucht über zufällig mit den @Value und @AllArgsConstructor Anmerkungen Stossen, aber ich konnte nicht machen es besser.

Ich google die Ausnahme und found an old bug report on jackson und another one that is open, but seems to be related to something else. Dies sagt jedoch nichts darüber aus, was dieser Fehler ist oder wie er behoben werden kann. Außerdem konnte ich nirgendwo etwas Nützliches finden.

Da, was ich versuche zu tun ist sehr grundlegende Verwendung von beiden Lombok und Jackson, scheint es seltsam, dass ich keine weiteren nützlichen Informationen zur Umgehung dieses Problems finden konnte. Vielleicht habe ich etwas verpasst?

Andere als nur zu sagen „nicht verwenden lombok“ oder „nicht jackson verwenden“, tut jemand eine Ahnung hat, wie diese zu lösen?

Antwort

1

Sie können Jackson mit fast allem spielen, wenn Sie seine "mixin" pattern verwenden. Im Grunde gibt es Ihnen eine Möglichkeit, Jackson-Anmerkungen zu einer vorhandenen Klasse hinzuzufügen, ohne diese Klasse tatsächlich zu ändern. Ich lehne es eher an, es hier zu empfehlen, als eine Lombok-Lösung, weil dies ein Problem löst, das Jackson mit einem Jackson-Feature hat, also ist es wahrscheinlicher, dass es langfristig funktioniert.

4

Ich hatte genau das gleiche Problem, „gelöst“ es durch Zugabe des suppressConstructorProperties = true Parameter (Ihr Beispiel verwenden):

@Value 
@Wither 
@AllArgsConstructor(suppressConstructorProperties = true) 
public class TestFoo { 
    @JsonProperty("xoom") 
    private String x; 
    private int z; 
} 

Jackson offenbar nicht die java.beans.ConstructorProperties Anmerkung zu Konstrukteuren mag hinzugefügt. Der suppressConstructorProperties = true Parameter teilt Lombok mit, es nicht hinzuzufügen (es tut es standardmäßig).

+3

'suppressConstructorProperties' jetzt :-( – lilalinux

0

Ich habe alle meine Klassen wie folgt kommentierte:

@JsonAutoDetect(fieldVisibility = Visibility.ANY) 
@JsonInclude(JsonInclude.Include.NON_DEFAULT) 
@Data 
@Accessors(fluent = true) 
@NoArgsConstructor 
@AllArgsConstructor 

es mit allen Lombok und Jackson Versionen gearbeitet, zumindest ein paar Jahren.

Beispiel:

@JsonAutoDetect(fieldVisibility = Visibility.ANY) 
@JsonInclude(JsonInclude.Include.NON_DEFAULT) 
@Data 
@Accessors(fluent = true) 
@NoArgsConstructor 
@AllArgsConstructor 
public class Person { 
    String id; 
    String first; 
    String last; 
} 

Und das ist es. Lombok und Jackson spielen zusammen wie ein Zauber.

0
@JsonInclude(JsonInclude.Include.NON_NULL) 
@Data 
public class Person { 
    String id; 
    String first; 
    String last; 
} 

Zusätzlich zur Datenklasse sollte der ObjectMapper korrekt konfiguriert sein. In diesem Fall funktioniert es ok mit einer ParameterNamesModule Konfiguration und die Sichtbarkeit der Felder Einstellung und Schöpfer Methoden

om.registerModule(new ParameterNamesModule()); 
    om.setVisibility(FIELD, JsonAutoDetect.Visibility.ANY); 
    om.setVisibility(CREATOR, JsonAutoDetect.Visibility.ANY); 

sollte es dann wie erwartet.

2

@AllArgsConstructor(suppressConstructorProperties = true) ist veraltet. Definieren Sie lombok.anyConstructor.suppressConstructorProperties=true (https://projectlombok.org/features/configuration) und ändern Sie POJO's Lombok Annotation von @Value zu @Data + @NoArgsConstructor + @AllArgsConstructor funktioniert für mich.

-1

Wenn Sie möchten, aber ein json serialisierbar POJO mit Lombok und Jackson. Verwenden Sie jacksons neue Annotation auf Ihrem Lomboks Builder @JsonPOJOBuilder (withPrefix = "") Ich habe diese Lösung versucht und es funktioniert sehr gut. Verwendungsbeispiel

import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 
    import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; 
    import lombok.*; 

    @JsonDeserialize(builder = Detail.DetailBuilder.class) 

    @Value 

@Builder 
public class Detail { 

    private String url; 
    private String userName; 
    private String password; 
    private String scope; 

    @JsonPOJOBuilder(withPrefix = "") 
    public static class DetailBuilder { 

    } 
} 
+0

veraltet ist ein Link zu einer Lösung ist willkommen, aber bitte sicher, dass Ihre Antwort ist nützlich, ohne es: [add Kontext rund um den Link] (// meta.stackexchange .com/a/8259) Damit Ihre Mitbenutzer eine Vorstellung davon haben, was es ist und warum es dort ist, dann zitieren Sie den relevantesten Teil der Seite, auf die Sie verlinken, falls die Zielseite nicht verfügbar ist mehr als ein Link kann gelöscht werden.] (// stackoverflow.com/help/deleted-answers) – geisterfurz007

+0

Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz zur Verfügung zu stellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - [Aus Bewertung] (/ review/low-quality-posts/18828665) – JimHawkins

+1

Link entfernt und die funktionierende Probe von mir hinzugefügt –

Verwandte Themen