Например, вот (правильная) сериализованная форма при запуске с Неубийный код :
Код: Выделить всё
{
"owner" : "Jay Leno",
"cars" : [ {
"type" : "Corvette",
"name" : "Corvette",
"year" : 1963
}, {
"type" : "Aztek",
"name" : "Ugly",
"year" : 2003
} ]
}
< /code>
Вот вывод того же кода после прохождения через Proguard: < /p>
{
"owner" : "Jay Leno",
"cars" : [ {
"a" : 1963,
"name" : "Corvette"
}, {
"a" : 2003,
"name" : "Ugly"
} ]
}
Вот MRE кода; Извините за то, что включил в вопрос столько кода, но это настолько минимально, насколько я мог бы получить, и все еще продемонстрировать контекст и проблему. Project. < /p>
Код: Выделить всё
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Corvette.class),
@JsonSubTypes.Type(value = Aztek.class)
})
public abstract class CarModel {
public abstract String getName();
public abstract int getYear();
}
@Getter
@AllArgsConstructor
@ToString
public class Corvette extends CarModel {
private int year;
@JsonCreator
public Corvette(@JsonProperty("name") String name, @JsonProperty("year") int year) {
this.year = year;
}
@Override
@ToString.Include
public String getName() {
return "Corvette";
}
}
@Getter
@Setter
@AllArgsConstructor
@ToString
public class Aztek extends CarModel {
private int year;
@JsonCreator
public Aztek(@JsonProperty("name") String name, @JsonProperty("year") int year) {
this.year = year;
}
@Override
@ToString.Include
public String getName() {
return "Ugly";
}
}
@Getter
public class Inventory {
private String owner;
private List cars;
@JsonCreator
public Inventory(@JsonProperty("owner") String owner, @JsonProperty("cars") List cars) {
this.owner = owner;
this.cars = cars;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("Inventory [");
builder.append("owner=")
.append(owner)
.append(", cars=");
builder.append("]");
return builder.toString();
}
}
public class JacksonPolymorphicSerialization {
private final static ObjectMapper JSONMapper =
JsonMapper.builder()
.configure(DEFAULT_VIEW_INCLUSION, false)
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
.serializationInclusion(Include.NON_ABSENT)
.build();
private static final ObjectReader JSONReader = JSONMapper.readerFor(Inventory.class);
private static final ObjectWriter JSONWriter = JSONMapper.writerFor(Inventory.class).withDefaultPrettyPrinter();
public static void main(String[] args) throws JacksonException {
Corvette corvette = new Corvette(1963);
Aztek aztek = new Aztek(2003);
Inventory inventory = new Inventory("Jay Leno", List.of(corvette, aztek));
String json = JSONWriter.writeValueAsString(inventory);
System.out.println("Serialized form:\n" + json);
System.out.println();
inventory = JSONReader.readValue(json);
System.out.println("Deserialized object: " + inventory);
}
}
< /code>
Вот файл строительства Gradle < /p>
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.guardsquare:proguard-gradle:7.6.1'
}
}
plugins {
id 'java'
id "io.freefair.lombok" version "8.12.1"
}
repositories {
mavenCentral()
}
def appMainClass = 'rizzo.test.JacksonPolymorphicSerialization'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
jar {
duplicatesStrategy = 'exclude'
manifest {
attributes 'Main-Class': "${appMainClass}"
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
dependencies {
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.18.2'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.18.2'
}
task proguard(type: proguard.gradle.ProGuardTask) {
dependsOn classes
verbose
printmapping "${buildDir}/proguard-mapping.txt"
injars "${buildDir}/classes/java/main"
outjars "${buildDir}/classes/obfuscated/"
libraryjars "${System.getProperty('java.home')}/jmods/java.base.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
libraryjars "${System.getProperty('java.home')}/jmods/java.logging.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
libraryjars "${System.getProperty('java.home')}/jmods/java.desktop.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
libraryjars "${System.getProperty('java.home')}/jmods/java.xml.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
libraryjars "${System.getProperty('java.home')}/jmods/java.sql.jmod", jarfilter: '!**.jar', filter: '!module-info.class'
// This will contain the app dependencies.
libraryjars sourceSets.main.compileClasspath
keepdirectories
// Preserve getters and setters
keepclassmembers 'class * { \
** get*(); \
void set*(***); \
}'
// Keep the main class entry point.
keep "public class ${appMainClass} { \
public static void main(java.lang.String[]); \
}"
// This helps produce useful stack traces (see https://www.guardsquare.com/manual/configuration/examples#stacktrace)
renamesourcefileattribute 'SourceFile'
keepattributes '*Annotation*,EnclosingMethod,SourceFile,LineNumberTable'
doLast {
delete "${buildDir}/classes/java/main"
copy {
from "${buildDir}/classes/obfuscated/"
into "${buildDir}/classes/java/main"
}
}
}
Вот что происходит с каждым. p>
Код: Выделить всё
> java -jar build/libs/ProguardJacksonTest.jar
Serialized form:
{
"owner" : "Jay Leno",
"cars" : [ {
"type" : "Corvette",
"name" : "Corvette",
"year" : 1963
}, {
"type" : "Aztek",
"name" : "Ugly",
"year" : 2003
} ]
}
First cars element is of type class rizzo.test.Corvette
Deserialized object: Inventory [owner=Jay Leno, cars=]
< /code>
Вывод с использованием запутанной сборки: < /p>
> java -jar build/libs/ProguardJacksonTest.jar
Serialized form:
{
"owner" : "Jay Leno",
"cars" : [ {
"a" : 1963,
"name" : "Corvette"
}, {
"a" : 2003,
"name" : "Ugly"
} ]
}
Exception in thread "main" java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class rizzo.test.b (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; rizzo.test.b is in unnamed module of loader 'app')
at rizzo.test.d.toString(SourceFile:29)
at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
at java.base/java.lang.StringConcatHelper.simpleConcat(StringConcatHelper.java:408)
at rizzo.test.JacksonPolymorphicSerialization.main(SourceFile:38)
Подробнее здесь: https://stackoverflow.com/questions/794 ... phic-types