TLDR;
The JDBI @BindBean
annotation generates an IllegalAccessException
with AutoValue generated types because the generated types are package private and by default can't be accessed by default using reflection.
Is JDBI inflexible or is there a workaround via AutoValue? (Full questions below)
Quick Background
I'm attempting to use the JDBI @BindBean
annotation with a type whose source is generated using AutoValue.
package com.example;
@AutoValue
public abstract class Foo {
public String getBar();
}
The issue is that the generated code looks like:
package com.example;
@AutoValue
class AutoValue_Foo extends Foo {
private final String bar;
@Override
public String getBar() {
return this.bar;
}
// toString, equals, hashCode
}
Notice the class is package private!
Now if I attempt to use @BindBean
, for example:
@SqlQuery("select * from baz where bar = :foo.bar")
Condition find(@BindBean("foo") Foo foo);
Because AutoValue_Foo
is package private, and BindBeanFactory
uses reflection, if an attempt is made to call find
with an AutoValue_Foo
type, the result is:
java.lang.IllegalAccessException: ... can not access a member of class com.example.Foo with modifiers "public"
The relevant JDBI code is here. I understand from a Java reflection perspective, this could be resolved using setAccessible(true)
but that would require a PR to JDBI.
So the questions are as follow:
Is there a way to restructure my code where I can bind a
Foo
of typeAutoValue_Foo
using@BindBean
without creating a new JDBI mapper?Is there a way to have
@AutoValue
generate classes that arepublic
. I understand why this would generally not be desirable (push people to use the interface and not the implementation).Is the
BindBeanFactory
too inflexible? Should it utilizesetAccessible(true)
on methods that are otherwise available outside of their originating package?