2013년 11월 29일 금요일

What is the way of Direct Memory Access in Java?

Java was initially designed as a safe, managed environment. Nevertheless, Java HotSpot VM contains a “backdoor” that provides a number of low-level operations to manipulate memory and threads directly.
This backdoor class – sun.misc.Unsafe – is widely used by JDK itself in packages like “java.nio” or “java.util.concurrent”. However, using this backdoor is certainly not suggested for use in the production environment, because this API is extremely dangerous, non-portable, and volatile. The Unsafe class provides an easy way to look into HotSpot JVM internals and to do some tricks. Sometimes it can be used to study VM internals without C++ code debugging, sometimes it can be leveraged for profiling and development tools.

How to use ‘sun.misc.Unsafe’
package com.blogspot.daddycat.test;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

public class UnsafeTest {

   public static void main(String... args) {
       Unsafe unsafe = null;

       try {
           Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
           field.setAccessible(true);
           unsafe = (sun.misc.Unsafe) field.get(null);
       } catch (Exception e) {
           throw new AssertionError(e);
       }

       int ten = 10;
       byte size = 1;
       long mem = unsafe.allocateMemory(size);
       unsafe.putAddress(mem, ten);
       long readValue = unsafe.getAddress(mem);
       System.out.println("Val: " + readValue);

       try {
Object o = unsafe.allocateInstance(java.lang.String.class);
System.out.println("Type: "+o.getClass().getCanonicalName());
} catch (InstantiationException e) {
e.printStackTrace();
}
   }
}

Console log
Val: 10
Type: java.lang.String

2013년 11월 27일 수요일

The Protocol Semantics of HTTP

There are rules. In a RESTful system, clients and servers interact only by sending each other messages that follow a predefined protocol.
The HTTP standard defines eight different kinds of messages, These four are the most commonly used:

GET
Get a representation of this resource.

DELETE
Destroy this resource.

POST
Create a new resource underneath this one, based on the given representation.

PUT
Replace this state of this resource with the one described in the given representation.

These two methods are mostly used as a client explores an API:

HEAD
Get the headers that would be sent along with a representation of this resource, but no the represntation itself.

OPTIONS
Discover with HTTP methods this resource respons to.

The other two methods defined in the HTTP standard, CONNECT and TRACE, are only used with HTTP proxies. I won’t be covering them.

I recommend that API designers consider a ninth HTTP method, defined not in the HTTP standard but in a supplement, RFC 5789:

PATCH
Modify part of the state of this resource based on the given representation. If some bit of resource state is not mentioned in the given representation, leave it alone.

PATCH is like PUT, but allows for fine-grained changes to resource state.

2013년 11월 26일 화요일

log4j의 SMTPAppender


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="mailAppender" class="org.apache.log4j.net.SMTPAppender">
<param name="BufferSize" value="50" />
<param name="SMTPHost" value="sniper.xxxx.co.kr" />
<param name="SMTPPort" value="25" />
<param name="SMTPUsername" value="inter999@xxxx.co.kr" />
<param name="SMTPPassword" value="mypassword" />
<param name="From" value="inter999@xxxx.co.kr" />
<param name="To" value="myID@gmail.com" />
<param name="Subject" value="Testing Log4j mail notification" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{ISO8601}]%n%n%-5p%n%n%c%n%n%m%n%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="error" />
<param name="LevelMax" value="fatal" />
</filter>
</appender>

<root>
<priority value="info" />
<appender-ref ref="mailAppender" />
</root>
</log4j:configuration>
log4j을 사용하지 않는 프로젝트는 없겠죠. 가장 많이 쓰는 Appender는 

ConsoleAppender, DailyRollingFileAppender, FileAppender 이정도 일것이다.

하지만 알고 보면 유용한 Appender들이 있으니
JDBCAppender, JMSAppender, SMTPAppender, SocketAppender, TelnetAppender 등이 있다.

2013년 11월 22일 금요일

Remote Intent를 이용한 안드로이드 장치 간 비동기식 메시지 푸싱 프레임워크

안드로이드 장치용으로 모바일 애플리케이션을 개발할 때 안드로이드의 인텐트(intent)는 안드로이드 장치에서 애플리케이션 내부와 애플리케이션 간의 메시지 전달 메커니즘으로 사용된다. 그러나 안드로이드의 인텐트는 서로 다른 안드로이드 장치 간의 인텐트를 이용한 메시지 전송은 지원되지 않고 있다. 만약 서로 다른 안드로이드 장치 간에 인텐트를 전송하는 기능이 지원된다면 좀 더 다양한 애플리케이션 구현을 쉽게 할 수 있다. 서로 다른 안드로이드 장치 간에 메시지 전송을 할 때 Socket을 이용하여 메시지를 전송 할 수는 있지만, 항상 연결을 유지하여야 한다는 단점이 있다. 따라서 본 논문에서는 서로 다른 안드로이드 장치 간의 메시지 전송을 위한 BRIF(Broadcasting Remote Intent FrameWork) 프레임워크를 제안한다. BRIF 프레임워크는 구글의 C2DM 서비스를 이용하여 서로 다른 안드로이드 장치 간의 메시지 전송을 비동기적으로 푸쉬하는 기능을 서비스하는 프레임워크다. 이것은 기존의 로컬 기기내에서 인텐트를 사용하는 것과 동일한 방법으로 원격지에 사용자 정의 인텐트를 보내는 코드를 쉽게 작성할 수 있다.

키워드 : 애플리케이션, 프레임워크, 인텐트, 안드로이드, 비동기

문서보기

안드로이드 애플리케이션을 테스트하기 위한 액티비티 기반의 테스트 케이스 생성 방법


사용자가 원하는 프로그램을 자유롭게 설치/삭제 할 수 있는 특징을 가진 스마트폰의 등장으로 인해, 수많은 개발자들이 스마트폰 애플리케이션 개발 시장에 뛰어들면서 좋은 애플리케이션을 빨리 개발하려는 경쟁이 더욱 치열해지고 있다. 그러나 안드로이드 환경은 애플리케이션 개발 및 배포 절차가 간단하여 누구나 쉽게 개발에 참여할 수 있어서 충분히 검증되지 않은 애플리케이션들이 배포될 가능성이 높다. 따라서 적은 부담으로 안드로이드 기반의 애플리케이션을 검증할 수 있는 체계적인 방법이 필요하다. 이에 본 논문에서는 안드로이드 애플리케이션을 위한 GUI 기반의 테스트 시나리오 자동 생성 방법을 제시한다. 자동화된 테스트 시나리오 생성을 통해 테스트에 소요되는 시간을 줄임으로써 테스트 단계에서의 생산성을 향상시킬 수 있다.

키워드 : 안드로이드 애플리케이션, GUI 테스팅, 테스트 케이스 생성

문서보기

2013년 11월 21일 목요일

Durable Subscriptions Topic

JMS Topic 에서는 Subscriber가 Server에 접속한 시점부터 발생한 Message을 받아오게 되어 있다. Subscriber가 종료되어 있는 시점에서 발생한 Message는 다시 받을 수 없게 되어 있다. 이러한 방식의 Nondurable Subscription이라한다. 반면  Durable Subscription의 경우는 Subscriber가 종료되어 있는 동안 발생한 Message을 다음 시작시점에 받아오게 되어 있다. 즉 누락되는 Message없이 Topic을 사용할수 있다는 것이다.

Nondurable Subscribers and Subscriptions


A Durable Subscriber and Subscription

Durable Subscriber Code


package example.durabletopic;

import java.util.Date;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Producer {

private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;

public static void main(String[] args) throws JMSException {

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

Topic topic = session.createTopic("example.topic");

MessageProducer producer = session.createProducer(topic);

TextMessage message = session.createTextMessage();

for(int i=0; i<1000; i++) {
message.setStringProperty("date", new Date().toString());
message.setText("HELLO JMS WORLD");
producer.send(message);
System.out.println("Sent message '" + message + "'");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

connection.close();
}
}
Message을 보내는 쪽에서는 Nondurable이든 Durable이든 차이가 없다. 차이는 Message을 받는 쪽에서 생긴다.


package example.durabletopic;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicSubscriber;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Consumers {
public static void main(String[] args) throws JMSException {
new Consumer("C1").start();
}
}

class Consumer extends Thread {

private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;
private String clientID;
public Consumer(String clientID) {
this.clientID = clientID;
}

@Override
public void run() {
Connection connection = null;
try {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
url);
connection = connectionFactory.createConnection();
connection.setClientID(clientID);
connection.start();

Session session = connection.createSession(false,
Session.CLIENT_ACKNOWLEDGE);

Topic topic = session.createTopic("example.topic");

TopicSubscriber durable = session.createDurableSubscriber(topic, "test_durable");

MessageListener listner = new MessageListener() {
public void onMessage(Message message) {
try {
String currentDate = message.getStringProperty("date");
System.out.println("Date:" + currentDate);

if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
System.out.println("Received message"
+ textMessage.getText() + "'");
}
} catch (JMSException e) {
System.out.println("Caught:" + e);
e.printStackTrace();
}
}
};
durable.setMessageListener(listner);
System.out.println("waiting...");
while (true) {
try {
this.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

} catch (JMSException e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}

}

}
Client의 Durable 속성은 “clientID”로 구분되어 서버에서 관리되기 때문에 ClientID는 전체에서 유니크 해야 한다.
최초 clientID로 접속한 이후 부터 Durable 속성이 적용된다. 만일 서버에 등록된 ClientID을 삭제하고 싶다면 “session.unsubscribe(name)”을 사용하면되고, 각 JMS 서버에서 관리하는 설정 값을 사용해도 된다.

ETL 솔루션 환경

ETL 솔루션 환경 하둡은 대용량 데이터를 값싸고 빠르게 분석할 수 있는 길을 만들어줬다. 통계분석 엔진인 “R”역시 하둡 못지 않게 관심을 받고 있다. 빅데이터 역시 데이터라는 점을 볼때 분산처리와 분석 그 이전에 데이터 품질 등 데이...