Класс отсутствует в доверенных пакетах, хотя отображается в списке доверенных пакетов.
Я пытаюсь реализовать простую связь Kafka между двумя различными приложениями Spring Boot без каких-либо специальных настроек, это приложение имеет только один kafkalistener. Мой yml для потребителя выглядит следующим образом:
spring:
kafka:
bootstrap-servers: ip_here
topic:
json: topic_here
consumer:
group-id: group_id
auto-offset-reset: earliest
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring:
json:
trusted:
packages: 'com.example.kw.dtos.Classdata'
Я получаю следующую ошибку:
Причина: java.lang.IllegalArgumentException: Класс 'com.example.kw.dtos.Classdata' отсутствует в доверенных пакетах: [java.util, java.lang, com.example.kw.dtos.Classdata]. Если вы считаете, что этот класс безопасен для десериализации, укажите его имя. Если сериализация выполняется только доверенным источником, вы также можете включить доверять всем (*).
Пакет находится в доверенных пакетах, но что-то не так.
Мой заводской класс:
@Configuration
@EnableKafka
public class MsgListener {
@Value("${spring.kafka.bootstrap-servers}")
private String bootstrapServers;
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
props.put(ConsumerConfig.GROUP_ID_CONFIG, "json");
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.example.kw.dtos.Classdata");
return props;
}
@Bean
public ConsumerFactory<String, Classdata> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(
consumerConfigs(),
new StringDeserializer(),
new JsonDeserializer<>(Classdata.class));
}
@Bean
public ConcurrentKafkaListenerContainerFactory<String, Classdata> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, Classdata> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
return factory;
}
}
2 ответа
Это должен быть только пакет com.example.kw.dtos
String packageName = ClassUtils.getPackageName(requestedType).replaceFirst("\\[L", "");
for (String trustedPackage : this.trustedPackages) {
if (packageName.equals(trustedPackage)) {
return true;
}
}
У нас была эта проблема при тестировании кафки. Мы исправили это так:
private static KafkaMessageListenerContainer<String, Data> createMessageListenerContainer() {
final Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("sender", "false", EMBEDDED_KAFKA);
final DefaultKafkaConsumerFactory<String, VoterData> consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps);
final JsonDeserializer<VoterData> valueDeserializer = new JsonDeserializer<>();
valueDeserializer.addTrustedPackages("path.to.package");
consumerFactory.setValueDeserializer(valueDeserializer);
consumerFactory.setKeyDeserializer(new StringDeserializer());
final ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC);
return new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);
}
Хитрость здесь в том, что вы должны установить его в двух местах
- spring.json.trusted.packages - для любых десериализаторов json, созданных вне влияния кафки
- spring.kafka.consumer.properties.spring.json.trusted.packages - для десериализаторов, созданных kafka
Это был единственный способ заставить его работать. Кроме того, он не принимает подстановочные знаки, поэтому он должен точно соответствовать пакету.