jsr107 / jsr107spec

JSR107 Cache Specification
Apache License 2.0
413 stars 164 forks source link

Handle jakarta namespace? #415

Closed rmannibucau closed 2 years ago

rmannibucau commented 3 years ago

Hi all,

With EE having broken the world what about jcache and its javax namespace? Should jcache go to eclipse too and move to jakarta?

Romain

eolivelli commented 3 years ago

+1

cruftex commented 3 years ago

+1

bmarwell commented 3 years ago

+1 I was searching yesterday if there was one.

cruftex commented 3 years ago

Basically the cache2k-api is a superset of the JCache API and almost complete with async support. So maybe I should contribute the API to Eclipse and the implementation to Apache?

rmannibucau commented 3 years ago

Hi, from what I saw from cache2k, it is not a package renaming as a javax->jakarta migration is expected (TCK should stay the same and a javaagent/remapper enable the migration) and it misses cdi integration. Now if it hits eclipse-ee4j and gets the backward compatible (except root package name) it can work. Guess ASF can get the implementation at geronimo jcache impl or other caching projects but this is a detail here.

tristantarrant commented 3 years ago

Since JCache was never part of JavaEE, wouldn't it be better if we worked on a new, async-first API for JakartaEE/Microprofile ?

rmannibucau commented 3 years ago

Well I see only drawbacks to make it part of microprofile:

  1. It seems it tries to join JakartaEE so back to previous point probably
  2. It is unstable by definition and not adopted by users in practise due to that - whereas Jcache should intend to be very stable

The async first API is also interesting because it is a biaised introduced by Jcache recently with distributed caches - and agree there is space for it - because there is no point being async in local caches. Ultimately caches must be local to be really fast so looks like a wider discussion to have about remoting and caching and not "put it all" under cache umbrella upfront IMHO.

Indeed jcache can move to a com.github.jcache or so (its own naming) but it would loose part of its "standard" side and native integration with JakartaEE in most implementation since then it is just a cache API as a Map can be or some specific API can be (look what happent in logging area to get an idea ;)). So I think it should either stay javax - but can't evolve - or move to jakarta and be given to jakarta ee if possible.

Hope it makes sense.

tristantarrant commented 3 years ago

The async first API is also interesting because it is a biaised introduced by Jcache recently with distributed caches - and agree there is space for it - because there is no point being async in local caches. Ultimately caches must be local to be really fast so looks like a wider discussion to have about remoting and caching and not "put it all" under cache umbrella upfront IMHO.

Even in the local case, async (or rather non-blocking) is needed whenever there is a CacheLoader/CacheWriter.

rmannibucau commented 3 years ago

@tristantarrant yes and no, don't want to hijack this thread which it since it is unrelated to this thread but if you make it async you add overhead (can be x2! just in terms of allocations) to the cache whereas these days with composable completion stages you can trivially replace loader/writers in your business code to keep the cache overhead very low and consistent with your code so since java 8 adoption loaders tend to not be used anymore and writers replaced by transversal solutions like interceptors so I wouldn't invest in async for that reason but only when it makes sense for the cache itself, ie when the cache is remote and has some ack to await (consistency config in general). That said, as mentionned this issue is not at all about async or not but jakarta or not and if you join jakarta you have to keep current API as it for now otherwise there is no point joining jakarta IMHO (would be better to do a new spec to be concrete rather than importing this which is what this thread tries to be about).

m-reza-rahman commented 3 years ago

Is there any chance this will happen? A number of Jakarta EE APIs could really leverage JCache such as Persistence (second-level cache) and Servlet (session cache).

anbusampath commented 3 years ago

+1 moving to Jakarta makes much sense. Also it can be used at various places.

dmatej commented 3 years ago

+1

LuisGalazM commented 3 years ago

+1

juangon commented 3 years ago

+1

fpapon commented 3 years ago

+1

cruftex commented 3 years ago

The discussion what should be included in Jakarta should better move on in eclipse. This is still the JSR107 issue tracker. Can somebody open a ticket there and refer it?

linghengqian commented 2 years ago

@TanjaObradovic Hi my friend, I would like to ask if the Eclipse community has any discussion about moving the JSR107 specification (JCache) to JakartaEE? There is such a discussion in the issue of the github repository related to the original javax namespace, I am curious about the reaction in the Eclipse community. There was some discussion at https://github.com/eclipse-ee4j/jakartaee-platform/issues/7, but no thread appeared to lead the community discussion.

m-reza-rahman commented 2 years ago

I think at this point, it’s up to mostly Oracle. The Eclipse Foundation from folks could follow up.

TanjaObradovic commented 2 years ago

Hello @linghengqian! I would invite you to start the conversation about this on the Jakarta EE community discussions jakarta.ee-community@eclipse.org, and raise the awareness to the wider community and gauge the interest there. I would also encourage the continuing the conversation on the eclipse-ee4j/jakartaee-platform#7. If there is interest from the community and platform team, we would need Oracle's input. This could be discussed at the platform call at that point.

m-reza-rahman commented 2 years ago

I’ll start a thread and cross post here. If others could chime in, it would be very helpful.

tristantarrant commented 2 years ago

I don't think Oracle has any real say in moving this spec to Jakarta (not more than any of the EG members). It was never part of the EE spec and the TCK has always been available under an open source license.

m-reza-rahman commented 2 years ago

The JCP folks should be able to help sort it out. I think the IP is at least partially or wholly still with Oracle. In other words, the transfer can’t happen without Oracle’s legal approval.

cruftex commented 2 years ago

@m-reza-rahman Regarding licensing:

The most important thing, the TCK, was released under Apache and changed just before finalization: https://github.com/jsr107/jsr107tck/commit/7c8ea270f2e722142ca3d67bdf77058964bc1c0d

I do maintain a Apache fork from the TCK here: https://github.com/cache2k/cache2k/tree/master/cache2k-jcache-tests

Regarding the API I could also help. The cache2k-api package is basically designed as pure API package and is implementation neutral. It has 100% feature overlap with the JCache API. I could strip it down to the JCache functionality and then fit the original TCK tests to it and release it under any license needed. I am also happy to document where it differs from JCache and why, which would be the start of the Spec process.

I contributed to JSR107 in its final stages and also the maintenance releases and I am happy to help and push things forward. AFIAK the original authors Brain and Greg are not available any more.

To clarify, I am not speaking about the annotations. I suggest to address these in a separate Spec. Also it is a good idea to rethink/redo these completely.

Of course if Oracle transfers the IP it would make things easier, but there is a way around.

cruftex commented 2 years ago

... wouldn't it be better if we worked on a new, async-first API for JakartaEE/Microprofile Even in the local case, async (or rather non-blocking) is needed whenever there is a CacheLoader/CacheWriter.

@rmannibucau @tristantarrant

W.r.t. to loading, JCache has:

    void loadAll(Set<? extends K> keys, boolean replaceExistingValues,
                 CompletionListener completionListener);

cache2k has:

CompletableFuture<Void> loadAll(Iterable<? extends K> keys);
CompletableFuture<Void> reloadAll(Iterable<? extends K> keys);

Cache2k also has an async loader and async build loader interface already.

So, for loading the original API already has something to offer and could be evolved. This example also shows how I converted the JCache features to Java 8 and improved the API (e.g. use of Iterable instead of Set).

W.r.t. "full async":

For the first step I recommend to stay very close to the original JCache features. JCache is still Java 6 and has a few flaws that can make it a burden to use. Better first address this and have a better API soon. When staying close to JCache functionality it can be easily supported by cache vendors.

Of course it would be nice to have a full async API. But the best API does not help if nobody is implementing it. Better do this as a second step. It also does not hurt to discuss and experiment with async APIs in parallel.

rmannibucau commented 2 years ago

My 2cts would be that javax.cache API is completely outdated for today usage. One example is what you mention (but it is more general, even get should return a completionstage - not future ;) - to enable composition and integration in a microservice which is not backed by JDBC only so think it is maybe better to start from scratch a new spec - only keeping the object hierarchy (provider/SPI -> manager -> cache).

cruftex commented 2 years ago

@rmannibucau

One example is what you mention (but it is more general, even get should return a completionstage - not future ;)

Why? This method should support async and non async usage. So another user might say it should return a Future.

A full async API that is enforcing proper async usage is a different topic and even if you do specify a full async API you still should have a non async version and/or support just the Map interface.

... and integration in a microservice which is not backed by JDBC

I don't see how there is a direct relation or limitation to JDBC.

... so think it is maybe better to start from scratch a new spec

Why?

I know a lot what needs to be changed, a lot that should be changed and a lot I am unhappy with and could be improved. But still JCache is a good starting point. Each cache implementation I know provides a synchronous interface, some provide a Map interface. Apache Ignite subclasses the JCache Cache interface, AFIAK EHCache 3 uses JCache as main access API.

It doesn't matter. When starting from scratch, you will run through the same process as JCache. Look at existing implementations and provide an API with a subset of what is available there.

Another approach, could be to define APIs for specific uses within EE. For example, the Cache defined by Spring does not have many operations but is still enough to support the annotations.

rmannibucau commented 2 years ago

@cruftex completionstage has a bridge to completionfuture we can enforce the spec to impl but it is more composable base for consumers than completionfuture which wrongly exposes old future API which is not ecouraged these days.

you still should have a non async version and/or support just the Map interface.

This is one thing i'd like to completely change in the spec: enable to inject features (by wrapping) instead of providing an all in one implementation. Typically eviction and things like that are features decorating a map the user can provide and not something we should enforce in a cache.

I don't see how there is a direct relation or limitation to JDBC.

Was a "language shortcut" to say "synchronous code" (in microservices you either consume a remote API - and generally speaking only JDBC is synchronous these days there - or you are local and synchronous. It is a bit caricaturally but I tried to be short ;)

Long story short, the thinking I'd like you have is: assume you don't have JCache, how would you do? And the answer is always "way simpler" so why keeping something overcomplex? Let's move to the needed features:

  1. Wrapping an user map (we can default to concurrent hash map) and add features - eivction and listeners mainly - on top of native Map API
  2. Enable to unwrap(AsyncMap.class) API to get completionstage composition

This requires a way lighter API than current one and it is fine to move the lifecycle management to the enclsoing IoC (CDI for EE Produces/Disposes) instead of faking managing it in the spec itself.

ben-manes commented 2 years ago
  1. Wrapping an user map (we can default to concurrent hash map) and add features - eivction and listeners mainly - on top of native Map API
  2. Enable to unwrap(AsyncMap.class) API to get completionstage composition

I believe this is where you deviate from the JCache spec leads' intent. Their focus was oriented around an abstraction that could work for many local, persisted, and distributed caches. Map can be problematic, e.g. remove(key) returns the old value which might be expensive to retrieve. They did not go extreme in that regard, such as Memcached does not allow iteration of the keys (Cache.iterator()) or support atomic computations (Cache.invoke). They attempted to serve these cases, while also incorporating a variation of Spring's popular AOP abstraction and support framework integrations like Hibernate. As a result the APIs can feel limited, fragile, and not very end-user friendly. That is not a fault of JCache but rather that it may not be possible to achieve all of the community's goals through a singular abstraction.

The api you envision might favor trying to extend the Java Collections Framework. That offers familiarity and good idioms, but was also designed assuming on-heap usages. In Guava we attempted to define an api based on those premises in Java 5, which was finalized after we received design reviews by Josh Bloch and Doug Lea. This was then modernized in Caffeine for Java 8+, which incorporates async. Those APIs try to feel very friendly to Java developers and follow Josh's bumper-sticker design rules, but that is very orthogonal to the original intents of JCache and would not have been appropriate given their goals.

Has any other JCP specification been completely overhauled during the transition to Jakarta? If not, then I do not think it is reasonable to do so here. It is already frustrating enough for the community to migrate packages, which causes painful incompatibilities with older libraries that are not actively transitioning. If the current api is not satisfactory, then I do not think that JCache should transition over and instead can be EOL'd. Jakarta may reasonably decide to invest in a new project to explore a different api, and if so then I think that should be fully separate from the jsr107 discussions here.

tristantarrant commented 2 years ago

Well said @ben-manes My take: JCache 1.0 can be frozen as it is. It would have made sense to bear the effort of the transition with the legacy API if there had been deeper connections with the JavaEE world (e.g. transactions, JPA) that would have caused a nightmare with the namespace transition. A new project, under the Jakarta banner, "inspired" by JCache but with all of the new design requirements (async/reactive), and possible with better integrations with other, neighbouring components, would be my recommendation

linghengqian commented 2 years ago

Hello @linghengqian! I would invite you to start the conversation about this on the Jakarta EE community discussions jakarta.ee-community@eclipse.org, and raise the awareness to the wider community and gauge the interest there. I would also encourage the continuing the conversation on the eclipse-ee4j/jakartaee-platform#7. If there is interest from the community and platform team, we would need Oracle's input. This could be discussed at the platform call at that point.

Thanks for your invitation, I have created a topic for discussion at jakarta.ee-community@eclipse.org. Discussions that also take place within jakarta.ee-community@eclipse.org are still available at https://www.eclipse.org/lists/jakarta.ee-community/maillist.html . (Forgive me being a mailing list novice, I obviously got the sender name wrong)

cruftex commented 2 years ago

@rmannibucau Romain,

Long story short, the thinking I'd like you have is: assume you don't have JCache, how would you do? And the answer is always "way simpler" so why keeping something overcomplex? Let's move to the needed features: Wrapping an user map (we can default to concurrent hash map) and add features - eivction and listeners mainly - on top of native Map API

With the ConcurrentHashMap you introduce atomic operations and iterators and also you mention listeners. However, for annotations and persistence you don't need that. However, on the other side the Map or CHM is lacking bulk operations. Bulk operation support (like getAll and putAll) should be present for efficiency.

assume you don't have JCache, how would you do?

Good question. Depends if you speak with a caching vendor or an application developer ;)

Even if I had JCache, as an application developer, I do not see why there is a need to "speak" with a cache directly in most scenarios.

For persistence, the cache is already wired in transparently.

When exposing an external interface, I would like to specify that the content can or should be cached. The platform would provide that and/or add headers so this happens in the edge server.

For internal services there should be standard interfaces for retrieving, querying and updating data. These services could be proxied to add transparent caches.

Take away: Caching is a cross cutting concern. Jakarta EE is wiring things together (CDI), where there could be caching in between and providing a standard for I/O (RESTful Web Services) where there is usually caching as well.

That is quite visionary and a long way to go. But that is how to make it simple for the application developer in the end.

rmannibucau commented 2 years ago

However, for annotations and persistence you don't need that.

Well there is no persistence in jcache, just callbacks easily wired with a decorator/wrapper of map so no big deal for this point. Agree for bulk operations but it is kind of the same since the putAll is there and it is the only needed one, others are just shortcuts not needed from a cache perspective (getAll is a 2 passes impl where first one checks what is in the map and second forces the listener/loader to load other values so it is more a listener API than a cache one and it is really a facade extension - unwrap i mentionned - for the cases needing it).

For the rest: don't get me wrong, I think the cdi layer is not that bad if it enables to support CompletionStage - what we did in geronimo impl for ex - but the CDI layer is really a subconsumer of the actually API - your getAll example is a good illustration of that and from an application dev perspective the consumption is not that trivial. The best consumers, as of today, of jcache are jpa and a bit servlet/jaxrs - but here a lot of issues are popping up by design - not by impl/code, and JPA one will need to evolve in terms of API to become modern enough and not superseeded by r2dbc or equivalent.

Honestly I used it a lot and CDI usage was ok for several apps but since a few years - microservices++ - it is not sufficient to have a Cache and interceptor layer is too limited to java 6 map API so i always wrapped it in a custom fashion, this is why i'm proposing to start back from scratch.

cruftex commented 2 years ago

@rmannibucau

rmannibucau commented on May 6, 2021

Should jcache go to eclipse too and move to jakarta?

rmannibucau commented 21 hours ago

... so i always wrapped it in a custom fashion, this is why i'm proposing to start back from scratch.

So now you answered the issue you created by yourself.

While I am with you that there should be a better and modern approach, having something like JCache right now (Payara ships with it) will definitely have some value as well. Maybe it makes sense to do both, be visionary but also do the feasible to solve some imminent needs?

Here is the discussion link to the EE Community. With that, I am closing this issue here.

https://www.eclipse.org/lists/jakarta.ee-community/msg02901.html

rmannibucau commented 2 years ago

Maybe it makes sense to do both, be visionary but also do the feasible to solve some imminent needs?

Thinking out loud but what does prevent to use jcache except the cdi integration? nothing, so it is only about the vendor glue code which must do a javax.cache/jakarta.enterprise integration more than anything else to get it right now, no? moving javax.cache to jakarta.cache will not help for that goal from my window.

cruftex commented 2 years ago

@rmannibucau If you mean that there is a lot work to do in the glue code, I fully agree. E.g. JCache is insufficient when it comes to configuration, but in EE context, you want to start your application without configuring each cache depending on what is available on the platform.

rmannibucau commented 2 years ago

I rather meant it is max 5mn and 6 LoC to make it work.