Skip to content

[BUG] @Valid TYPE_USE bean validation annotation on builder causes issues on JBoss EAP 7.4 #19188

@jpraet

Description

@jpraet
Description

Similar to #17875. The applied fix does not entirely solve the issue.

Related to #17874, the @Valid bean validation annotation also gets added on TYPE_USE in the builder.

  public static PartnersRestBuilder<?, ?> builder() {
    return new PartnersRestBuilderImpl();
  }

  private static class PartnersRestBuilderImpl extends PartnersRestBuilder<PartnersRest, PartnersRestBuilderImpl> {

    @Override
    protected PartnersRestBuilderImpl self() {
      return this;
    }

    @Override
    public PartnersRest build() {
      return new PartnersRest(this);
    }
  }

  public static abstract class PartnersRestBuilder<C extends PartnersRest, B extends PartnersRestBuilder<C, B>>  {
    private List<@Valid PartnerRest> items = new ArrayList<>();
    private Integer total;
    protected abstract B self();

    public abstract C build();

    public B items(List<@Valid PartnerRest> items) {
      this.items = items;
      return self();
    }
    public B total(Integer total) {
      this.total = total;
      return self();
    }
  }
}
PartnersRest.java
package be.fgov.kszbcss.tad.admin.rest.model;

import be.fgov.kszbcss.tad.admin.rest.model.PartnerRest;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.io.Serializable;
import javax.validation.constraints.*;
import javax.validation.Valid;

import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.annotation.JsonTypeName;



@JsonTypeName("Partners")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaJAXRSSpecServerCodegen", date = "2024-07-17T13:55:57.807731525+02:00[Europe/Brussels]", comments = "Generator version: 7.7.0")
public class PartnersRest  implements Serializable {
  private @Valid List<@Valid PartnerRest> items = new ArrayList<>();
  private Integer total;

  protected PartnersRest(PartnersRestBuilder<?, ?> b) {
    this.items = b.items;
    this.total = b.total;
  }

  public PartnersRest() {
  }

  /**
   **/
  public PartnersRest items(List<@Valid PartnerRest> items) {
    this.items = items;
    return this;
  }

  
  @JsonProperty("items")
  @NotNull @Valid public List<@Valid PartnerRest> getItems() {
    return items;
  }

  @JsonProperty("items")
  public void setItems(List<@Valid PartnerRest> items) {
    this.items = items;
  }

  public PartnersRest addItemsItem(PartnerRest itemsItem) {
    if (this.items == null) {
      this.items = new ArrayList<>();
    }

    this.items.add(itemsItem);
    return this;
  }

  public PartnersRest removeItemsItem(PartnerRest itemsItem) {
    if (itemsItem != null && this.items != null) {
      this.items.remove(itemsItem);
    }

    return this;
  }
  /**
   **/
  public PartnersRest total(Integer total) {
    this.total = total;
    return this;
  }

  
  @JsonProperty("total")
  public Integer getTotal() {
    return total;
  }

  @JsonProperty("total")
  public void setTotal(Integer total) {
    this.total = total;
  }


  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    PartnersRest partners = (PartnersRest) o;
    return Objects.equals(this.items, partners.items) &&
        Objects.equals(this.total, partners.total);
  }

  @Override
  public int hashCode() {
    return Objects.hash(items, total);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class PartnersRest {\n");
    
    sb.append("    items: ").append(toIndentedString(items)).append("\n");
    sb.append("    total: ").append(toIndentedString(total)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }


  public static PartnersRestBuilder<?, ?> builder() {
    return new PartnersRestBuilderImpl();
  }

  private static class PartnersRestBuilderImpl extends PartnersRestBuilder<PartnersRest, PartnersRestBuilderImpl> {

    @Override
    protected PartnersRestBuilderImpl self() {
      return this;
    }

    @Override
    public PartnersRest build() {
      return new PartnersRest(this);
    }
  }

  public static abstract class PartnersRestBuilder<C extends PartnersRest, B extends PartnersRestBuilder<C, B>>  {
    private List<@Valid PartnerRest> items = new ArrayList<>();
    private Integer total;
    protected abstract B self();

    public abstract C build();

    public B items(List<@Valid PartnerRest> items) {
      this.items = items;
      return self();
    }
    public B total(Integer total) {
      this.total = total;
      return self();
    }
  }
}

This somehow causes an issue on JBoss EAP 7.4.

I guess the presence of the @Valid annotation causes the container to treat the builder as a CDI bean?

Before #18724:

org.jboss.weld.exceptions.DeploymentException: WELD-001503: Bean class which has interceptors cannot be declared final:  class be.fgov.kszbcss.tad.admin.rest.model.PartnersRest$PartnersRestBuilderImpl

After #18724 (which attempted to fix the issue by making the builder class non-final):

org.jboss.weld.exceptions.DeploymentException: WELD-001436: Type be.fgov.kszbcss.tad.admin.rest.model.PartnersRest$PartnersRestBuilderImpl is not proxyable because it has a private constructor [EnhancedAnnotatedConstructorImpl] private be.fgov.kszbcss.tad.admin.rest.model.PartnersRest$PartnersRestBuilderImpl() - class be.fgov.kszbcss.tad.admin.rest.model.PartnersRest$PartnersRestBuilderImpl.""
openapi-generator version

OK in 7.1.0, broken from 7.2.0 onward.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions