I am trying to integrate Ehcache with my Java Spring MVC Web Applications. I have followed the instructions from the following article:
https://dzone.com/articles/implementing-ehcache-using.
I have added the following dependency to my pom.xml file:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.9.0</version>
</dependency>
My ehcache.xml is as follows:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cache name="swcmRestData"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000"
eternal="false"
diskSpoolBufferSizeMB="20"
timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU"
transactionalMode="off">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
I have the following entries in my root-context.xml:
<!-- EhCache Configuration -->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="true"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>
And I have a method for which I want to enable ehCache:
#Cacheable(value="swcmRestData", key="url")
public <T> T getEntity(String url, java.lang.Class<T> gt) throws RestException
{
T t = restClientService.getEntity(url, gt);
return t;
}
I want the data to be retrieved from the ehCache if the same url is passed to the specified method. I do not get any errors while running the code. But looks like the caching is not working. Is there anything that I am missing here
Two things that could be the cause of the problem:
You are missing the Spring configuration so that there is a link between the defined beans and the caching annotation. Effectively that's point 2 in the article you link which you do not mention here.
As suggested in comments, the method you are caching is called from within the same class. That's a limitation of Spring AOP implementation when using proxies. If you configure Spring to do bytecode weaving it will work.
If none of the above are the source of error, please provide more information on your setup.
Related
Why the following ehcache.xml doesn't allow to clear caches via JMX (the Operations tab is disabled in JVisualVM for MBean for cache management and enabled for cache statistic)? I use spring boot framework and specify ehcache.xml file location via spring.cache.jcache.config property and just use #Cachable spring framework annotation.
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
xsi:schemaLocation="
http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">
<service>
<jsr107:defaults enable-management="true" enable-statistics="true"/>
</service>
<cache alias="stringCache">
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<heap unit="entries">2000</heap>
</cache>
</config>
Clearing cache entries is not supported by the JSR-107 specification. Only clearing the statistics is possible. To workaround that, you will have to create your own MBean.
I am working on a project in spring boot and I need to add Spring integration poller for polling files from a location and run spring batch on that file to process it.
I have used spring batch integration for this(Document Reference below.)
http://docs.spring.io/spring-batch/trunk/reference/html/springBatchIntegration.html
In spring boot, I have succesfully configured my poller in #Configuration file as below
#Bean
#InboundChannelAdapter(value = "fileInputChannel", poller = #Poller(
fixedRate = "1000"), autoStartup = "true")
public MessageSource<File> filesScanner() {
CompositeFileListFilter<File> filters = new CompositeFileListFilter<File>();
filters.addFilter(new SimplePatternFileListFilter("*.xml"));
filters.addFilter(new AcceptOnceFileListFilter<File>());
filters.addFilter(getLastModifiedFileFilter());
FileReadingMessageSource source = new FileReadingMessageSource();
source.setDirectory(new File("F:/DataInput/"));
source.setFilter(filters);
return source;
}
This poller is defined in java configuration whereas the channels are defined in xml as below.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-file="http://www.springframework.org/schema/integration/file"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/file
http://www.springframework.org/schema/integration/file/spring-integration-file.xsd">
<int:channel id="ticketingResponse" />
<int:channel id="mailFailureTicketData" />
<int:channel id="moveSuccessTicketingFile" />
<int:channel id="moveFailureTicketingFile" />
<int:channel id="ticketingFileInput" />
<int:channel id="ticketingJobParameters" />
<!-- <int-file:inbound-channel-adapter id="filePoller"
channel="inboundFileChannel"
directory="file:/tmp/myfiles/"
filename-pattern="*.csv">
<int:poller fixed-rate="1000"/>
</int-file:inbound-channel-adapter> -->
<bean id="earliestTicketingFileSelecter" class="com.avios.integration.iqcx.FilesSortingComparator" />
<bean id="compositeFilesFilter"
class="org.springframework.integration.file.filters.CompositeFileListFilter">
<constructor-arg>
<list>
<bean
class="org.springframework.integration.file.filters.RegexPatternFileListFilter">
<constructor-arg name="pattern" value="${ticketing.input.file.pattern}" />
</bean>
<bean class="org.springframework.integration.file.filters." />
<bean
class="org.springframework.integration.file.filters.LastModifiedFileListFilter">
<property name="age" value="${ticketing.input.file.age}" />
</bean>
</list>
</constructor-arg>
</bean>
<bean id="ticketingFilesScanner"
class="org.springframework.integration.file.FileReadingMessageSource">
<property name="filter" value="compositeFilesFilter" />
<property name="directory" value="/tmp/myfiles/" />
</bean>
<int-file:inbound-channel-adapter id="filePoller"
channel="inboundFileChannel"
directory="file:/tmp/myfiles/"
filename-pattern="*.csv">
<int:poller fixed-rate="1000"/>
</int-file:inbound-channel-adapter><!-- <int-file:inbound-channel-adapter
directory="${ticketing.input.file.path}" channel="ticketingFileInput"
comparator="earliestTicketingFileSelecter" auto-startup="true" filter="compositeFilesFilter" >
<int:poller ></int:poller>
</int-file:inbound-channel-adapter> -->
<int:transformer id="iqcxFilesToJobParameters" ref="jobParameterTransformer"
input-channel="ticketingFileInput" method="addTicketingFileToJobParameter"
output-channel="ticketingJobParameters" />
<int:outbound-channel-adapter channel="ticketingJobParameters"
ref="iqcxJobLaunchingGateway" method="handleMessage" />
</beans>
I am getting the below error in my XML configuration file.
cvc-complex-type.3.2.2: Attribute 'fixed-rate' is not allowed to appear in element 'int:poller'.
I checked this on google and found only the below link which wasn't much of use as i am getting exact same error.
Using Spring Boot & Spring Integration with database backed Configuration
Attribute 'fixed-rate' is not allowed to appear in element 'int:poller'
Spring boot version i am using is as below.
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
Spring integration jar in library - Spring-integration-core-4.2.8.RELEASE.jar
I also tried excluding integration jar from batch-integration dependency and adding it separately as below but that didn't work either.
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-integration</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.integration/spring-integration-core -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
Also checked the XSD http://www.springframework.org/schema/integration/spring-integration.xsd and it has the attribute fixed-delay in poller. Any suggestions for resolving this?
Read the important note in the online schema:
+++++ IMPORTANT +++++
This schema is for the 1.0 version of Spring Integration Core. We cannot update it to the current schema
because that will break any applications using 1.0.3 or lower. For subsequent versions, the unversioned
schema is resolved from the classpath and obtained from the jar.
Please refer to github:
https://github.com/spring-projects/spring-integration/tree/master/spring-integration-core/src/main/resources/org/springframework/integration/config/xml
for the latest schema.
In the old schema, fixed-rate was part of a periodic trigger child element on the poller.
The 4.2 schema is here.
If this is just an IDE error, you can ignore it, or configure your IDE to be "spring aware".
Spring finds the actual schema on the classpath.
With STS, enable "spring nature" on the project.
sometimes it could be due to missing spring-boot-starter-integration & spring-integration-file dependency in pom.xml. So check if actually spring-integration-file dependency is available in your project when you are using spring integration.
I am working with ehcache. I am caching Spring #Service method :
#Service( value = "dataServicesManager" )
#Transactional
public class DataServicesManager implements IDataServicesManager{
#Autowired
private IDataDAO dataDAO;
#Override
#Cacheable( value = "alldatas" )
public List<Data> getAllDatas(Integer param) {
// my logic
return results;
}
// others services
}
Here is the Spring configuration snippet:
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"/>
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="WEB-INF/ehcache.xml"/>
<property name="shared" value="true"/>
</bean>
Here is my ehcache configuration.
<ehcache xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<diskStore path="C:/TEMP/ehcache"/>
<defaultCache eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="1200"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120" />
<cache name="alldatas" maxEntriesLocalHeap="10000" eternal="false"
timeToIdleSeconds="21600" timeToLiveSeconds="21600" memoryStoreEvictionPolicy="LRU">
</cache>
</ehcache>
When i call the service method getAllDatas from a Spring #Controller the method is cached and the second time call retrieve the result stores in cache.
What i don't understand is that i cannot find the <diskStore path="C:/TEMP/ehcache"/> specify in the ehcache.xml. So i have two questions :
Question 1: Why "C:/TEMP/ehcache" directory is not created ?
Question 2: Where is cached my service results ?
Your Ehcache configuration is to blame.
The defaultCache element will only be used when you create a cache programatically without specifying a configuration.
But you define explicitly your alldatas cache, without any disk options.
So your configuration needs to become:
<cache name="alldatas" maxEntriesLocalHeap="10000" eternal="false"
timeToIdleSeconds="21600" timeToLiveSeconds="21600" memoryStoreEvictionPolicy="LRU"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120">
</cache>
And then this cache will use the disk store.
If you do not plan on having other caches in your application, you can also remove the defaultCache element for clarity.
Probably because your retrieved data does not overflow to disk. Caching is done in memory until some threshold is overpassed. Try to reduce the maxEntriesLocalHeap to something that you know is small enough for your data to overflow and see if the file is created.
I'm trying to move the creation of Cache that uses RMI from ehcache.xml file to a Spring xml.
It wasn't a problem to just create a EhCacheFactoryBean but how does RMICacheReplicatorFactory definition suppose to/can be implemented?
Here is how it looks in ehcache.xml file.
Many thanks,
Idan
<cache name="MyCache1"
maxElementsInMemory="1000"
eternal="false"
overflowToDisk="true"
diskSpoolBufferSizeMB="20"
timeToLiveSeconds="3000"
timeToIdleSeconds="3000"
memoryStoreEvictionPolicy="LFU">
<!-- RMI replication listener -->
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true,
replicatePuts=true,
replicatePutsViaCopy=true,
replicateUpdates=true,
replicateUpdatesViaCopy=true,
replicateRemovals=true" />
<!-- RMI Cache bootstrap -->
<bootstrapCacheLoaderFactory
class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
properties="bootstrapAsynchronously=true, maximumChunkSizeBytes=5000000"
propertySeparator="," />
</cache>
When using Spring 3 there is a cacheEventListeners property of type Set<CacheEventListener> for the EhCacheFactoryBean (see https://jira.springsource.org/browse/SPR-6234). When using 2.5 you could extend EhCacheFactoryBean yourself like shown here.
I have been trying to configure JPA with ehcache but no success till now. The configurations which i am doing are :
persistence.xml
<persistence-unit name="customDatabase">
<jta-data-source>jdbc/oracleXE_DS</jta-data-source>
<class>com.td.waw.cse.entities.Product</class>
<properties>
<property name="openjpa.Log" value="DefaultLevel=TRACE, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
<property name="openjpa.QueryCache" value="net.sf.ehcache.openjpa.datacache.EhCacheQueryCache"/>
<property name="openjpa.DataCacheManager" value="net.sf.ehcache.openjpa.datacache.EhCacheDataCacheManager"/>
<property name="openjpa.DataCache" value="net.sf.ehcache.openjpa.datacache.EhCacheDataCache"/>
<property name="openjpa.RemoteCommitProvider" value="net.sf.ehcache.openjpa.datacache.NoOpRemoteCommitProvider"/>
</properties>
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true" monitoring="autodetect"
dynamicConfig="true" >
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
/>
<!-- OpenJPA data cache -->
<cache name="openjpa"
maxElementsInMemory="5000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
/>
<!-- OpenJPA query cache -->
<cache name="openjpa-querycache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
Product.java
#Entity
#Table(name="PRODUCT")
#NamedQueries({#NamedQuery(name="getAllProducts", query = "select products from Product products")})
public class Product implements Serializable {}
I am not getting any exception but i could not see the ehcache working as nothing specific to ehcache printed in the logs.
I would really appreciate if someone can help in this.
Add the following properties in persistence.xml:
<property name="openjpa.QueryCache" value="ehcache"/>
<property name="openjpa.DataCacheManager" value="ehcache"/>
Add the following jars in classpath:ehcache-core-2.4.4.jar, ehcache-openjpa-0.2.0.jar and slf4j-api-1.6.1.jar.
That's all.
Jar Downloads:
link - http://ehcache.org/downloads/catalog?activated=true
ehcache-core-2.4.4.jar and slf4j-api-1.6.1.jar - ehcache-core-2.4.4-distribution.tar.gz module
ehcache-openjpa-0.2.0.jar - ehcache-openjpa-0.2.0-distribution.tar.gz
References
L2 caching explained - http://blogs.oracle.com/carolmcdonald/entry/jpa_caching
OpenJPA L2 caching implementation - http://openjpa.apache.org/builds/1.0.2/apache-openjpa-1.0.2/docs/manual/ref_guide_caching.html
Ehcache OpenJPA implementation - http://www.ehcache.org/documentation/user-guide/openjpa-provider
DataNucleus works perfectly fine with EHCache, with the config specified here
http://www.datanucleus.org/products/accessplatform_2_2/jpa/cache.html#ehcache
It will print log messages about the L2 cache whenever it is accessed. You don't mention your JPA provider.