问题
I am implementing cache system in maven project.I am not using spring or any framework.The concept is to :
1.At first user will hit the API and Check whether the data is available in cache or not.
2.If cache is empty ,call the database and put values in cache and send them back.
3.If cache is not empty, then return the values from cache.
So,for proper organization,I used the Java caching System(JCS) library,which I took reference from:
https://www.javaworld.com/article/2077936/open-source-java-projects-java-caching-system.html
So,I need to have cache.ccf file which will have all configuration for cache memory.
The logic I used in my service class is.This method will be called from API call:
public List<Album> getAllMusic() {
try
{
Properties props = new Properties();
props.load(new FileInputStream("src/main/resources/log4j.properties"));
PropertyConfigurator.configure(props);
List<Album> albumList = (List) cache.get("musicCache");
System.out.println("Size of album is"+albumList.size());
if(albumList!=null) {
System.out.println("Returning data from cache");
return albumList;
}
} catch(Exception e ){
try{
System.out.println("Putting data in cache");
musicDao.putIncache();
}
catch(Exception ef){
}
return musicDao.getAllTopHundredMusic();
}
return null;
}
At,first I will check the cache using:
List<Album> albumList = (List) cache.get("musicCache");
and in the first instance it will be always empty,so I will call the DAO layer and also put the datas in the cache in same time which is:
System.out.println("Putting data in cache");
musicDao.putIncache();
So,the data gets loaded in the cache,but again when i hit the URL,the cache is still null and it again hits the DAO layer(as in 2nd time hit,it needs to get data from cache not from DAO).I try to check my cache size,but its always empty.When i put the data in cache,its being added in cache but when I try to retrieve it,it is always empty. The logic to put all the data in cache is in DAO layer is:
public void putIncache() {
try {
CompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();
Properties props = new Properties();
props.put("jcs.default","DC");
props.put("jcs.default.cacheattributes",
"org.apache.jcs.engine.CompositeCacheAttributes");
// lots more props.put - this is basically the contents of cache.ccf
Logger log
= Logger.getLogger(MusicDao.class);
ccm.configure(props);
// Load the cache
cache = JCS.getInstance("musicCache");
int i=0;
for(Album a:albumList){
cache.put(new Integer(i+1), a);
}
} catch (CacheException e) {
System.out.println("here");
e.printStackTrace();
}
}
I am putting my full codes now: my model class is:
package com.ashwin.cacheapp.model;
import java.io.Serializable;
public class Album implements Serializable {
private Integer id;
private String artist;
private String title;
public Album() {
}
public Album( Integer id, String artist, String title ) {
this.id = id;
this.artist = artist;
this.title = title;
}
public Integer getId() {
return id;
}
public void setId( Integer id ) {
this.id = id;
}
public String getArtist() {
return artist;
}
public void setArtist( String artist ) {
this.artist = artist;
}
public String getTitle() {
return title;
}
public void setTitle( String title ) {
this.title = title;
}
public String toString() {
return artist + ": " + title;
}
}
The APi call happens through this class:
package com.ashwin.cacheapp;
import com.ashwin.cacheapp.model.Album;
import com.ashwin.cacheapp.response.ResponseGen;
import com.ashwin.cacheapp.service.MusicService;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PUT;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("hello")
@RequestScoped
public class ApiResource {
MusicService musicService=new MusicService();
@GET
@Path("getAllMusic")
@Produces(MediaType.APPLICATION_JSON)
public List<Album> getAllMusic() {
List<Album> albumList=musicService.getAllMusic();
return musicService.getAllMusic();
}
}
MusicService.java
package com.ashwin.cacheapp.service;
import com.ashwin.cacheapp.dao.MusicDao;
import com.ashwin.cacheapp.model.Album;
import org.apache.jcs.JCS;
import java.util.List;
import org.apache.log4j.PropertyConfigurator;
import java.io.FileInputStream;
import java.util.Properties;
//@Stateless
public class MusicService {
private MusicDao musicDao=new MusicDao();
private JCS cache;
public List<Album> getAllMusic() {
try
{
Properties props = new Properties();
props.load(new FileInputStream("src/main/resources/log4j.properties"));
PropertyConfigurator.configure(props);
List<Album> albumList = (List) cache.get("musicCache");
System.out.println("Size of album is"+albumList.size());
if(albumList!=null) {
System.out.println("Returning data from cache");
return albumList;
}
} catch(Exception e ){
try{
System.out.println("Putting data in cache");
musicDao.putIncache();
}
catch(Exception ef){
}
return musicDao.getAllTopHundredMusic();
}
return null;
}
}
The Dao Class is:(I am using dummy datas)
package com.ashwin.cacheapp.dao;
import com.ashwin.cacheapp.model.Album;
import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
import org.apache.jcs.engine.control.CompositeCacheManager;
import org.apache.log4j.Logger;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class MusicDao {
private List<Album> albumList=new ArrayList<Album>();
private JCS cache;
public List<Album> getAllMusic() {
return null;
}
public List<Album> getAllTopHundredMusic() {
albumList.add(new Album(1, "Toby Mac", "Diverse City"));
albumList.add(new Album(2, "Toby Mac", "Diverse City"));
albumList.add(new Album(3, "Toby Mac", "Diverse City"));
albumList.add(new Album(4, "Toby Mac", "Diverse City"));
albumList.add(new Album(5, "Toby Mac", "Diverse City"));
albumList.add(new Album(6, "Toby Mac", "Diverse City"));
albumList.add(new Album(7, "Toby Mac", "Diverse City"));
albumList.add(new Album(8, "Toby Mac", "Diverse City"));
albumList.add(new Album(9, "Toby Mac", "Diverse City"));
albumList.add(new Album(10, "Toby Mac", "Diverse City"));
albumList.add(new Album(11, "Toby Mac", "Diverse City"));
albumList.add(new Album(12, "Toby Mac", "Diverse City"));
albumList.add(new Album(13, "Toby Mac", "Diverse City"));
albumList.add(new Album(14, "Toby Mac", "Diverse City"));
albumList.add(new Album(15, "Toby Mac", "Diverse City"));
albumList.add(new Album(16, "Toby Mac", "Diverse City"));
albumList.add(new Album(17, "Toby Mac", "Diverse City"));
albumList.add(new Album(18, "Toby Mac", "Diverse City"));
albumList.add(new Album(19, "Toby Mac", "Diverse City"));
return albumList;
}
public void putIncache() {
try {
CompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();
Properties props = new Properties();
props.put("jcs.default","DC");
props.put("jcs.default.cacheattributes",
"org.apache.jcs.engine.CompositeCacheAttributes");
// lots more props.put - this is basically the contents of cache.ccf
Logger log
= Logger.getLogger(MusicDao.class);
ccm.configure(props);
// Load the cache
cache = JCS.getInstance("musicCache");
int i=0;
for(Album a:albumList){
cache.put(new Integer(i+1), a);
}
} catch (CacheException e) {
System.out.println("here");
e.printStackTrace();
}
}
}
In src/main/resource
i have config file cache.ccf as:
jcs.default=
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=200
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.elementattributes.IsEternal=false
jcs.default.elementattributes.MaxLifeSeconds=86400
jcs.default.elementattributes.IdleTime=86400
I dont know whether this file is either called from class path or not so i added in my pom.xml as:
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.ccf</include>
</includes>
</resource>
</resources>
in pom.xml it is:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ashwin</groupId>
<artifactId>CacheApp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>CacheApp</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>jfrog-libs</id>
<name>jfrog-libs</name>
<url>http://repo.jfrog.org/artifactory/libs-releases</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jcs-core</artifactId>
<version>2.2.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/jcs/jcs -->
<dependency>
<groupId>jcs</groupId>
<artifactId>jcs</artifactId>
<version>1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/concurrent/concurrent -->
<dependency>
<groupId>concurrent</groupId>
<artifactId>concurrent</artifactId>
<version>1.3.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.ccf</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
My output when i call api http://localhost:8080/api/hello/getAllMusic
is:
Putting data in cache
Putting data in cache
Putting data in cache
Putting data in cache
My expected output is:
Putting data in cache
Returning data from cache
Returning data from cache
Returning data from cache
Returning data from cache
Edited Source code: I made the new class MusicClass.java
package com.ashwin.cacheapp.dao;
import com.ashwin.cacheapp.model.Album;
import com.ashwin.cacheapp.model.Student;
import java.util.Properties;
import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
import org.apache.jcs.engine.control.CompositeCacheManager;
import org.apache.log4j.Logger;
public class MusicCache {
private JCS cache;
// static variable single_instance of type Singleton
private static MusicCache single_instance=null;
// private constructor restricted to this class itself
private MusicCache()
{
try {
CompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();
Properties props = new Properties();
props.put("jcs.default","DC");
props.put("jcs.default.cacheattributes",
"org.apache.jcs.engine.CompositeCacheAttributes");
// lots more props.put - this is basically the contents of cache.ccf
Logger log
= Logger.getLogger(MusicDao.class);
ccm.configure(props);
// Load the cache
cache = JCS.getInstance("musicCache");
cache.put( "123", new Student( 123, "John", "Swizher", "Weige", "Civil") );
cache.put( "143", new Student( 143, "Theoder", "", "Sattler", "Computer Science" ) );
cache.put( "153", new Student( 153, "Martin", "Sam", "Suckhorozka", "Electrical" ) );
cache.put( "163", new Student( 163, "Russel", "", "Latour", "Mechanical" ) );
} catch (CacheException e) {
System.out.println("here");
e.printStackTrace();
}
}
// static method to create instance of Singleton class
public static MusicCache Singleton()
{
// To ensure only one instance is created
if (single_instance == null)
{
single_instance = new MusicCache();
}
return single_instance;
}
}
Changing in function of service class is:
public List<Album> getAllMusic() {
try
{
Properties props = new Properties();
props.load(new FileInputStream("src/main/resources/log4j.properties"));
PropertyConfigurator.configure(props);
List<Album> albumList = (List) cache.get("musicCache");
System.out.println("Size of album is"+albumList.size());
if(albumList!=null) {
System.out.println("Returning data from cache");
return albumList;
}
} catch(Exception e ){
try{
System.out.println("Putting data in cache");
MusicCache x = MusicCache.Singleton();
}
catch(Exception ef){
}
return musicDao.getAllTopHundredMusic();
}
return null;
}
Still I got the same output
来源:https://stackoverflow.com/questions/57729882/cache-memory-not-saving-values-in-cache-when-running-the-project