我正在使用 Fabric8 对各种 K8S 自定义资源执行 CRUD 操作。当读取资源并尝试检索其
spec
时,我在 ClassCastException
和定义资源规范的 POJO 之间遇到 RawExtension
MyCRDSpec
java.lang.ClassCastException: class io.fabric8.kubernetes.api.model.runtime.RawExtension cannot be cast to class my.package.MyCRDSpec
自定义资源类
@Group("my.group")
@Version("v1alpha1")
public class MyCRD extends CustomResource<MyCRDSpec, MyCRDStatus> implements
Namespaced {
}
规格POJO
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MyCRDSpec implements KubernetesResource {
private String id;
private String name;
...
}
POJO 状态
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyCRDStatus implements KubernetesResource {
private String msg;
}
这就是我阅读资源并尝试检索
spec
的方式
try (final KubernetesClient client = new KubernetesClientBuilder().build()) {
final MixedOperation<MyCRD, KubernetesResourceList<MyCRD>, Resource<MyCRD>> crdClient =
client.resources(MyCRD.class);
final MyCRD crd= crdClient.inNamespace("ns").withName("my-existing-custom-resource-name").get();
return crd.getSpec().getName();
}
检索规范的原因是我希望能够使用自定义资源中包含的属性映射到域对象。然而,我每次都会遇到这个
ClassCastException
。记录 getSpec()
的完整结果表明它似乎绑定到 RawExtension
而不是预期的 MyCRDSpec
spec=RawExtension(super=AnyType(value={...}))
到目前为止,我一直在遵循 this 和 this 作为指南。我也尝试过更改我的客户端配置,但没有任何结果。
我没有包含 CRD yaml 定义或如何创建自定义资源,因为该功能按预期工作,但它与我上面和这些指南中的代码非常相似。我可以毫无问题地查看 CRD 和我在集群中创建的资源。
我正在使用
spring-cloud-kubernetes-fabric8-all
版本 3.1.0
和 JDK 21。
编辑
ClassCastException
还包含有关类加载器的错误
io.fabric8.kubernetes.api.model.runtime.RawExtension and my.package.MyCRDSpec are in unnamed module of loader org.springframework.boot.loader.launch.LaunchedClassLoader
检查了这个问题中的一些答案后,我尝试用手动 getter/setter 替换 Lombok 注释,但这没有什么区别。
编辑2
进步。用
MyCRDSpec
注释 @JsonDeserialize()
可以解决问题。问题是,为什么我需要这样做?Fabric8 客户端中是否有某些内容意外或不正确地设置了自定义反序列化器?
您不需要使用
MyCRDSpec
来扩展 MyCRDStatus
和 KubernetesResource
。使用此类扩展它们似乎将其注册到 KubernetesDeserializer,尝试将其映射为实际的 Kubernetes 资源(如 Deployment、Pod 等)。通过添加 @JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class)
解决了该问题,因为这将 Jackson 配置为不使用 KubernetesDeserializer。