-
Notifications
You must be signed in to change notification settings - Fork 165
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
Refine cache resolution when annotations are used #341
Comments
Its not totally clear or easily digestible what you are aiming at. Can you please add a code example and the possible ambiguous outcomes? Please mind the spec on page 53:
Type checking is not mandatory and there are no TCK tests for runtime type checks. |
@cruftex: the spec says type checking is not mandatory for mutative operations. However when a cache is created with type parameters then it has to be always obtained via: Chapter 11.2.1 specified how a cache name should be generated. It implies the cache is supposed to also accessed directly (=it's not just an internal concern of the interceptor/proxy). However the spec does not mandate whether the annotation interceptors should use a cache with type checking or a raw cache. Without knowing this you do not know what |
I think I got it. So it boils down to: With annotations the usable cache typing of a requested cache is only Correct? I still wonder whether it might be a hazelcast or in general a specific implementation issue. |
@cruftex: that's correct. I wonder about the same. There is a chance it's a bug in the CDI glue used in Payara. |
Hmm,
I would say this rule only applies if the configuration of the different types is happening by means defined by JSR107, which would yield an ambiguous situation. OTOH, it is always the case that a cache implementation will not be able to store every object type (e.g. not serializable ones). There are always restrictions that might apply. So I think it is legal that an implementation has a separate type configuration inside the implementation configuration and outside the JSR107 defined scope that restricts the types and does not follow the rule above. So, if an implementation wants to leverage more concrete type information that it gets inside its own That said, as I can see from your gist, hazelcast refuses to return the cache since the configured types do not match (and strictly follows the rule above). Maybe hazelcast can do something more useful and still be Spec compliant? Did you open an issue at hazelcast? OTOH, I think we both agree that the Spec should ensure a consistent and practical behavior. I just doubt that we can do this within a reasonable effort in a maintenance release. |
Specifying the type just with the class, is limited anyways, e.g. there is no way to have the complete type information for generic types just as |
@cruftex: I'm not sure if I'm fully following you. Hazelcast does not provide implementation of the CDI interceptors for caching annotation. Payara (app. server used in the gist I linked) implements CDI caching interceptors and use public imperative JSR107 API to talk to Hazelcast ( As far I know the other containers (Spring, TomEE) do the same - they also use the public JSR107 API to implement the behaviour specified by the JSR107 annotations. Thanks to this design the JSR107 provider is independent on the container implementing the annotations and vice versa - you can have implementations for Guice, Spring, CDI and they can use Hazelcast, Cache2k or any other JSR107 compliant provider. In other words: I use JCache annotations to store some data into a cache. I also want to have a full imperative access to the same cache via I also agree the type configuration options provided by the spec are somewhat clumsy, but that's a different topic. |
Okay, we have a bunch of different requirements we actually speak about. We need to structure that a little. 1) Type information on the annotated methods should be transported through to the cache implementationAlthough the Spec says that type information is derived from the signature for constructing the cache name, it is not specifying that this must also be used to retrieve the cache. There is also no TCK test for this. The cache implementation can make use of the additional type information, e.g. by doing runtime checks or selecting serializers more effective. 2) It should possible to retrieve the used
|
you did a great job with analysing my not-so-structured thoughts, well done! ad 1.: you wrote: "Although the Spec says that type information is derived from the signature for constructing the cache name, it is not specifying that this must also be used to retrieve the cache." However the JavaDoc of the
Do I still miss something? ad 2: agreed ad 3: I agree with the 1st part. "Just" amending the spec to mandate which version of You also opened a new question "How to get a reference to EDIT: Nevermind, I misunderstood you in the first point. Now I understand that you are suggesting that the type information of the intercepted method may or may not be used to retrieve the cache. Is this correct? |
To be honest, I feel a little lost here. Since I do not use EE and the cache annotations myself it takes me always some time to get into the concepts again. Anyhow, I poked around a little bit more and thought how this makes some sense. The Spec says, in the JavaDoc from
I think that is the main conceptual statement we need to deal with. It has two questions: "What types are used?" and "What CacheManager?" Used Types for Default Cache ResolutionThere are two conceptual mismatches:
Let me further elaborate this: The configured types in the cache for type enforcement and the types the application operates on may be different. In case the cache is configured with The effective types may be subtypes, too. If you define caching DAOs for each entity you might want to have one DAO per entity but a shared cache for every entity. So the cache would have the configured types While it is desirable to infer the types from the parameters and pass it to the cache, it will do more harm then good. In a real usage scenario with Spring or EE container, probably => For what we have right now, I think we do better with defining The only right solution would have been to consequently make the type declarable at annotation level, too. We cannot fix that in 1.x... Used CacheManager for Default Cache ResolutionAgain, the Spec says, in the JavaDoc from
This could mean the container default, or the default as defined by the imperative API. If the meaning/interpretation is the "imperative API default", this means:
=> It is more practical to allow a container to have parameters for its default provider, URL, etc. it uses for a specific application. This means also, that a container would have a container specific way to get a cachemanager of an application. I think that is okay. This could be addressed by an EE integration standard, to ensure consistency in the EE world. Wrap UpI'll just remember Mark Reinhold saying something like "We only can make things less painful". Proposal: Relevant JavaDoc at
JavaDoc at
Add here:
|
The RI always does createCache(cacheName, new MutableConfiguration<Object, Object>()); See https://github.com/jsr107/RI/blob/562f40e599550ba5cd3f822d298df808d9d9a528/cache-annotations-ri/cache-annotations-ri-common/src/main/java/org/jsr107/ri/annotations/DefaultCacheResolverFactory.java#L73 that's why Payara does. |
Thanks Steve, good hint I missed to cite that code. The complete passage is:
It does |
The actual cache annotations however always produce a GeneratedCacheKey as the key type or something that implements the interface so I suppose the key type should be GeneratedCacheKey the value type could be difficult to determine in the general case. |
Hmm, it is hard to find arguments for the usefulness of changing to We have now "Any types" or "Sepcific types". Using One interesting aspect would be, that a cache implementation could assume that every key is serializable. I am a afraid that this will cause additional harm to the users and/or cause other troubles. Users will need to configure that type for every cache, since on JCache imperative API level the correct type must be used and known. |
Looking into this with a real life example I have over at https://github.com/gregrluck/microprofile-conference. |
@gregrluck: Just looked at your code example. Good work, it is very important to take real scenarios. In the last commit you added the use of an annotation:
Is this working?! According to the Spec the key type is always |
Haven’t got far enough to know if it is working because Payara blew up. Have an answer to that now so will let you know. Greg Luck web: http://gregluck.com http://gregluck.com/
|
Got Payara working. In the direct API we are using Long as the key. Annotation key types must be GeneratedCacheKey. In the example we have a LongKey which contains the Long but implemented GeneratedCacheKey. Interoperability between the two APIs is broken. You could hack it up by using GeneratedCacheKey implementations yourself as keys but that is ugly. I have reached out to Eric Dalquist who designed this to see what his idea was here. To fix this we are going to have to change the Annotations API which we cannot do in 1.1 So moving this to 2.0 |
Does anyone know why we would need to keep GeneratedCacheKey? Why not make this Object? |
Chapter 11.2.1 of the specification describes cache name resolution, but it does not say anything about type configuration.
Should a caching container/framework use a cache with type checking configured?
This should be refined it the specification as otherwise it may result in portability issues when switching between containers.
The text was updated successfully, but these errors were encountered: