Thursday, August 13, 2015
Observe folder to pick file when it's available
public class MMTServerStartListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
YourMonitorListenerImpl fileMonitor;
@Override
public void onApplicationEvent(ContextRefreshedEvent context) {
try {
String filePath = "<file path>";
startMonitor(filePath, fileMonitor);
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
}
private void startMonitor(String filePath, YourMonitorListenerImpl fileMonitorImpl) {
try {
if (filePath != null && filePath.length() > 0) {
final File directory = new File(filePath.trim());
FileAlterationObserver fao = new FileAlterationObserver(directory);
fao.addListener(fileMonitorImpl);
final FileAlterationMonitor monitor = new FileAlterationMonitor();
monitor.addObserver(fao);
LOGGER.info("Starting monitor. CTRL+C to stop.");
monitor.start();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
try {
LOGGER.info("Stopping monitor.");
monitor.stop();
} catch (Exception ignored) {
LOGGER.error(ignored.getMessage(), ignored);
}
}
}));
} else {
LOGGER.error("Invalid input the monitor folder");
}
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
}
}
With "YourMonitorListenerImpl" implements "FileAlterationListener" interface.
Wednesday, August 12, 2015
Thread with ExecutorService
ThreadFactory buildCache = new ThreadFactoryBuilder().setNameFormat("thread-name-%d").build();
ExecutorService executorService = Executors.newFixedThreadPool(totalThreads, buildCache);
List<Future> trackingTask = new ArrayList<Future>();
for (int index = 0; index < totalThreads; index++) {
trackingTask.add(executorService.submit(new Runnable() {
@Override
public void run() {
//run your code
}
}));
}
// Run and waiting for task to finish
for (Future task : trackingTask) {
task.get();
}
// Shutdown executor:
executorService.shutdownNow();
ExecutorService executorService = Executors.newFixedThreadPool(totalThreads, buildCache);
List<Future> trackingTask = new ArrayList<Future>();
for (int index = 0; index < totalThreads; index++) {
trackingTask.add(executorService.submit(new Runnable() {
@Override
public void run() {
//run your code
}
}));
}
// Run and waiting for task to finish
for (Future task : trackingTask) {
task.get();
}
// Shutdown executor:
executorService.shutdownNow();
Using Redis cache
Installation:
Follow the instruction at: Install Redis cache in linux - DigitalOceanUsing Redis cache:
Create bean:<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="${atm.cache.redis.host}"
p:port="${atm.cache.redis.port}"
p:poolConfig-ref="jedisPoolConfig"
p:usePool="true"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connectionFactory-ref="jedisConnFactory" p:keySerializer-ref="stringRedisSerializer"/>
Autowired in java implement:
@Autowired
private RedisTemplate<String, ProgramBasicInfo> programRedisTemplate;
Delete all cache: (in this case, it get connection and then flush all data)
programRedisTemplate.getConnectionFactory().getConnection().flushAll();
Delete cache:
programRedisTemplate.opsForHash().getOperations()
.delete(Constants.CACHE_PROGRAM_GUIDE_KEY);
Put data to cache:
programRedisTemplate.opsForHash().put(Constants.CACHE_PROGRAM_GUIDE_KEY, program.getProgramId(), programBasicInfo);
Get data from cache:
(ProgramBasicInfo) programRedisTemplate.opsForHash().get(Constants.CACHE_PROGRAM_GUIDE_KEY, programId);
References:
http://blog.joshuawhite.com/java/caching-with-spring-data-redis/http://caseyscarborough.com/blog/2014/12/18/caching-data-in-spring-using-redis/
Tuesday, August 11, 2015
Synchronize SimpleDateFormat object in Java
SimpleDateFormat object does not work properly in a multi threaded environment. It may output a wrong date when parsing. So the safest way is to synchronize it.
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public String formatDate(Date d) {
synchronized(sdf) {
return sdf.format(d);
}
}
Hope that help.
Sunday, August 9, 2015
Check if a class is loaded and lib file location in JVM
Example below is to see if JVM using ojdbc6 version 11 or version 12.
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
ClassPath clazzPath = ClassPath.from(loader);
Set<ClassInfo> classes = clazzPath.getTopLevelClasses();
for (final ClassPath.ClassInfo classInfo : classes) {
if (classInfo.getName().startsWith("oracle")) {
if (classInfo.getName().contains("oracle.jdbc.babelfish")) {
isVersion12 = true;
}
}
}
if(isVersion12) {
LOGGER.info("Ojdbc version 12");
} else {
LOGGER.info("Ojdbc version 11");
}
Class klass = OracleConnection.class;
URL location = klass.getResource('/' + klass.getName().replace('.', '/') + ".class");
LOGGER.info(location.toString());
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
ClassPath clazzPath = ClassPath.from(loader);
Set<ClassInfo> classes = clazzPath.getTopLevelClasses();
for (final ClassPath.ClassInfo classInfo : classes) {
if (classInfo.getName().startsWith("oracle")) {
if (classInfo.getName().contains("oracle.jdbc.babelfish")) {
isVersion12 = true;
}
}
}
if(isVersion12) {
LOGGER.info("Ojdbc version 12");
} else {
LOGGER.info("Ojdbc version 11");
}
Class klass = OracleConnection.class;
URL location = klass.getResource('/' + klass.getName().replace('.', '/') + ".class");
LOGGER.info(location.toString());
Read package name and version from Manifest file
Bean:
public class BuildVersion {/** The build name. */
private String buildName;
/** The version. */
private String version;
/**
* Gets the version.
*
* @return the version
*/
public String getVersion() {
return version;
}
/**
* set version.
*
* @param version the new version
*/
public void setVersion(String version) {
this.version = version;
}
/**
* Gets the builds the name.
*
* @return the builds the name
*/
public String getBuildName() {
return buildName;
}
/**
* Sets the builds the name.
*
* @param buildName the new builds the name
*/
public void setBuildName(String buildName) {
this.buildName = buildName;
}
}
VersionServiceImpl:
private BuildVersion getBuildVersion() {BuildVersion buildVersion = new BuildVersion();
Class clazz = this.getClass();
String className = clazz.getSimpleName() + ".class";
String classPath = clazz.getResource(className).toString();
try {
String manifestPath = classPath.substring(0, classPath.lastIndexOf("/WEB-INF")) +
"/META-INF/MANIFEST.MF";
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
Attributes attr = manifest.getMainAttributes();
String title = attr.getValue("Specification-Title");
String version = attr.getValue("Specification-Version");
buildVersion.setBuildName(title);
buildVersion.setVersion(version);
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
return buildVersion;
}
VersionEndpoint:
@Component@Path ("/")
public class VersionEndpoint {
/** The version service. */
@Autowired
private VersionService versionService;
/**
* getVersion service use to retrieve the current release version.
*
* @param format the format
* @return Version response
*/
@GET
@Path ("/version")
@Produces ({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response getVersion(@DefaultValue (WSConstants.RESPONSE_TYPE_JSON) @QueryParam ("format") String format) {
try {
return Response.ok().entity(versionService.getVersion()).type(WSUtil.getWSResponseType(format)).build();
} catch (Exception e) {
return Response.ok().entity("Error: " + e.getMessage()).type(WSUtil.getWSResponseType(format)).build();
}
}
}
Install Ibus-unikey in Linux for Vietnamese
Uninstall all preinstalled ibus package and its dependencies
sudo apt-get remove --auto-remove ibus
Purging config/data too
sudo apt-get purge --auto-remove ibus
Maybe restart is needed.
Install new ibus-unikey
sudo apt-get install ibus-unikey
After installing done, run:
ibus-setup
to open Ibus Preferences.
Choose Input method tab, check 'Customize active input methods'. In selection box, click Show all input methods, choose Vietnamese->Unikey.
Logout your system to active the new input method.
Now in top right corner of your screen, you are able to select 'Unikey' to input Vietnamese.
Subscribe to:
Posts (Atom)