opened
hgschmie
username_0
Similar to what was mentioned in #201, a problem with e.g. Jackson is that the generated classes (e.g. Foo_AutoValue) are package private. When turning off the "make the class accessible feature" with `objectMapper.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS);`
will lead to exceptions where Jackson claims it can not execute a public method on such a bean:

```
 java.lang.IllegalAccessException: Class com.fasterxml.jackson.databind.ser.BeanPropertyWriter can not access a member of class com.zuora.owl.testbed.db.entity.AutoValue_NationEntity with modifiers "public"
! at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
! at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
! at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
! at java.lang.reflect.Method.invoke(Method.java:491)
! at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:687)
! at com.fasterxml.jackson.module.afterburner.ser.ObjectMethodPropertyWriter.serializeAsField(ObjectMethodPropertyWriter.java:40)
! at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
```

while the implemented abstract method in the parent bean is public:

```java
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;

import java.util.UUID;

@AutoValue
public abstract class NationEntity implements Entity {

    public static NationEntity create(
            @JsonProperty("id") long id,
            @JsonProperty("nationKey") UUID nationKey,
            @JsonProperty("name") String name,
            @JsonProperty("regionKey") UUID regionKey,
            @JsonProperty("comment") String comment) {
        return new AutoValue_NationEntity(id, nationKey, name, regionKey, comment);
    }

    @JsonProperty(required = true)
    public abstract long getId();

    @JsonProperty(required = true)
    public abstract UUID getNationKey();

    @JsonProperty(required = true)
    public abstract String getName();

    @JsonProperty(required = true)
    public abstract UUID getRegionKey();

    @JsonProperty(required = true)
    public abstract String getComment();
}
```

and also in the generated class, the class itself is package private:

``` 
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.UUID;
import javax.annotation.Generated;

@Generated("com.google.auto.value.processor.AutoValueProcessor")
 final class AutoValue_NationEntity extends NationEntity {

  private final long id;
  private final UUID nationKey;
  private final String name;
  private final UUID regionKey;
  private final String comment;

  AutoValue_NationEntity(
      long id,
      UUID nationKey,
      String name,
      UUID regionKey,
      String comment) {
    this.id = id;
    if (nationKey == null) {
      throw new NullPointerException("Null nationKey");
    }
    this.nationKey = nationKey;
    if (name == null) {
      throw new NullPointerException("Null name");
    }
    this.name = name;
    if (regionKey == null) {
      throw new NullPointerException("Null regionKey");
    }
    this.regionKey = regionKey;
    if (comment == null) {
      throw new NullPointerException("Null comment");
    }
    this.comment = comment;
  }

  @JsonProperty(required = true)
  @Override
  public long getId() {
    return id;
  }

  @JsonProperty(required = true)
  @Override
  public UUID getNationKey() {
    return nationKey;
  }

  @JsonProperty(required = true)
  @Override
  public String getName() {
    return name;
  }

  @JsonProperty(required = true)
  @Override
  public UUID getRegionKey() {
    return regionKey;
  }

  @JsonProperty(required = true)
  @Override
  public String getComment() {
    return comment;
  }

  @Override
  public String toString() {
    return "NationEntity{"
        + "id=" + id + ", "
        + "nationKey=" + nationKey + ", "
        + "name=" + name + ", "
        + "regionKey=" + regionKey + ", "
        + "comment=" + comment
        + "}";
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (o instanceof NationEntity) {
      NationEntity that = (NationEntity) o;
      return (this.id == that.getId())
           && (this.nationKey.equals(that.getNationKey()))
           && (this.name.equals(that.getName()))
           && (this.regionKey.equals(that.getRegionKey()))
           && (this.comment.equals(that.getComment()));
    }
    return false;
  }

  @Override
  public int hashCode() {
    int h = 1;
    h *= 1000003;
    h ^= (int) ((this.id >>> 32) ^ this.id);
    h *= 1000003;
    h ^= this.nationKey.hashCode();
    h *= 1000003;
    h ^= this.name.hashCode();
    h *= 1000003;
    h ^= this.regionKey.hashCode();
    h *= 1000003;
    h ^= this.comment.hashCode();
    return h;
  }

}
```

The issue is that Jackson uses the "`public java.util.UUID AutoValue_NationEntity.getNationKey()` method instead of `public abstract java.util.UUID NationEntity.getNationKey()` so the class uses is not public. 

Workarounds that I have is either adding the  `@JsonSerialize(as=NationEntity.class)` annotation to NationEntity or allow Jackson to use `setAccessible`. Neither is really satisfying.

How about an attribute to `@AutoValue` that controls the visibility of generated classes with the default of "package private" but the option to make those public if desired?
introspection of package private classes
issue
closed
eamonnmcmanus
username_1
issue
created
eamonnmcmanus
username_1
For me this is clearly a bug in Jackson. It's a well-known problem that when you are invoking a public Method you may need to find its specification in a public superclass or superinterface. AutoValue even [does this](https://github.com/google/auto/blob/d5ca4ab484fd0def8d8c67b20481c3e285ed6c03/value/src/main/java/com/google/auto/value/processor/escapevelocity/ReferenceNode.java#L328) in its own implementation.

If you really want `AutoValue_Foo` to be public then you can trivially write an [extension](https://github.com/google/auto/blob/master/value/userguide/extensions.md) to achieve that. I don't expect that we will ever want this behaviour to be part of core AutoValue.
comment