Mapping with @Field @IndexedEmbedded Integer[] field throws InaccessibleObjectException

Description

When we find an @IndexedEmbedded, we use introspection to find out exactly what is "embedded". This makes sense, since @IndexedEmbedded is about embedding stuff, right?
Well, not always. The @IndexedEmbedded annotation has another meaning: when there is a @Field on the annotated property, we actually use it to tell Hibernate Search to wrap the field bridge in a "container" field bridge (see ). This is especially useful when one wants to index a list or array of simple values, such as String or Integer for instance.
Since we cannot distinguish between the two use cases, we end up always using introspection on the element type, even if the element type is something like java.lang.Integer.

This is fine in JDK8 and below, but starting from JDK9 such things are prevented by module isolation: you can't use setAccessible outside of your own module unless explicitly allowed to, and thus you can't inspect private members by default.

Stack trace:

Activity

Show:

Yoann RodièreApril 25, 2017 at 1:07 PM

I'm confused about this note. Do you have an example?

Something like that:

Sanne GrinoveroApril 25, 2017 at 12:58 PM

what if someone used programmatic mapping to put an annotation on Integer.doubleValue()

I'm confused about this note. Do you have an example?

Yoann RodièreApril 25, 2017 at 12:38 PM

In my opinion, the ideal solution would be to disallow using @IndexedEmbedded this way, and introduce a separate annotation (see and the related PR). But that's a breaking change, and ideally we'd want JDK9 compatibility in 5.8 (it's in the roadmap).

So we have to find something else.

We could simply exclude java.lang from the types to be introspected, but this hardly seems like an ideal solution: what if someone used programmatic mapping to put an annotation on Integer.doubleValue(), for instance? Or some other java.lang type where it would make more sense?

The only two real solutions I can think of are:

  • Avoid to call setAccessible unless we actually find out that a member is to be taken into consideration (@Field, @IndexedEmbedded, ...). We can only do this if inspecting annotations doesn't require to call setAccessible first. I think it's the case, but I'll have to try.

  • When using introspection, totally ignore properties that cannot be made accessible. I find this solution a bit more error-prone, but if the previous one is impossible, that could do the trick...

Fixed

Details

Assignee

Reporter

Components

Fix versions

Affects versions

Priority

Created April 25, 2017 at 12:23 PM
Updated May 11, 2017 at 7:35 AM
Resolved April 25, 2017 at 2:28 PM