Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@AutoValue is not compatible with validation 2.0's @Valid #682

Closed
findepi opened this issue Nov 22, 2018 · 5 comments
Closed

@AutoValue is not compatible with validation 2.0's @Valid #682

findepi opened this issue Nov 22, 2018 · 5 comments
Assignees

Comments

@findepi
Copy link

findepi commented Nov 22, 2018

Same as #288 but for Validation 2.0 (javax.validation:validation-api:2.0.1.Final) annotation.

Consider class:

@AutoValue
public abstract class MyClass
{
    @Valid
    @AutoValue.CopyAnnotations(exclude = Valid.class) // this is ineffective
    public abstract Optional<@NotEmpty String> getFoo();

    public static MyClass create(Optional<String> newFoo)
    {
        return new AutoValue_MyClass(newFoo);
    }
}

@CopyAnnotations works for validation 1.0 annotation but does not work for validation 2.0 (javax.validation:validation-api:2.0.1.Final).
There:

@Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
public @interface Valid {
}

@CopyAnnotations javadoc says that TYPE_USE annotations are copied regardless:

@Generated("com.google.auto.value.processor.AutoValueProcessor")
final class AutoValue_MyClass extends MyClass {
  ...
  @Override
  public @Valid Optional<String> getFoo() {
    return foo;
  }
  ....

This breaks validation (using Apache BVal):

javax.validation.ConstraintDeclarationException: Multiple method return values marked @Valid in hierarchy [Meta.ForMethod(public abstract java.util.Optional com.example.MyClass.getFoo()), Meta.ForMethod(public java.util.Optional com.example.AutoValue_MyClass.getFoo())]

	at org.apache.bval.jsr.metadata.Liskov.noRedeclarationOfReturnValueCascading(Liskov.java:172)
	at org.apache.bval.jsr.metadata.Liskov.validateContainerHierarchy(Liskov.java:118)
	at org.apache.bval.jsr.metadata.HierarchyBuilder$ForContainer.<init>(HierarchyBuilder.java:302)
	at org.apache.bval.jsr.metadata.HierarchyBuilder.forContainer(HierarchyBuilder.java:372)
	at org.apache.bval.jsr.metadata.CompositeBuilder$ForExecutable.getReturnValue(CompositeBuilder.java:204)
	at org.apache.bval.jsr.descriptor.MetadataReader$ForExecutable.getReturnValueDescriptor(MetadataReader.java:367)
	at org.apache.bval.jsr.descriptor.ExecutableD.<init>(ExecutableD.java:43)
	at org.apache.bval.jsr.descriptor.MethodD.<init>(MethodD.java:32)
	at org.apache.bval.jsr.descriptor.MetadataReader$ForBean.lambda$getMethods$6(MetadataReader.java:190)
	at java.util.HashMap.forEach(HashMap.java:1289)
	at org.apache.bval.jsr.descriptor.MetadataReader$ForBean.getMethods(MetadataReader.java:186)
	at org.apache.bval.jsr.descriptor.BeanD.<init>(BeanD.java:56)
	at org.apache.bval.jsr.descriptor.DescriptorManager.getBeanDescriptor(DescriptorManager.java:81)
	at org.apache.bval.jsr.job.ValidationJob.getBeanDescriptor(ValidationJob.java:577)
	at org.apache.bval.jsr.job.ValidationJob.access$200(ValidationJob.java:81)
	at org.apache.bval.jsr.job.ValidationJob$BeanFrame.<init>(ValidationJob.java:246)
	at org.apache.bval.jsr.job.ValidationJob$BeanFrame.<init>(ValidationJob.java:242)
	at org.apache.bval.jsr.job.ValidateBean.computeBaseFrame(ValidateBean.java:40)
	at org.apache.bval.jsr.job.ValidationJob.getResults(ValidationJob.java:555)
	at org.apache.bval.jsr.ValidatorImpl.validate(ValidatorImpl.java:53)

Expected behavior

com.google.auto.value.AutoValue.CopyAnnotations#exclude should be honored, so that user remains in control of the annotations output in the generated class.

@eamonnmcmanus
Copy link
Member

To my mind the check that BVal is performing is not legitimate. The return type of the abstract method is @Valid Optional<@NotEmpty String>, and AutoValue is correctly copying that type to the implementation. If @Valid were supposed to apply to a single method in the hierarchy (so to the abstract method but not its override) then it would have METHOD but not TYPE_USE as its @Target.

I do think it's a bug that AutoValue isn't copying the @NotEmpty from the type argument of Optional.

@eamonnmcmanus eamonnmcmanus self-assigned this Nov 27, 2018
@findepi
Copy link
Author

findepi commented Nov 27, 2018

@eamonnmcmanus it might be that my particular problem could be solved on bval's side alone. I don't know enough yet to judge this.

However, I see no reason why I, as an @AutoValue user, should be left with no control over annotations in the generated subclass. Especially when the mechanism to control these already exists -- @CopyAnnotations(exclude = ...).
In the code, I am saying explicitly "hey, @AutoValue, do not copy this annotation over there" and @AutoValue is saying "ekhm, I just know better, I choose to disobey you".

@eamonnmcmanus
Copy link
Member

Right now AutoValue considers that type annotations on the return value of an abstract property method are part of the property type, and it copies them everywhere that type is mentioned in the generated code: on the return type of the implementing method, as we have seen, but also on the type of the private field that holds the property value, and on the type of the corresponding constructor parameter or builder field. We could extend the meaning of @CopyAnnotations so that it allows you to prevent an annotation from being copied in these contexts, though I'm concerned that the specification of @CopyAnnotations would then be even more complicated than it already is. If we don't do that then we should at least make it an error to try to exclude a type annotation. I agree that the current behaviour of just ignoring the exclusion is not good.

@tbroyer
Copy link
Contributor

tbroyer commented Nov 27, 2018

Given that annotations with both TYPE_USE and METHOD apply to both the return type and the method, how about honoring @CopyAnnotations(exclude = …) for those annotations?

But then of course, I too do think BVal is wrong (and/or it was a mistake to make @Valid a type annotation in Bean Validation 2.0; they probably should have added a new annotation instead that would have only been a type annotation, I suppose they did it that way for backwards compatibility…)

@eamonnmcmanus
Copy link
Member

OK, I suppose it does make sense for AutoValue to omit an annotation that it has been explicitly told to, even when that annotation is a type annotation. I continue to think that for this to happen there must be a problem elsewhere, but I've made the change anyway and it will be present in the next release.

@ronshapiro ronshapiro mentioned this issue Jan 3, 2019
ronshapiro pushed a commit that referenced this issue Jan 3, 2019
Do not copy a type annotation from an abstract property method of an @autovalue class to the implementation of that method, if there is also a @CopyAnnotations annotation that excludes the type annotation.

Fixes #682.

RELNOTES=In AutoValue, @CopyAnnotations.exclude now affects type annotations.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=227527442
copybara-service bot pushed a commit that referenced this issue Sep 10, 2024
Bumps the github-actions group with 1 update: [actions/setup-java](https://github.com/actions/setup-java).

Updates `actions/setup-java` from 4.2.2 to 4.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/setup-java/releases">actions/setup-java's releases</a>.</em></p>
<blockquote>
<h2>v4.3.0</h2>
<p>What's Changed</p>
<ul>
<li>Add support for SapMachine JDK/JRE by <a href="https://github.com/Shegox"><code>@​Shegox</code></a> in <a href="https://redirect.github.com/actions/setup-java/issues/614">#614</a></li>
</ul>
<pre lang="yaml"><code>steps:
 - name: Checkout
   uses: actions/checkout@v4
 - name: Setup-java
   uses: actions/setup-java@v4
   with:
     distribution: ‘sapmachine’
     java-version: ’21’
</code></pre>
<p>Bug fixes :</p>
<ul>
<li>
<pre><code>Fix typos on Corretto by @johnshajiang in [#666](actions/setup-java#666)
</code></pre>
</li>
<li>
<pre><code>IBM Semeru Enhancement on arm64 by @mahabaleshwars in [#677](actions/setup-java#677)
</code></pre>
</li>
<li>
<pre><code>Resolve Basic Validation Check Failures by @aparnajyothi-y
 in [#682](actions/setup-java#682)
</code></pre>
</li>
</ul>
<p>New Contributors :</p>
<ul>
<li>
<pre><code>@johnshajiang made their first contribution in [#666](actions/setup-java#666)
</code></pre>
</li>
<li>
<pre><code>@Shegox made their first contribution in [#614](actions/setup-java#614)
</code></pre>
</li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-java/compare/v4...v4.3.0">https://github.com/actions/setup-java/compare/v4...v4.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/setup-java/commit/2dfa2011c5b2a0f1489bf9e433881c92c1631f88"><code>2dfa201</code></a> basic validation failure fix (<a href="https://redirect.github.com/actions/setup-java/issues/682">#682</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/7467385c615a13cecd14d5768e738332968d0792"><code>7467385</code></a> feat: add support for SapMachine JDK/JRE (<a href="https://redirect.github.com/actions/setup-java/issues/614">#614</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/8e04ddff28554375a9a1096c888a2ef2c9803cd7"><code>8e04ddf</code></a> Update Error Messages and Fix Architecture Detection for IBM Semeru (<a href="https://redirect.github.com/actions/setup-java/issues/677">#677</a>)</li>
<li><a href="https://github.com/actions/setup-java/commit/67fbd726daaf08212a7b021c1c4d117f94a81dd3"><code>67fbd72</code></a> Fix typos on Corretto (<a href="https://redirect.github.com/actions/setup-java/issues/665">#665</a>) (<a href="https://redirect.github.com/actions/setup-java/issues/666">#666</a>)</li>
<li>See full diff in <a href="https://github.com/actions/setup-java/compare/6a0805fcefea3d4657a47ac4c165951e33482018...2dfa2011c5b2a0f1489bf9e433881c92c1631f88">compare view</a></li>
</ul>
</details>
<br />

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-java&package-manager=github_actions&previous-version=4.2.2&new-version=4.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions

</details>

Fixes #1834

COPYBARA_INTEGRATE_REVIEW=#1834 from google:dependabot/github_actions/github-actions-bc3bba8501 ab1fc54
PiperOrigin-RevId: 672948325
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants