java에서 FileOutputStream 과 FileOutputStream을 감싸는 FilterOutputStream를 이용해서 파일을 저장할 때가 있을 때 보통 FilterOutputStream만 flush와 close() 메서드 콜만 하고 끝나는 경우의 코드들이 있다.

그러나 좀 더 확실히 하기 위해서는 FileOutputStream 의 getFD() 메소드를 호출하여 FileDescriptor 를 꺼집어 내서 sync() 메서드 콜을 해야 함으로 안정하게 sync 해야 physical device에 데이터가 저장된다.

flush는 그냥 버퍼를 비우는 것 뿐이고, sync 는 파일시스템 내부의 캐쉬를 모두 physical device로 가는 것이다. 확실히 저장시키는 습관이 필요하다. 

 

1. 일반 IO의 경우는 아래와 같이 사용한다.

FileOutputStream fos = new FileOutputStream(“file.db”);
DataOutputStream stream = new DataOutputStream(fos);
stream.write(1); 
stream.flush();
fos.getFD().sync();
stream.close();

-------------------------------

2. NIO의 경우는 아래와 같이 사용한다.

FileOutputStream s = new FileOutputStream(filename) ;
Channel c = s.getChannel() ;
c.write(buffer);
c.force(true) ;
s.getFD().sync() ;
c.close() ;

Posted by '김용환'
,

 

김성근감독님의 책을 볼 때마다 개발자로 사는 것, 그리고 진정한 인간으로 사는 것은 야구와 비슷하다는 생각이 든다. 끝없는 훈련, 따뜻한 마음, 냉정한 머리, 분명함, 리더쉽 내용이 좋다. 시련과 두려움을 이겨내고 좋은 야구를 만들듯. 나도 내 인생의 야구를 만들어내고 싶다. 적당한 것에 대한 타협, 안정감을 버려야지….

 

 

image

 

리더는 외로워야 한다. 외로운게 리더다. 선수들 정신 교육하고, 왜 정신 못차리냐고, 왜 똑바로 야구 못하느냐고 가르친다. 그게 김성근이다.

 

일년 내내 달릴 수 있는 팀은 어디에도 없다. 달릴 수 없는 상황까지 계산에 넣어두고 있어야 한다.

성적이 떨어져서 감독이 지나치게 손을 대면 팀 분위기는 더 나빠진다. 감독과 선수 모두가 불안감 때문에 제대로 경기를 못한다.

 

감독의 불안이 선수들에게 전해지면 이미 진 것이다.

 

일이라는 것은 소위 신념을 가지고 강한 의지로 자신의 목적을 달성하는 것이다.

 

내가 선수들 혹사시킨다는 말을 들으면서 죽기 살기로 연습시키는 이유는 딱 하나다. 선수를 만들기 위해서이다.

안전함 속에서 무슨 일을 어떻게 할 수 있을까. 지독하게 훈련하는 과정에서 성장이 일어나고, 단 한순간도 집중력을 잃지 않아야 이길 수 있는 게 승부의 세계다.

그냥 하는 연습하는 중 하루가 아니라, 생각이 바뀌고 몸이 바뀐 중요한 순간을 만든 것이다.

 

강하니까 이길 수 있는 게 아니라, 이길 때까지 하니까 강한 것이니까.

 

“너 사람들한테 인정받으려고 바꾸는거야? 너 스스로가 바뀌면 그걸로 되잖아. 왜 다른 사람이 인정을 안해줬다고 원점으로 돌리려고 해. 시작이 틀린 거 잖아.”

 

리더는 절대 혼자 갈 수 없는 사람이다. 조금 느리더라도 한마음을 가지고 함께 가야 한다. 마음을 얻어 한마음으로 함께 가야 멀리까지 갈 수 있다.

 

내가 제일 싫어하는 말은 만족과 여유다.

 

결단은 모든 것을 다 얻겠다는 마음에서 하는 게 아니다. 오히려 얼마나 과감하게 버릴 수 있냐가 중요하다.

 

두려운 것은 똑같지만 그것을 뛰어넘게 해주는 것이 안간힘이다.

 

훈련은 약속이다. 자기와의 약속을 지킬 때 야구는 그때 완성될 수 있다.

 

항상 인내하고 눈과 귀를 열고 순수한 마음으로 받아들일 건 받아야 한다.

 

결과가 안 좋다고 자신의 믿음을 저버리는 인내는 선수를 속이고, 나를 속이는 말장난에 그칠 뿐이다.

 

너희들 삼진 먹어도 된다. 하지만 그 안에 근거가 있어야 돼.

 

내가 가장 좋아하는 길은 야구장 가는 길이다. 앞으로도 나는 그 길 위에서 부딪히며 살 것이다. 그것이 나의 베스트이다.

Posted by '김용환'
,
Posted by '김용환'
,
Posted by '김용환'
,

 

* 리눅스 시스템 & 커널 기초- 한빛 미디어

리눅스 커널쪽으로 쉽게 접근할 수 있는 책 (깊게 안들어가서 초보자가 보기에 딱 좋은 책) 2.4 기준임

6장 메모리 관리

 
* 대학교 자료
http://mie.pcu.ac.kr/Lectures%20Data/LinuxEmbeddedSystem/10/Ch06_%EB%A9%94%EB%AA%A8%EB%A6%AC%20%EA%B4%80%EB%A6%AC%20%5B%ED%98%B8%ED%99%98%20%EB%AA%A8%EB%93%9C%5D.pdf

리눅스 시스템 및 커널 기초를 자료로 만든 자료임

 

* proc 파일 시스템과 물리 주소/가상주소/MMU 이야기를 쉽게 정리한 문서

http://www.kandroid.org/board/data/board/linux/file_in_body/1/device_driver-14.pdf

 

* 페이지 테이블에 주소 변환 정보가 채워지는 원리

http://www.iamroot.org/xe/index.php?mid=Kernel_8_ARM_H&document_srl=54103

 
* 누군가 공부하다만 자료
http://www.google.com/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=18&ved=0CFQQFjAHOAo&url=http%3A%2F%2Fulkml.googlecode.com%2Ffiles%2F%25EB%25A9%2594%25EB%25AA%25A8%25EB%25A6%25AC_%25EB%25B0%259C%25ED%2591%259C%25EC%259E%2590%25EB%25A3%258C3.pptx&ei=_lxET_a3A-mAmQXdtIyiBA&usg=AFQjCNElA1sVVUkItGAOEp0BjCOEUbqJcw



* 리눅스 커널 프로그래밍- 한빛미디어

8장 메모리 관리




* 잘 정리한 웹 자료

http://dojeun.egloos.com/317480

Posted by '김용환'
,

 

스마트폰에서 했던 Cut the rope 게임이 웹으로 오픈되었다.

http://www.cuttherope.ie/

IE9 또는 다른 브라우져(크롬 등등)에서 작동됨

 

image

Posted by '김용환'
,



java에서 jvm으로 넘어오면 파라미터를 체크하려면 좀 귀찮은 작업을 해야 하는데. Apache common cli를 쓰면 좀 편리하다.  properties 체크도 할 때 하려면 귀찮아서 추후를 위해서 만들어본다.


Test.java

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;


public class Test {
 public static final String DEFAULT_CONFIG = "a.prop";
 
 public static void main(String[] args) throws Exception {
  Map<String, String> propMap = readProperties();
  Map<String, String> argMap = readOption(args);
  if (argMap == null) {
   return;
  }
  
  //...
  System.out.println("property..");
  for (Map.Entry<String,String> entry : propMap.entrySet()) {
   System.out.println("key : " + entry.getKey() + ", value : " + entry.getValue());
  }
  
  System.out.println("argument..");
  for (Map.Entry<String,String> entry : argMap.entrySet()) {
   System.out.println("key : " + entry.getKey() + ", value : " + entry.getValue());
  }
 }

 private static Map<String, String> readOption(String[] args) throws ParseException {
  Options options = new Options();
  options.addOption("m", "mode", true, "mode data");
  options.addOption("n", "num", true, "number data");

  CommandLineParser parser = new PosixParser();
  CommandLine cmd = parser.parse(options, args);

  if (!cmd.hasOption('n') || !cmd.hasOption('m')) {
   HelpFormatter formatter = new HelpFormatter();
   formatter.printHelp("Help ....", options);
   return null;
  }
  
  Map<String, String> map = new HashMap<String, String>();
  String number = cmd.getOptionValue('n');
  String mode = cmd.getOptionValue('m');
  map.put("number", number);
  map.put("mode", mode);
  return map;
 }

 private static Map<String, String> readProperties() throws IOException {
  InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(DEFAULT_CONFIG);
  if (in == null) {
   throw new IOException("Not found config file " + DEFAULT_CONFIG);
  }

  Properties properties = new Properties();
  properties.load(in);
  
  Map<String, String> map = new HashMap<String, String>();
  for (Map.Entry<Object,Object> entry : properties.entrySet()) {
   map.put((String) entry.getKey(), (String)entry.getValue());
  }
  return map;
 }
}




a.prop


a=1
b=2


그냥 실행시에는 에러가 발생


usage: Help ....
 -m,--mode <arg>   mode data
 -n,--num <arg>    number data


파라미터를 넘기면(-n 5 -m run) 다음과 같은 결과 나옴

property..
key : b, value : 2
key : a, value : 1
argument..
key : number, value : 5
key : mode, value : run




pom.xml의 추가할 depdendency 추가.



  <dependency>
   <groupId>commons-cli</groupId>
   <artifactId>commons-cli</artifactId>
   <version>1.1</version>
  </dependency>
Posted by '김용환'
,

 

jconsole은 업데이트가 잘 안되어서, 거의 버려진 반면 (그래도 jconsole이 내게는 편하다..)  jvisualvm은 계속 업데이트되고 있다. plugin이 짱이고, 이젠 대세로 되어가고 있다. 좋은 툴이다.

 

$java-home/bin 디렉토리에 있는 jconsole.exe 파일을 실행한다.

image

 

메뉴의 Tools->Plugins를 실행한다.

image

 

내가 원하는 플러그인을 체크해서 설치한다.  (주로 볼 것은 MBeans이다.)

image

 

설치하는 화면이 계속 보인다.

image

 

어그리먼트에 어그리해준다.

image

 

다시 jvisualvm을 실행하고 나서, jmx connection을 하나 연다.

image

 

탭이 여러 개 생긴 것을 확인할 수 있다.

image

 

mbean의 com.sun.management의 HotSpotDiagnostic 을 선택한다.

image

 

jconsole과 크게 다르지 않다.

image

 

heap dump를 날려준다~

image

 

 

그리고, jconsole 을 썼던 아쉬운 점도 해결할 수 있다.  플러그인 설치할 때, Options로 한다.

 

Tools->Options를 선택한다.

image

jdk 의 demo/management에 있는 jar 를 추가한다.

image

 

 

점점 jvisualvm은 좋아지고 있다.

http://visualvm.java.net/ 을 참조하면 떢고물이 나온다. 참 예전에는 힘들게 했는데.. 세상이 좋아지고 있다.

image

Posted by '김용환'
,

 

tomcat 6 에서 동작하던 웹 어플리케이션을 tomcat 7 (7.0.25) 으로 올려보았다.  tomcat 7이 servlet 3.0의 comet을 지원하는 것외에 특별히 고쳤을까 싶었는데..

tomcat6의 catalina.sh를 그대로 사용할 때와 tag library쪽에 이슈가 있었다.

 

## catalina.sh start 되게

설정 파일 conf/server.xml과 bin/catalina.sh 는 tomcat 6에 있는 것으로 사용하려고 하다가 다음과 같은 에러를 만났다. (역시 tomcat 7의 catalina.sh을 사용하는 것이 맞을 듯.)

java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory

 

tomcat7의 catalina.sh 에 classpath에 bin/tomcat-juli.jar 부분이 변경된 것 같다.

# Add tomcat-juli.jar to classpath
# tomcat-juli.jar can be over-ridden per instance
if [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then
  CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar
else
  CLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar
fi

 

또한 입맛에 좀 맞게 catalina.sh를 변경해야 한다.  (CATALINA_JAVAOPTS, $CATALINA_LOGDIR, CATALINA_LOGFILE, CATALINA_HOME)

conf/server.xml은 그대로 수정해서 사용하니 잘 동작된다.

 

## catalina.sh  stop되게

stop 시에 대한 설정을 일부 수정해야 한다.

stop을 하면, sleep 5초를 한다. (디폴트) kill 하고, 안죽으면 force하게 죽는 작업이 되어 있다.

이 부분을 입맛에 맞게 변경

 

## catalina.sh configtest

아파치의 문법 체크(httpd -t )처럼 설정 문법을 테스트하는게 생겼다.

 

소스는 다음과 같다.

elif [ "$1" = "configtest" ] ; then
   
    eval \"$_RUNJAVA\" $JAVA_OPTS \
      -Djava.endorsed.dirs=\"$JAVA_ENDORSED_DIRS\" -classpath \"$CLASSPATH\" \
      -Dcatalina.base=\"$CATALINA_BASE\" \
      -Dcatalina.home=\"$CATALINA_HOME\" \
      -Djava.io.tmpdir=\"$CATALINA_TMPDIR\" \
      org.apache.catalina.startup.Bootstrap configtest
    result=$?
    if [ $result -ne 0 ]; then
        echo "Configuration error detected!"
    fi   
    exit $result
fi

 

 

## Tomcat 이슈

tomcat6에서 잘 동작하는 소스를 tomcat 7에서 돌릴 때는 어떠할까. 태그 라이브러리쪽에 이슈가 있었다.

org.apache.jasper.JasperException: The absolute uri: http://taglib.google.com/hiu cannot be resolved in either web.xml or the jar files deployed with this application

at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:56)
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:410)
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:117)
at org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:311)
at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:152)
at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:410)
at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:475)
at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1427)
at org.apache.jasper.compiler.Parser.parse(Parser.java:138)
at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:242)
at org.apache.jasper.compiler.ParserController.parse(ParserController.java:102)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:198)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:373)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:353)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:340)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:357)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

 

tomcat 6에서는 기존에 tag library 파일들을 META-INF 디렉토리안에 넣으면 자동으로 인식하는 기능이 있었는데, 이 부분이 tomcat 7부터는 web.xml에 명시적으로 관련 정보를 넣는 구조로 바뀌었다.

 

즉 기존의 파일은 다음과 같이 사용했다.


src/main/java/META-INF/taglib/hiu-taglib.tld

<?xml version="1.0" encoding="UTF-8"?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">

    <description>HIU Custom Tags</description>
    <tlib-version>1.2</tlib-version>
    <short-name>hiu</short-name>
    <uri>http://taglib.google.com/hiu</uri>


<tag>

….

</tag>

…..

 

web.xml에 taglibarary에 대한 url와 location에 대해서 명확히 지정해야 한다.

(tld 파일을 META-INF가 아닌 WEB-INF 로 이동해야 잘 인식해서 WEB-INF 로 이동하니 잘된다.
/META-INF/taglib.tld 파일로 수정해도 인식 못한다. )

* web.xml에 추가할 내용

<jsp-config>
    <taglib>
        <taglib-uri>http://taglib.google.com/hiu</taglib-uri>
        <taglib-location>/WEB-INF/hiu-taglib.tld</taglib-location>
    </taglib>
</jsp-config>

WEB-INF 디렉토리 밑에 tag lib를 두면 자동으로 인식하기 때문에 꼭 저렇게 사용하지는 않아도 된다.

정확한 지식을 위해서 jsp 2.2 스펙을 참조한다.

 

 

* Java Server Page 2.2 specification (tomcat 7이 적용, jsp 2.2) 
http://jcp.org/aboutJava/communityprocess/mrel/jsr245/index.html

스펙을 참조하니. 이해가 되었다. 역시 스펙의 힘이란…

 

예제가 설명이 되어 있다.

 

순서에 대한 정보도 있다.

자세한 내용은 아래를 참조하면 된다.

JSP.7.3.2 TLD resource path
JSP.7.3.3 Taglib Map in web.xml
JSP.7.3.4 Implicit Map Entries from TLDs
JSP.7.3.5 Implicit Map Entries from the Container
JSP.7.3.6 Determining the TLD Resource Path

Posted by '김용환'
,

 

CENTOS 4.7 운영체제를 설치하고 자바 7을 설치했는데, dl (dynamic lib) 에러가 난다. glic 2.4 이상이 설치되어야 jdk 7이 돌아가는 것 같다. Oracle 공식 문서(readme, announcement)에서는 이 부분을 못찾았다.

glic 버전을 확인하니. 2.3이다.

]# ldd --version

ldd (GNU libc) 2.3.4

 

java 1.7.0을 설치했다..

]# java –version
Error: dl failure on line 875
Error: failed /home/www/apps/jdk1.7.0/jre/lib/i386/server/libjvm.so, because /lib/tls/libc.so.6: version `GLIBC_2.4' not found (required by /home/www/apps/jdk1.7.0/jre/lib/i386/server/libjvm.so)

 

java 1.7.0_03을 설치했다. (wget http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-i586.tar.gz)

]# java –version
Error: dl failure on line 875
Error: failed /home/www/apps/jdk1.7.0_03/jre/lib/i386/server/libjvm.so, because /lib/tls/libc.so.6: version `GLIBC_2.4' not found (required by /home/www/apps/jdk1.7.0_03/jre/lib/i386/server/libjvm.so)

 

 

인터넷을 검색하니. “jdk7-b64 has new dependency on glibc-2.4” 이런 내용도 나오구..

http://mail.openjdk.java.net/pipermail/nio-dev/2009-July/000602.html

 

-------------

다른 장비는 CentOS 5.3 이다. glibc는 2.5 이다.

]# ldd --version
ldd (GNU libc) 2.5

 

]# ./java -version
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) Server VM (build 22.1-b02, mixed mode)

 

리눅스에서 java 7을 사용하려면 glibc 2.4를 쓰는 게 좋을 것 같다.

Posted by '김용환'
,