'3. Implementation/Java'에 해당되는 글 12건

  1. 2016.07.21 Functions as First-Class Values (1등 시민으로서의 함수)
  2. 2015.02.02 cglib - Byte Code Generation Library
  3. 2015.01.13 Set up spring MVC development environment using Luna
  4. 2014.11.29 Stop thread using own flag and interrupt method
  5. 2013.09.10 Jenkins Plugin Development 참고 사이트
  6. 2011.11.24 Java Reflection 관련
  7. 2011.07.21 간단한 클래스 이름 가져오기
  8. 2010.08.14 인스턴스 초기화
  9. 2010.08.14 JNI - Java Native Interface
  10. 2010.08.14 inner class and static nested class
  11. 2009.08.26 jar 파일 실행 법
  12. 2009.07.28 wait & notify & notifyAll
2016. 7. 21. 13:23

Functions as First-Class Values (1등 시민으로서의 함수)

What is Functions as First-Class Values?


This is translated as "1등 시민으로서의 함수" in Korean. (Why is this translated like that?)

First class? 1등 시민? 


First-class (en-en dictionary)

: If you describe something or someone as first-classyou mean that they are extremely good and of the highest quality.


A class of this term does not mean the class of java. It seems that to distinguish class word from general java class "시민" might be used. 

But it causes me to understand it more confused. 


Anyway, return to the subject.


In Java, we are accustomed to passing objects and primitive values to methods, returning them from methods, and assigning them to variables. This means that objects and primitives are first-class values in Java. 


Java cannot declare any function without a class. Instead java only has methods.

But methods aren't first-class in Java.


You can't pass a method as an argument to another methods, return a method from a method, or assign a method as a value to a variable.


However, most anonymous inner classes are effectively function "wrappers".


Many Java methods take an instance of an interface that declares one method. 



package functions;
import java.awt.*;
import java.awt.event.*;
class HelloButtonApp2 {
 private final Button button = new Button();
 public HelloButtonApp2() {
 button.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent e) {
 System.out.println("Hello There: event received: " + e);
 }
 });
 }
}


Let's introduce a abstraction for all these "function objects"!.



package functions;
public interface Function1Void( <A >) {
 void apply(A a);
}


And let's try to use Function1Void like :


package functions;
import java.fawt.*;
import java.fawt.event.*;
class FunctionalHelloButtonApp {
 private final Button button = new Button();
 public FunctionalHelloButtonApp() {
 button.addActionListener(new Function1Void <ActionEvent >() { // 1
 public void apply(ActionEvent e) { // 2
 System.out.println("Hello There: event received: "+e);
 }
 });
 }
}

Abstraction callback function is great but instead of using this, lambda approach on Java 8 is better. 


Refer : Functional Programming for Java Developers by Dean Wampler

2015. 2. 2. 23:42

cglib - Byte Code Generation Library

cglib - Byte Code Generation Library is high level API to generate and transform Java byte code. It is used by AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access.

https://github.com/cglib/cglib/wiki


Here is good example for this:


http://markbramnik.blogspot.kr/2010/04/cglib-introduction.html


In addition, I attached sample project to be able to run his explanation:



CglibTest.zip



TODO: I need to investigate and study cglib's usage more!


It's now widely used at famous frameworks like Hibernate, Spring and more.

2015. 1. 13. 23:03

Set up spring MVC development environment using Luna

This guide sets up Spring MVC development environment with maven


1. Download eclipse luna


http://www.eclipse.org/luna/


2. Install STS (Spring Tool Suite)


  • Run eclipse
  • Find the Help > Eclipse Marketplace menu on toolbar
  • Type 'sts' on Search tab
  • Click 'install' button which title is 'Spring Tool Suite (STS) for Eclipse Luna ~~~~
  • Restart eclipse

3. Install maven plugin

  • Find the Help > Eclipse Marketplace menu on toolbar
  • Type 'm2e' on Search tab
  • Click 'install' button which title is 'Maven Integration for Eclipse (Luna) 1.5.0'
    • If this was already installed, the buttons are Update and Uninstall. If so, skip this step.
  • Restart eclipse

4. Create Spring MVC Project

  • File > New > Project
  • Type the spring then select 'Spring Project'
  • Select the 'Spring MVC Project' template and specify a project name
  • Proceed nexts until you met the dialog that asks package name
  • Enter any package name and finish it.



2014. 11. 29. 05:46

Stop thread using own flag and interrupt method

Here is the sample code that explains how to stop thread using own flag and interrupt method respectively.


public class Main {

	static interface IClosableThread {
		void start();

		void close();
	}

	static class StopThreadUsingFlag extends Thread implements IClosableThread {
		private boolean stopThis = false;

		public void run() {
			try {
				while (this.stopThis == false) {
					System.out.print(".");
					Thread.sleep(500);
				}
			} catch (InterruptedException e) {
			}

			System.out.println();
			System.out.println("Finished!");
		}

		public void close() {
			this.stopThis = true;

			try {
				this.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	static class StopThreadUsingInterrupt extends Thread implements
			IClosableThread {
		public void run() {
			try {
				while (!this.isInterrupted()) {
					System.out.print(".");
					Thread.sleep(500);
				}
			} catch (InterruptedException e) {
			}

			System.out.println();
			System.out.println("Finished!");
		}

		public void close() {
			this.interrupt();

			try {
				this.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		System.out.println("Hello, Java!");

		IClosableThread thread = new Main.StopThreadUsingFlag();
		thread.start();
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		thread.close();

		thread = new Main.StopThreadUsingInterrupt();
		thread.start();
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		thread.close();

	}
}


2013. 9. 10. 03:10

Jenkins Plugin Development 참고 사이트





2011. 11. 24. 01:32

Java Reflection 관련

권장할 방법은 아니지만 어쩔수 없이 Java Reflection 을 사용할 일이 있어서 이래저래 자료를 찾아보았습니다. 찾아보다가 한가지 궁금한점이 생겼습니다. 상속과 overriding이 되었을 때에도 Java Reflection 이 제대로 동작하는가 였습니다. 어떤 인터넷 글에서 overriding 이 되더라도 Base 클래스의 Reflection 을 사용하면 Base 클래스의 메소드가 호출된다는 내용을 읽은것 같았습니다. 만약 그게 사실이라면 Java Reflection 을 사용할 수 없게 되버리는데 말이죠. (설마?) 그래서 간단한 Sample 을 작성해서 확인해보기로 하였습니다.  

import java.lang.reflect.Field;
import java.lang.reflect.Method;


public class ReflectionTest {
	public static class Base{
		protected int mFlag = 2;
		
		protected void print() {
			System.out.println("Base.Print");
		}
	}
	
	public static class Derived extends Base {
		public Derived() {
			mFlag = 3;
		}
		@Override
		protected void print() {
			System.out.println("Dervied.Print");
		}
	}
	
	public static void printWithReflection(Base base) {
		try {
			Field field = Base.class.getDeclaredField("mFlag");
			field.setAccessible(true);
			int flag = field.getInt(base);
			System.out.println(flag);
			
			Method method = Base.class.getDeclaredMethod("print", null);
			method.setAccessible(true);
			method.invoke(base, null);
		} catch (Exception e) {
		}
	}
	
	public static void main(String [] args) {
		Base base = new Base();
		Derived derived = new Derived();
		
		printWithReflection(base);
		printWithReflection(derived);
	}
}


위 코드에서 Derived 라는 클래스는 Base 클래스의 print 함수를 overriding 하였고, printWithReflection 함수는 Derived 클래스가 아닌 Base 클래스를 이용하여 Field 와 Method 를 받아서 호출하였습니다. 결과는 아래와 같이 overriding 하더라도 문제없이 동작하였습니다. 

2
Base.Print
3
Dervied.Print 
 
2011. 7. 21. 05:40

간단한 클래스 이름 가져오기

패키지 명을 제외한 클래스 이름만 가져오고 싶은 경우가 있습니다.
간단하지만 모르면 . 을 파싱해서 원하는 클래스 이름을 반환하는 함수를 작성하여 사용했었습니다. 물론 아무 의심 없이 구글링을 해서 얻은 정보였습니다. 나쁘진 않지만 간단한 함수가 이미 제공되고 있습니다. 바로 Class 의 getSimpleName() 입니다.

 
TestClass testClass = new TestClass();
testClass.class.getSimpleName();


Class 클래스의 자세한 정보는 아래 링크 참고:
http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Class.html
2010. 8. 14. 05:47

인스턴스 초기화


public class Foo {
    public Foo() { System.out.println("constructor called"); }

    static { System.out.println("static initializer called"); }

    { System.out.println("instance initializer called"); }
}
아래 코드를 실행하면

new Foo();
new Foo();
아래처럼 보이게 된다.

static initializer called
instance initializer called
constructor called
instance initializer called
constructor called
인스턴스 초기화를 사용하면 초기화 관련된 공통 코드를 구현하기에 좋을 것 같다. 
2010. 8. 14. 03:02

JNI - Java Native Interface

JNI - Java Native interface

자바로 작성된 프로그램과 자바로 작성되지 않은 서비스, API 툴킷, 프로그램등과 통합할 필요가 있을 경우 사용합니다. 

JNI 는 자바 가상 머신이 native 메소드를 사용할 수 있도록 하기 위한 표준 이름과 호출 규약을 정의하고 있습니다. 사실,  호스트 운영 체제의 입출력, 그래픽, 네트워킹, 그리고 쓰레딩 연산을 수행하기 위한 로컬 시스템 호출을  자바 가상 머신이 사용하기 위해 JNI 가 자바 가상 머신 내에 만들어져 있습니다.

JNI 예제

ReadFile 자바 소스


import java.util.*;

class ReadFile {
//Native method declaration
  native byte[] loadFile(String name);
//Load the library
  static {
    System.loadLibrary("nativelib");
  }

  public static void main(String args[]) {
    byte buf[];
//Create class instance
    ReadFile mappedFile=new ReadFile();
//Call native method to load ReadFile.java
    buf=mappedFile.loadFile("ReadFile.java");
//Print contents of ReadFile.java
    for(int i=0;i<buf.length;i++) {
      System.out.print((char)buf[i]);
    }
  }
}

Native 메소드 선언

native 선언은 자바 가상 머신에서 native 함수를 실행하기 위한 브리지를 제공한다. 이 예에서는, loadFile 함수를 Java_ReadFile_loadFile 이라는 C 함수로 맵핑한다. 함수 구현은 파일 이름을 나타내는 문자열을 받아서 그 파일의 내용을 바이트 배열로 반환한다.


native byte[] loadFile(String name);

라이브러리 로드

native 코드 구현을 포함하고 있는 라이브러리는 System.loadLibrary() 를 호출함으로써 로드된다. static 초기화 블럭에서 이 함수를 호출하는 것은 라이브러리가 클래스당 한번만 로드되는 것을 보장한다. 라이브러리는 필요하다면 static 블락 밖에서 로드될 수도 있다. 

static {    System.loadLibrary("nativelib");  }
프로그램 컴파일하기

컴파일하기 위해서는, 아래 명령을 수행하면 된다.

javac ReadFile.java

다음은, native 메소드를 선언하는 헤더 파일을 생성할 필요가 있고 파일을 로드하고 읽는 C 함수를 호출하기 위한 native 메소드를 구현해야 한다.

헤더 파일 생성

헤더 파일을 생성하기 위해선, ReadFile 클래스에 대해 javah 명령어를 수행하면 된다. 이 예에서는, 생성된 헤더 파일은 ReadFile.h 라는 이름을 가진다. 이 파일은 loadFile native 함수를 구현할 때 사용되는 메소드 시그너처를 가지고 있다.

javah -jni ReadFile

Note: javah 를 사용할 때, 완전한 클래스 명을 사용해야 한다.

메소드 시그너처

ReadFile.h 헤더 파일은 Java 언어 메소드를 native C 함수로 매핑하기 위한 인터페이스를 정의한다. Java 언어 mappedfile.loadFile 메소드의 인자와 반환값을 nativelib 라이브러리 내에 있는 loadFile native 메소드로 맵핑하기 위한 메소드 시그너처를 사용한다. 아래 그 예이다.


/*
   * Class:     ReadFile
   * Method:    loadFile
   * Signature: (Ljava/lang/String;)[B
   */
  JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile
    (JNIEnv *, jobject, jstring);
메소드 시그너처 파라미터는 다음과 같은 기능을 한다.

* JNIEnv *: JNI 환경에 대한 포인터이다. 이 포인터는 자바 가상 머신의 현재 쓰레드에 대한 핸들이고 맵핑 및 기타 정보를 가지고 있다.

* jobject: 이 native code 를 호출한 메소드에 대한 레퍼런스이다. 호출 메소드가 static 이라면, 이 파라미터는 jobject 대신 jclass 일 것이다.

* jstring: native 메소드에 의해 제공되는 파라미터. 이 예제에서는, 읽을 파일의 이름이다.

native 메소드 구현

아래 C 소스 파일에서, loadFile 선언은 ReadFile.h 에 있는 C 선언을 복사해서 붙여넣은 것이다. JNI 는 기본적으로 C / C++ 모두 에 대한 맵핑을 제공한다.


#include <jni.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile
  (JNIEnv * env, jobject jobj, jstring name) {
    caddr_t m;
    jbyteArray jb;
    jboolean iscopy;
    struct stat finfo;
    const char *mfile = (*env)->GetStringUTFChars(
                env, name, &iscopy);
    int fd = open(mfile, O_RDONLY);

    if (fd == -1) {
      printf("Could not open %s\n", mfile);
    }
    lstat(mfile, &finfo);
    m = mmap((caddr_t) 0, finfo.st_size,
                PROT_READ, MAP_PRIVATE, fd, 0);
    if (m == (caddr_t)-1) {
      printf("Could not mmap %s\n", mfile);
      return(0);
    }
    jb=(*env)->NewByteArray(env, finfo.st_size);
    (*env)->SetByteArrayRegion(env, jb, 0, 
	finfo.st_size, (jbyte *)m);
    close(fd);
    (*env)->ReleaseStringUTFChars(env, name, mfile);
    return (jb);
}
기 존재하는 C 함수를 호출하기 위해서는 아래 두가지 방법중 하나를 선택할 수 있다.

1. JNI 에 의해 생성된 이름을 기 존재하는 C 함수 이름과 매핑한다. Language issue 장에서는 XBase 데이터베이스 함수과 Java 언어 코드 간에 매핑하는 방법을 보여준다. 

2. java.sun.com 웹사이트의 JNI Page 에서 이용가능한 공유 스텁(shared stubs) 을 사용한다.

동적 또는 정적 객체 라이브러리로 컴파일 하기

라이브러리는 실행시 로드될 수 있도록 동적 또는 정적 객체 라이브러리로 컴파일되어야 한다. 정적 또는 아카이브 라이브러리는 실행화일로 컴파일되어 실행시에 로드될 수 없다. 공유 객체 또는 동적 라이브러리로 컴파일하는 예는 아래와 같다.


Gnu C/Linux:

gcc  -o libnativelib.so -shared -Wl,-soname,libnative.so  
     -I/export/home/jdk1.2/include 
     -I/export/home/jdk1.2/include/linux nativelib.c  
     -static -lc

Gnu C++/Linux with Xbase

g++ -o libdbmaplib.so -shared -Wl,-soname,libdbmap.so  
    -I/export/home/jdk1.2/include 
    -I/export/home/jdk1.2/include/linux 
    dbmaplib.cc -static -lc -lxbase


Win32/WinNT/Win2000

cl -Ic:/jdk1.2/include 
   -Ic:/jdk1.2/include/win32 
   -LD nativelib.c -Felibnative.dll
예제 실행하기

예제를 실행하기 위해서는, 자바 가상 머신이 native 라이브러리를 찾을수 있어야 한다. 이렇게 하기 위해, 라이브러리 경로에 현재 경로를 추가한다.



Unix or Linux:
  LD_LIBRARY_PATH=`pwd`
  export LD_LIBRARY_PATH


Windows NT/2000/95:
  set PATH=%path%;.
라이브러리 경로가 올바르게 지정되었다면, 아래 명령으로 실행한다.

java ReadFile

참고: 
2010. 8. 14. 02:38

inner class and static nested class

자바에서 내부 클래스 (inner class) 와 정적 중첩 클래스 (static nested class)의 주요 차이점은 무엇입니까? 설계/구현시 이들 중 어떤것을 선택해야 하는지요?

중첩 클래스(nested class)

중첩 클래스는 두 카테고리로 나누어 집니다. 정적 과 비 정적. static 으로 선언된 중첩 클래스는 간단히 정적 중첩 클래스 (static nested class) 라 부릅니다. 비정적 중첩 클래스는 내부 클래스(inner class)라고 부릅니다.

1. 정적 중첩 클래스(static nested class)

정적 중첩 클래스 는 아래 예처럼 접근할 수 있습니다.

 OuterClass.StaticNestedClass

예를 들어, 정적 중첩 클래스의 객체를 생성하기 위해서는 아래 구문을 사용합니다.

 OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

2. 내부 클래스(inner class)

내부 클래스의 인스턴스 객체는 외부 클래스(outer class)의 인스턴스 내에서 존재합니다. 



아래 클래스를 살펴봅시다.

 class OuterClass {
     ...
     class InnerClass {
        ...
     }
}    

내부 클래스의 인스턴스는 외부 클래스 (outer class)의 인스턴스 내에서만 존재할 수 있으며 메소드 및 필드 역시 '외부클래스.내부클래스' 형식으로 접근할 수 있습니다.

내부 클래스를 인스턴스화하기 위해서는, 외부 클래스의 인스턴스를 먼저 생성해야 합니다. 그러고 나서, 아래 구문을 이용하여 외부 클래스 내의 내부 클래스를 생성합니다.

 OuterClass.InnerClass innerObject = outerObject.new InnerClass();
2009. 8. 26. 05:48

jar 파일 실행 법

심플하다. ㅋ


java -jar filename.jar

출처 : 구글링, http://ubuntuforums.org/showthread.php?t=348698
2009. 7. 28. 07:27

wait & notify & notifyAll

+. Wait set - 쓰레드 대합실

wait set 은 인스턴스의 wait 메소드를 실행한 후 동작을 정지하고 있는 쓰레드들의 집합이다. 예를 들면 인스턴스마다 가지고 있는 쓰레드의 대합실 같은 존재이다.

쓰레드는 wait 메소드를 실행하면 동작을 일시 정지하고 wait 셋이라고 하는 대합실로 들어간다. 쓰레드는 다음중 어느 한 상황이 발생하기 전까지는 영원히 그 wait 셋 안에서 잠들어 있게 된다.

  • 다른 쓰레드에서 notify 메소드에 의해 깨어난다.
  • 다른 쓰레드에서 notifyAll 메소드에 의해 깨어난다.
  • 다른 쓰레드에서 interrupt 메소드에 의해 깨어난다.
  • wait 메소드가 타임아웃 된다.
+. wait 메소드 - 쓰레드를 wait 셋에 넣는다.

wait 메소드를 실행하기 위해서는 쓰레드가 락을 가지고 있어야 한다. 그러나 wait 셋에 들어갈 때 쓰레드는 그 인스턴스의 락을 일단 해제한다. 이것을 그림으로 나타내면 아래와 같다.

락을 취한 쓰레드 A 가 wait 메소드를 실행한다.


쓰레드 A는 wait 셋에 들어가 락을 해제한다.


쓰레드 B는 락을 설정할 수 있게 된다.


+. notify 메소드 - 쓰레드를 wait 셋에서 꺼낸다.

notify 메소드를 사용하면 wait 셋에 있는 쓰레드 한 개를 wait 셋에서 꺼낸다. 이 과정을 그림으로 나타내면 아래와 같다.

락을 취한 쓰레드 B가 메소드를 실행한다.



쓰레드 A가 wait 셋에서 나와 wait 다음 순서로 남어가려 하지만 notify 를 실행한 쓰레드 B가 아직 락을 가지고 있다.



notify를 실행한 쓰레드 B가 락을 해제한다.



wait 셋에서 나온 쓰레드 A가 락을 취하고 wait 다음 순서로 넘어간다.



 notify 메소드를 실행했을 때 wait 셋에서 대기 중인 쓰레드가 여러개라고 하자. 이 때 어느 쓰레드가 선택될지는 정해져 있지 않다. 제일 먼저 wait 한 쓰레드가 선택될지 무작위로 선택될지 그 밖의 방법으로 선택될지는 Java 처리계에 따른다. 그러므로 선택된 쓰레드에 의존하여 프로그램을 작성하는 것은 바람직하지 않다.

+. notifyAll 메소드 - 모든 쓰레드를 wait 셋에서 꺼낸다.

notifyAll 메소드를 사용하면 wait 셋에 있는 모든 쓰레드를 wait 셋에서 꺼낸다. -> 하지만 이 말이 모든 쓰레드가 수행을 시작한다는 의미는 아니다. 락은 이미 notifyAll 을 호출한 쓰레드가 가지고 있으므로 notifyAll 호출 쓰레드가 락을 해제할 때까지 블락된 상태가 된다. 락이 해제된 후, wait 셋에 있는 쓰레드들 중 락을 취한 쓰레드만이 수행을 재개한다.

notifyAll 을 호출하여 wait 셋에 있는 쓰레드들을 깨운다.


Wait 셋에서 깨어난 쓰레드는 인스턴스의 락을 취하기 위해 블락된다.


notiffyAll을 호출한 쓰레드가 락의 소유권을 해제한다.


블락되어 있는 쓰레드들 중 락을 소유한 쓰레드만이 수행을 재개한다.


다시 다음과 같이 wait 셋이 구성 될 것이다.



 notify 메소드와 notifyAll 메소드는 많이 비슷하다. 그렇다면 어느 쪽을 써야 할까?
쉽지 않은 선택이다. notify 가 notifyAll 보다 빠르다. 깨울 쓰레드가 적기 때문이다. 그러나 notify 를 사용할 경우 이용 방법에 따라 프로그램이 멈출 위험이 있다. 일반적으로 notifyAll 을 사용한 쪽이 notify 를 사용한 쪽보다 코드가 견고해진다. 그러니까 프로그래머가 코드의 의미와 한계를 충분히 이해하고 있는 경우가 아니라면 notifyAll 을 사용하는 편이 낫다.

+. wait, notify, notifyAll 은 Object 클래스의 메소드

wait, notify, notifyAll 의 동작을 떠올려 보자.

  • obj.wait 은 obj의 wait 셋에 현재의 쓰레드를 넣는다.
  • obj.notify 는 obj의 wait 셋에서 1개의 쓰레드를 깨운다.
  • obj.notifyAll 은 obj 의 wait 셋에 있는 모든 쓰레드를 깨운다.
즉, wait, notify, notifyAll 은 모두 쓰레드에 대한 조작이라기 보다 인스턴스의 wait 셋에 대한 조작이라고 할 수 있다. wait 셋은 모든 인스턴스가 가지고 있으므로 wait, notify, notifyAll 은 Object 클래스의 메소드인 셈이다.

참고 : Java 언어로 배우는 디자인 입문 : 멀티쓰레드편