Skip to content
This repository has been archived by the owner on Feb 23, 2023. It is now read-only.

Introduce initial caching support #465

Closed
sdeleuze opened this issue Feb 4, 2021 · 17 comments
Closed

Introduce initial caching support #465

sdeleuze opened this issue Feb 4, 2021 · 17 comments
Labels
for: external-project For an external project and not something we can fix type: compatibility Native image compatibility issue

Comments

@sdeleuze
Copy link
Contributor

sdeleuze commented Feb 4, 2021

We have basic configuration for caching in CachingHints, but EhCache is not supported, and enabling caching support in PetClinic JPA with the following configuration:

@Configuration
@EnableCaching
class CacheConfiguration {

	@Bean
	public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() {
		return cm -> {
			cm.createCache("vets", cacheConfiguration());
		};
	}

	private javax.cache.configuration.Configuration<Object, Object> cacheConfiguration() {
		return new MutableConfiguration<>().setStatisticsEnabled(true);
	}

}

Generates this error that seems to indicate the need for a processor:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'vetController' defined in class path resource [org/springframework/samples/petclinic/vet/VetController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'vetRepository': Post-processing of FactoryBean's singleton object failed; nested exception is com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface org.springframework.samples.petclinic.vet.VetRepository, interface org.springframework.data.repository.Repository, interface org.springframework.transaction.interceptor.TransactionalProxy, interface org.springframework.aop.framework.Advised, interface org.springframework.core.DecoratingProxy, interface java.io.Serializable] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.

We should also document what kind of caching is supported (see the list in CacheType) and bring back caching support in the petclinic-jpa sample as configured in https://github.com/spring-projects/spring-petclinic.

@sdeleuze sdeleuze added the type: compatibility Native image compatibility issue label Feb 4, 2021
@sdeleuze sdeleuze added this to the 0.9.1 milestone Feb 4, 2021
sdeleuze added a commit that referenced this issue Feb 4, 2021
More work is needed for proper caching support, see gh-465.

Closes gh-451
@sdeleuze
Copy link
Contributor Author

As a follow-up of #481, here is my proposal for a more efficient caching support.

First, once spring-projects/spring-boot#25321 is merged, we should configure CacheConfigurations to be initialized at build time to avoid using the cache configuration classes at runtime if they are not useful.

Second, we should update CacheConfigurationImportSelector substitution to add classpath check (based on manual conversion of @ConditionalOnClass to return only the relevant ones.

Third, we should update CacheHints to dynamically add the relevant hints based on a build-time execution of CacheConfigurationImportSelector.

@sdeleuze sdeleuze modified the milestones: 0.9.1, 0.9.0 Feb 17, 2021
@sdeleuze
Copy link
Contributor Author

Tentatively scheduled for 0.9.0 since that's an important feature.

@sdeleuze sdeleuze self-assigned this Feb 18, 2021
@sdeleuze sdeleuze added the status: blocked An issue that's blocked on an external project change or another issue label Mar 1, 2021
@snicoll
Copy link
Contributor

snicoll commented Mar 7, 2021

@sdeleuze I can see this is blocked. Anything I can help you with?

@sdeleuze sdeleuze removed the status: blocked An issue that's blocked on an external project change or another issue label Mar 7, 2021
@sdeleuze
Copy link
Contributor Author

sdeleuze commented Mar 8, 2021

Thanks for the offer, I am progressing again on it after the discussion we had on #526.

@sdeleuze
Copy link
Contributor Author

sdeleuze commented Mar 8, 2021

I gave it another try with Ehcache 3 and JSR 107, and ended up being blocked on unsafe access in ThreadLocalRandomUtil that I was not able to make it work despite what I think is proper unsafe field configuration. This is likely fixable but will require more time.

That issue + the fact that we need a processor for creating dynamically the proxy configuration + the fact that we need time for proper testing, feedback and adding support for other mechanism clearly indicate to me that this is not doable for 0.9.0.

I have pushed my work on sdeleuze@caching. Let's get back on this for 0.10.0.

@sdeleuze sdeleuze modified the milestones: 0.9.0, 0.10.0 Mar 8, 2021
sdeleuze added a commit that referenced this issue Mar 9, 2021
Not yet finished but could be useful if some users want to craft themselves
the missing hints.

See gh-465
sdeleuze added a commit that referenced this issue Mar 9, 2021
Build fails on some samples otherwise

See gh-465
@sdeleuze sdeleuze modified the milestones: 0.11.0, 0.10.0 Mar 15, 2021
@sdeleuze sdeleuze modified the milestones: 0.10.0, 0.11.0 Apr 19, 2021
@goafabric
Copy link

It would also be nice to have caffeine working.
While SimpleCache works btw. out of the box for now,
Caffeine needs a lot of Typehints in Version 2.8.x

Following this issue which implicates that Quarkus and Micronaut got it working:
ben-manes/caffeine#434
I put a lot of Typehints (see below)

But still more and more Hints would be needed, because of the excessive use of Reflection.
Version 3.x uses much less Reflection, but there i also gave up after hours.
Would be great to see this supported by Spring

-- cut - not enought to get it working ---

@typehint(typeNames = {
"com.github.benmanes.caffeine.cache.PSW", "com.github.benmanes.caffeine.cache.PSWMS",
"com.github.benmanes.caffeine.cache.SSLA", "com.github.benmanes.caffeine.cache.SSLMSW",
"com.github.benmanes.caffeine.cache.SSMSW", "com.github.benmanes.caffeine.cache.SSMSA",
"com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef"
},
access = AccessBits.ALL
)

@ben-manes
Copy link

Caffeine v3 no longer uses Unsafe, so that might help you get farther if somehow blocked on Ehcache due to that.

The Quarkus folks suggested a compile-time evaluation, but I don't really understand Graal enough to implement and verify the suggestion. Any help making this easier for integrators would be appreciated.

@goafabric
Copy link

Caffeine v3 no longer uses Unsafe, so that might help you get farther if somehow blocked on Ehcache due to that.

The Quarkus folks suggested a compile-time evaluation, but I don't really understand Graal enough to implement and verify the suggestion. Any help making this easier for integrators would be appreciated.

Thanks for your reply .. actually thats what i tried out, Caffeine v3 because it uses much less reflection ... unfortunately i still could not get this running, because still a lot of hints needed to be added, that i could not figure out.
I might eventually try out v3 again if this seems to be the right choice

@goafabric
Copy link

goafabric commented May 14, 2021

@ben-manes oh sorry ..
I got it wrong .. you are actually the developer of caffeine .. so I guess you know better :)
first and foremost thx for this awesome piece of software ...
but as stated .. even with unsafe gone, from what I also saw in the code, its not working, at least not of the box,
because i suspect further things need to be added

Also one of the problems with version 3.x is, that its' compile with java 11.
Which is usually not a big deal, but as the standard for graalvm is currently still level 8,
graalvm 11 has to be used, which seems to have some drawbacks currently.
But I'll try nontheless

.. so I retried V3.x and it basically crashes with the exception below
and I am pretty sure that i already invested some time 1 month ago to dig in deeper without finding a solution

Caused by: java.lang.NoSuchFieldException: no such field: com.github.benmanes.caffeine.cache.UnboundedLocalCache.refreshes/java.util.concurrent.ConcurrentMap/getField
at java.lang.invoke.MemberName.makeAccessException(MemberName.java:965) ~[na:na]
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1101) ~[na:na]
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:2021) ~[na:na]
at java.lang.invoke.MethodHandles$Lookup.findVarHandle(MethodHandles.java:1514) ~[na:na]
at com.github.benmanes.caffeine.cache.UnboundedLocalCache.(UnboundedLocalCache.java:88) ~[na:na]
... 31 common frames omitted
Caused by: java.lang.NoSuchFieldError: refreshes

@ben-manes
Copy link

Thanks for trying to get it all working. I’m not familiar with Graal and I’d be open to suggestions to make Caffeine better at supporting it. Sorry that you have to fight through this.

oracle/graal#3028 sounds like VarHandles are not supported, leading to improper dead code elimination. I guess it is incompatible with 3.x for now.

In 2.x there is a jandex resource that lists all of the reflections. It was removed in v3 as Quarkus decided it wasn’t necessary, but maybe that could help you bootstrap 2.x. Otherwise I’m at a loss as well.

@goafabric
Copy link

Thank you for your support.
I think your suggestions should be a great help to ger it working.
I‘ll give it a spin eventually

@sdeleuze sdeleuze modified the milestones: 0.11.0, Backlog Jun 8, 2021
@sdeleuze sdeleuze changed the title Add caching support Introduce initial caching support Nov 4, 2021
@sdeleuze sdeleuze modified the milestones: Backlog, 0.11.0-RC1 Nov 4, 2021
@sdeleuze
Copy link
Contributor Author

sdeleuze commented Nov 4, 2021

Let's try to provide initial caching support for Redis, the new AOT engine from 0.11 should make it much easier.

@linghengqian
Copy link

I didn't see any discussion about Spring Native in the Github issue of EhCache. Based on the above discussion, can I assume that Spring Native and JCache (aka JSR107) configured via EhCache are still unavailable?

@snicoll
Copy link
Contributor

snicoll commented Feb 22, 2022

The issue is still open, so yes. To a large extent, this is a bout adding the necessary hints on third party libraries though so the fix wouldn't probably come here.

@linghengqian
Copy link

linghengqian commented Mar 1, 2022

We have basic configuration for caching in CachingHints, but EhCache is not supported, and enabling caching support in PetClinic JPA with the following configuration:

@Configuration
@EnableCaching
class CacheConfiguration {

	@Bean
	public JCacheManagerCustomizer petclinicCacheConfigurationCustomizer() {
		return cm -> {
			cm.createCache("vets", cacheConfiguration());
		};
	}

	private javax.cache.configuration.Configuration<Object, Object> cacheConfiguration() {
		return new MutableConfiguration<>().setStatisticsEnabled(true);
	}

}

I'm sitting on some related attempts. As in https://www.ehcache.org/blog/2017/03/15/spontaneous-cache-creation.html , it seems that EhCache 3 discourages the adoption of new MutableConfiguration<>(), which is inherently somewhat conflicting with JCacheManagerCustomizer. Can I understand that this is because Spring discourages exposing the API of JCache-implementing components within JCache's operations, or is this an intentional design by EhCache 3? In the URL of ehcache/ehcache3#2997 , I made some attempts to understand why EhCache 3 is configured that way in JCacheManagerCustomizer,but some differences related to it confuse me.

@linghengqian
Copy link

@sdeleuze
Copy link
Contributor Author

sdeleuze commented Jan 2, 2023

Spring Native is now superseded by Spring Boot 3 official native support, see the related reference documentation for more details.

As a consequence, I am closing this issue, and recommend trying your use case with latest Spring Boot 3 version. If you still experience the issue reported here, please open an issue directly on the related Spring project (Spring Framework, Data, Security, Boot, Cloud, etc.) with a reproducer.

Thanks for your contribution on the experimental Spring Native project, we hope you will enjoy the official native support introduced by Spring Boot 3.

@sdeleuze sdeleuze closed this as not planned Won't fix, can't repro, duplicate, stale Jan 2, 2023
@sdeleuze sdeleuze removed this from the Backlog milestone Jan 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
for: external-project For an external project and not something we can fix type: compatibility Native image compatibility issue
Development

No branches or pull requests

5 participants