하이버네이트 튜토리얼을 보며 따라하고 있는데 SessionFactory 빈을 생성하는 과정에서 예외가 발생하면서 아래와 같은 스택을 뿌리며 생성에 실패한다.


Caused by: java.util.MissingFormatArgumentException: Format specifier '%s'

at java.util.Formatter.format(Formatter.java:2519) ~[na:1.8.0_25]

at java.util.Formatter.format(Formatter.java:2455) ~[na:1.8.0_25]

at java.lang.String.format(String.java:2927) ~[na:1.8.0_25]

at org.jboss.logging.Slf4jLocationAwareLogger.doLogf(Slf4jLocationAwareLogger.java:81) ~[jboss-logging-3.1.3.GA.jar:3.1.3.GA]

at org.jboss.logging.Logger.debugf(Logger.java:553) ~[jboss-logging-3.1.3.GA.jar:3.1.3.GA]

at org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl.classForName(StandardClassLoaderDelegateImpl.java:53) ~[hibernate-commons-annotations-4.0.4.Final.jar:4.0.4.Final]

at org.hibernate.cfg.annotations.SimpleValueBinder.fillSimpleValue(SimpleValueBinder.java:491) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]

at org.hibernate.cfg.SetSimpleValueTypeSecondPass.doSecondPass(SetSimpleValueTypeSecondPass.java:42) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]

at org.hibernate.cfg.Configuration.processSecondPassesOfType(Configuration.java:1470) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]

at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1418) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]

at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]

at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928) ~[hibernate-core-4.3.5.Final.jar:4.3.5.Final]

at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]

at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:454) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]

at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:439) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]

... 43 common frames omitted





구글링으로 예외와 관련한 것들을 찾아보다가, 비슷한 유형이 나타나지 않길래 라이브러리 내에서 어떤 부분이 문제인지를 확인하려고 org.hibernate.annotations.common.util.StandardClassLoaderDelegateImpl 클래스를 따라가보니 아래 부분에서 예외가 발생했다.


catch ( Throwable ignore ) {

log.debugf( "Unable to locate Class [%s] using TCCL, falling back to HCANN ClassLoader" );

}


빨간색으로 표기한 %s에 전달되어야 할 문자열을 전달하지 않아서 발생하는 예외였다. 실수는 할 수 있지만.. 유틸리티성 클래스라 테스트 커버리지에 포함되지 않아서인지 릴리즈에 버젓이 나 버그요 어디 한번 실행해 보시지 하는 태도라니.


이는 하이버네이트 ORM 4.3.5.Final 버전에서 발생하며, 이 후 버전에서는 고쳐진 듯 하다. (4.3.10.Final 버전으로 확인하니 예외가 발생하지 않는다.)


사실 상용 프레임워크나 소프트웨어는 거의 사용하지 않고 오픈 소스를 주로 이용하다보니, 검증없이 신뢰하기 마련인데, 이번 계기로 모든 것에 의심을 가지자는 태도를 다시 갖춰야겠다.

CentOS 서버에 SSH 연결 후에 잠시 다른 창에서 작업하고 있으면 창이 꺼지는 바람에 이유를 찾아보니

/etc/bashrc 파일의 TMOUT 환경변수 때문이었다.


TMOUT=300

readonly TMOUT

export TMOUT



보안상으로 세션의 타임아웃 값을 지정해 일정 시간동안 동작이 없으면 자동으로 로그아웃하는 것이 권장되지만, 테스트 서버에서는 불편하기만 한지라..(편리함을 얻고 보안을 버린다!는 망언) TMOUT 값을 지우려고 unset을 해보았다.


$ unset TMOUT

bash: PI: readonly variable


/etc/bashrc 파일에서 readonly TMOUT 이라고 된 것을 확인했을 때는 값만 변경할 수 없는 줄 알았더니,

환경 변수의 삭제 또한 할 수 없었다.



구글링을 통해 쉽게 Stackoverflow에서 답을 찾을 수 있었다.


$ readonly PI=3.14

$ unset PI

-bash: unset: PI: cannot unset: readonly variable

$ cat << EOF| sudo gdb

attach $$

call unbind_variable("PI")

detach

EOF

$ echo $PI


$


gdb를 통해 bash의 unbind_variable 메서드를 호출함으로써 변수를 제거한다.

답변 작성자에 따르면 이는 일종의 핵이며(디버거를 통해 프로세스 내부의 함수를 호출하는 것이므로), 추천하는 방법이 아니라고 한다. 사용 시의 위험에 대해서는 본인이 책임지라고 적어두었다.


참 재미있는 쉘 스크립트의 세계 'ㅅ'


참고 : Stack overflow - Unset readonly variable in bash

집에 여자친구가 쓰는 IKEA 포엥 암체어와 풋스툴 쿠션은 있는데,
풋스툴 프레임이 없다(!), 암체어를 사다 놓았는데 왜 쓰질 못하니!! ㅠㅠㅠ


목공방 수업을 하며 남는 재료를 어디에 쓸까하던 참에 수제(짝퉁) 풋스툴 프레임을 만들기로 했다. 완성한다면 아래와 같은 모습이 된다.

(이미지 출처 : (좌)http://baniworld.tistory.com/420, (우)http://ilovecurry.tistory.com/28)


일단 그림이 그려져야 하니 어설프게 설계 비슷한 스케치를 한다.

풋스툴이 무릎에 닿는 부분은 암체어의 앞쪽 높이와 같아야 하고, 반대쪽 부분은 다리를 올렸을 때 편한 자세를 유지할 수 있도록 무릎쪽과 14도 가량의 기울기로 기울어져야 한다. 프레임 설계도가 없어 풋스툴 사진을 보고 눈대중으로 해서 잘 맞을 지 모르겠다. 암체어의 길이가 500mm, 무릎쪽 다리가 360mm, 발끝쪽 다리가 260mm로 계산했던지라 오랜만에 삼각함수를 썼다.. 가물 가물해서 간단한 삼각함수임에도 한참을 고민했다...;

이케아 정품 프레임의 경우 가로로 고정하는 부분과 옆 쪽 프레임 결합 시 위의 그림처럼 긴 피스와 결합되는 반대쪽에 피스를 단단하게 고정하기 위한 너트가 있는데, 같은 방식으로 해볼까하다가 재료가 있는지도 모르고, 괜히 잘못되면 슬퍼질까 하여 배운 방법으로 단순하게 피스로만 고정하기로 했다.


좀더 구체적(인지는 모르겠지만)으로 잡아본 스케치, 정품은 ㄷ자의 프레임이 하나의 세트이고, 견고하기 때문에 가로로 고정하는 부분 이외에 추가적으로 지지대를 잡아주지 않아도 되지만, 목공방 선생님이 보시고는 전,후면의 지지대 말고 좌,우의 지지대도 추가해야 튼튼할 것 같다고 말씀해 주셔서 그림엔 없는 좌, 우측의 지지대도 추가하기로 했다.


  작업 1일차 (15. 6. 18.)

​상단 2개의 조각, 종아리 부분이 맞닿을 수 있는 부분이라 완곡한 모서리를 위해 샌딩을 열심히 했다. 샌딩 작업만 한 시간 반 이상한 것 같다.. 재단하고 샌딩하는데 두 시간 반의 수업 시간이 모두 지나가버렸다.

먼저 거친 사포로 모서리를 과하다 싶을 정도로 갈아내고, 부드러운 사포로 마무리했다. 위 사진은 아직 마무리가 덜 된 상태.


앞, 뒤쪽의 4개의 다리 부분. 아래쪽의 라운딩 처리한 부분도 샌딩 작업의 결과.. 심히 노가다 작업이었다. 같이 수업 들으시는 분들이 보고는 어떻게 동그랗게 했냐고 여쭤보시길래 사포질로만 했다고 하니 놀라신다. 내심 뿌듯하다 ㅋㅋ



  작업 2일차 (15. 6. 25.)

생각보다 진도를 많이 나가진 못했다. 목표는 오늘이 완성이었건만 한 쪽 프레임만 상단 부분까지 조립하고, 반대쪽은 아래쪽의 지지대만 결합하는 것까지 진행했다.

모든 부분이 직각이 아니고 기울기를 가진 부분이 있다보니 생각보다 길이 계산이 쉽지 않다. 이번엔 길이를 계산하지 않고 직각자와 눈대중으로 길이를 쟀더니.. 낭패..

네 개의 다리 중 긴 부분을 기울기에 맞게 잘라내야 했다. 거기에 목공 비트로 윗 부분을 고정했는데, 이것도 맞추기가 여간 쉽지 않다. 틀어지지 않게 한다고 했건만 틀어져버려서 목공비트가 들어가는 곳에 뚫은 구멍을 넓혀서 간격을 맞춰야 했다.

이제 남은 작업은 쿠션을 올릴 받침을 지지하는 지지대와, 쿠션 받침 부분인데.. 이번 주의 경험을 토대로 좀 더 정확하게 만들어 봐야겠다.

정품 풋 스툴 프레임의 경우 쿠션을 얹으면 프레임이 쿠션보다 위로 더 올라오게 되는데, 잘라낸 길이를 고려하면 프레임과 쿠션의 높이를 같게 하거나 쿠션의 높이가 조금 더 높도록 지지대를 대야겠다. 

다음 주에는 원래 수업 진도를 나가게 되어서 아마 다다음 주가 되어야 완성할 수 있을 것 같다. 그 사이에 쿠션을 받치는 5T 두께의 합판을 구해봐야겠다.


<뚝딱이 목공방 작업실 전경>


  작업 3일차 (15. 7. 1.)

일단 프레임은 완성! 직각이 아닌 것을 다루는 게 이렇게나 어려운 건 줄 몰랐다.. 부분 부분 어긋나서 목심으로 짜맞춘 곳은 삐뚤삐뚤하기도 해서, 목심이 들어가는 구멍을 넓혀서 차이를 메꿔야 했다. 그래서 단단히 고정되지 못하고 흔들흔들하는 건 어쩔 수 없는 결과.. 목공방 선생님도 "다음 주엔 보강작업을 해야겠구만!" 하셨다. 네. 그렇습니다. 어떻게 보강을 하면 좋을까요? 흔들 풋스툴이 될 수는 없으니까요.


수업 내용을 따라 이 전에 작업해뒀던 좌식 책상에 오일 스테인으로 마감하고, 프레임을 만들고 나니 오늘 수업은 끝. 책장을 만들어야 하는데 책장 옆 부분을 만들기 위한 재료가 없어진 건 함정, 왜 내가 이름을 안써뒀을까. 허허 ㅜㅜ 누가 훔쳐가지 않아도 이름이 없으면 헷갈려서 누군가가 써버릴 수도 있는 일인데.. 다음 주까지 없으면 선생님께서 더 잘라주신다곤 하셨지만 그건 너무 죄송하다. 있는 재료로 다른 걸 만들어볼까도 생각 중이다.

다음 주엔 튼튼하게 고정되도록 보강작업을 하고, 쿠션 받침을 넣으면 이제 완성이다. 수업 내용에 쓰는 시간과 풋스툴 프레임을 만드는 시간을 적절히 잘 분배해서 꼭 완성시켜야지.


  작업 4일차 (15. 7. 8.)

스피디하게 쿠션 받침대를 재단하여 프레임을 조립해 보았다. 지금은 조립할 수 있는 헐렁헐렁한(?) 상태지만 맞춰본 후에는 목공 본드로 본딩을 해야한다. 이케아는 조립이지만 나는 완성형(?)의 프레임인 셈이다.



다리쪽에 피스로 고정한 부분에 목심을 만들어 채워주고, 목심으로 고정한 부분은 목공 본드를 바른 후 클램프로 고정을 시켜두었다.

여담으로 4.8T 쿠션 받침대용 판을 쓰려고 자투리 재료로 보이는 아이로 가져와서 선생님께 이거 써도 되냐고 여쭤보니.. 좀 그렇지만 쓰셔도 된다고 말씀하셔서 뭐지..? 했더니. 자작나무라 저 크기에 5만원이었다고... 어이쿠 그 돈이면 이케아 프레임을 그냥 사겠다 'ㅅ';;;


클램프로 고정한 모습! 본드가 마르고, 마감만 하면 이제 끝! 집에 잘 데려오기만 하면 프레임 위에 쿠션을 깔고, 다리를 올릴 수 있는 풋스툴이 된다. 잘 말라서 튼튼하게 붙어 있으렴


web.xml 파일에 아래 필터를 추가하고 추가한 필터를 모든 URI에 대해 매핑하도록 설정한다.

필터가 두 개 이상인 경우 web.xml 파일 상에서 가장 위에 위치하도록 해야한다.


    <filter>

        <filter-name>encoding-filter</filter-name>

        <filter-class>

            org.springframework.web.filter.CharacterEncodingFilter

        </filter-class>

        <init-param>

            <param-name>encoding</param-name>

            <param-value>UTF-8</param-value>

        </init-param>

        <init-param>

        <param-name>forceEncoding</param-name>

        <param-value>true</param-value>

        </init-param>

    </filter>


    <filter-mapping>

        <filter-name>encoding-filter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>


본 문서는 ID3v24 Structure 문서(http://id3.org/id3v2.4.0-structure)를 번역한 글입니다.

잘못된 번역 또는 오탈자에 대한 지적은 달갑게 받도록 하겠습니다 :)




비공식 표준 문서 M. Nilsson

파일명: id3v2.4.9-structure.txt 2000. 11. 1.


ID3 태그 버전 2.4.0 - 기본 구조


이 문서의 상태

    

   이 문서는 비공식적인 표준이며, ID3v2.3.0 표준을 대체한다 [ID3v2]. 공식 표준문서와 내용이

같더라도, 다른 리비전 번호를 사용할 것이다. 내용을 명확하게 하기 위해 변경될 수는 있지만

기능적으로 추가되거나 대체되지는 않을 것이다.


이 문서의 배포에는 제한이 없다.



초록


   이 문서는 비공식 표준인 ID3v2 [ID3v2]의 수정된 버전으로써 ID3v2.4.0의 기본 구조를

설명한다. ID3v2는 오디오 파일 내에서 오디오의 메타 정보를 저장하는 유연한 방법을 제공한다.

포함되는 정보는 이퀄라이제이션 커브와 같은 기술적인 정보뿐만 아니라 제목, 연주자, 저작권

등의 정보이다.


   ID3v2.4.0은 구현을 가능한 용이하게 수정할 수 있도록 하기 위해 되도록 ID3v2.3.0과

유사하게 구성한다.



1. 목차


이 문서의 상태

초록

1. 목차

2. 이 문서의 규칙

2. 표준 개요

3. ID3v2 개요

3.1. ID3v2 헤더(Header)

3.2. ID3v2 확장된 헤더(Extended header)

3.3. 패딩(Padding)

3.4. ID3v2 푸터(Footer)

4. ID3v2 프레임개요

4.1. 프레임 헤더 플래그

4.1.1. 프레임 상태 플래그

4.1.2. 프레임 포맷 플래그

5. 태그 위치

6. 비동기화(Unsynchronisation)

6.1. 비동기화 스키마

6.2. Synchsafe 정수

7. 저작권

8. 참조

9. 작성자 주소



2. 이 문서의 규칙


태그에 표시된 따옴표(")안의 텍스트는 정확한 텍스트 문자열이다.

숫자 앞의 $ 기호는 16진수를 의미하며, %기호는 이진수를 의미한다. $xx는 바뀔 수 있는 두 자리의

16진수를 나타내는 데 사용된다. %x는 바뀔 수 있는 한 자리의 이진수를 나타내는 데 사용된다.

바이트의 최상위 비트(MSB, Most significant bit)는 7번 비트이며, 최하위 비트(LSB, Least

significant bit)는 0번 비트로 부른다.


태그는 이 문서의 전체 태그를 지칭하며, 프레임은 태그의 정보를 갖는 블럭이다. 태그는 헤더, 프레임

및 옵션 패딩으로 구성되어 있다. 필드는 하나의 값, 문자열과 같은 정보의 한 부분이다. 숫자 문자열은

문자 "0123456789"로 구성된 문자열이다. "반드시 ~이어야 한다", "반드시 ~이 아니어야 한다.",

"필수", "가능", "가능하지 않을 수 있다.", "권장", "~일 수 있다.", "선택 사항"과 같은 표현은

RFC 2119 [KEYWORDS]에 기술된 바와 같이 해석될 수 있다.


(주: 영어 표현에서는 RFC 2119의 키워드를 사용할 수 있으나 번역하는 경우 위의 키워드를 정의하여 번역에 사용하기에는 문맥 또는 어감에 따라 표현이 달라질 수 있음)



3. ID3v2 개요


ID3v2는 해당 오디오 파일 내에 오디오에 관한 메타 데이터를 저장할 수 있게하는 범용의 오디오 태그

포맷이다. 이 문서에서 설명하는 ID3 태그는 주로 MPEG-1/2/ 레이어 I, MPEG-1/2/ 레이어 II,

MPEG-1/2 레이어 III 그리고 MPEG-2.5로 인코딩된 파일을 대상으로 하지만, 다른 타입으로 인코딩된

오디오나 오디오 메타 데이터를 위한 독립형 포맷으로 작업할 수 있다.


ID3v2는 발생할 수 있는 새로운 메타 정보의 요구를 충족하기 위해 유연하고 확장 가능하도록 설계되었다.   ID3v2는 프레임으로 칭하는 다양한 정보 블럭을 위한 컨테이너를 구성하며, 오디오 파일을 읽는

소프트웨어에서 ID3v2에 대해 고려하지 않을 수 있도록 한다. 모든 프레임의 시작 부분은 소프트웨어에

알려지지 않은 프레임 및 플래그 필드를 스킵할 수 있도록 하는 미리 정의된 식별자와 크기를 기술한다.  

플래그는 인코딩의 상세 정보와, 소프트웨어에서 알 수 없는 태그를 프레임에 유지될 수 있도록 하고,

파일이 변경되었는지를 설명한다.


ID3v2의 비트 순서(비트오더, bit order)는 MSB(최상위 비트)가 첫 번째이다. 멀티 바이트로 구성된

숫자의 바이트 순서(바이트오더) 에서의 최상위바이트는 첫 번째이다(예, $12345678은 $12 34 56 78로

인코딩된다). 또한 빅 엔디안(big endian)으로 알려진 네트워크 바이트 순서를 사용한다.


전체 태그 구조


     +-----------------------------+

     |       헤더 (10 바이트)      |

     +-----------------------------+

     |       확장된 헤더       |

     | (가변 길이, 선택 사항) |

     +-----------------------------+

     |   프레임 (가변 길이)  |

     +-----------------------------+

     |           패딩           |

     | (가변 길이, 선택 사항) |

     +-----------------------------+

     | 푸터 (10 바이트, 선택사항) |

     +-----------------------------+


일반적으로 패딩과 푸터는 상호 배타적이다. 상세한 내용은 3.3.절, 3.4.절, 5.절에서 확인할 수 있다.



3.1. ID3v2 헤더


ID3v2 태그의 첫 번째 부분은 10 바이트의 태그 헤더이다. 다음과 같이 배치된다.


ID3v2/파일 식별자 "ID3"

ID3v2 버전 $04 00

ID3v2 플래그 %abcd0000

ID3v2 크기 4 * %0xxxxxx


태그의 첫 3 개 바이트는 항상 "ID3"이며, 곧이어 따라오는 두 개의 버전을 의미하는 바이트는 ID3v2 태그의

버전을 나타낸다. ID3v2 버전의 첫 번째 바이트는 메이저 버전이고, 두 번째 바이트는 리비전 번호이다.

위 경우는 ID3v2.4.0을 의미한다. 모든 리비전은 하위 호환성을 가지지만, 메이저 버전은 하위 호환성을

갖지 않는다. 만약 ID3v2.4.0 이하를 지원하는 소프트웨어가 5 이상을 만나면 태그 전체를 무시하면 된다.

버전 또는 리비전은 절대 $FF가 될 수 없다.

버전 뒤의 ID3v2 플래그 필드는 현재 네 개의 플래그 비트만 사용된다. a - 비동기(Unsynchronisation) 'ID3v2 플래그'의 7번 비트는 모든 프레임에 비동기를 사용할 지의 여부를 나타낸다. (상세한 내용은 6.1.

절 참조) 플래그 비트가 셋인 경우(1인 경우) 사용함을 나타낸다. b - 확장된 헤더(Extended header) 두 번째 비트(6번 비트)는 태그 헤더가 확장되었는지 여부를 나타낸다. 확장된 헤더는 3.2.절에서 설명한다. 플래그 비트가 셋인 경우 확장된 헤더를 사용하는 것을 나타낸다. c - 실험용 지시자(Experimental indicator) 세 번째 비트(5번 비트)는 '실험용 지시자'로 사용된다. 실험용 태그를 사용하는 경우 이 플래그 값이

셋(set, 1) 되어야 한다. d - 푸터 여부(Footer present) 4번 비트는 태그의 끝을 의미하는 푸터를 나타낸다 (3.4. 절). 값이 셋 된 경우 푸터가 있음을 의미한다.

위의 4개 외의 모든 플래그는 반드시 %abcd0000 과 같이 0이어야 한다. 정의되지 않은 비트 중의 하나가 셋인

경우 플래그의 기능을 알지 못하는 파서는 태그를 읽지 못할 수 있다. ID3v2 태그 크기는 28비트의 유효한 크기를 가진 32비트의 Synchsafe 정수(6.2. 절)로 저장된다. (256MB

까지 표현됨) ID3v2 태그의 크기는 확장된 헤더, 패딩 그리고 비동기(Unsynchronisation) 뒤의 프레임의 바이트 길이의

합이다. 푸터를 사용한다면 ('전체 크기' - 20)바이트와 같고, 사용하지 않는다면 ('전체 크기' - 10) 바이트

와 같다. ID3v2 태그는 아래의 패턴으로 찾을 수 있다. $49 44 33 yy yy xx zz zz zz zz yy 부분이 $FF 보다 작을 때, xx는 '플래그' 바이트이고, zz는 $80보다 작다. 3.2. 확장된 헤더 확장된 헤더는 태그 구조의 자세한 이해를 제공할 수 있는 정보를 포함하고 있지만, 확장된 헤더는 선택적인

부분이므로 태그 정보를 정확하게 파싱하는 것은 중요하지 않다. 확장된 헤더 크기 4 * %0xxxxxxx 플래그 바이트 수 $01 확장된 플래그 $xx '확장된 헤더 크기'는 32비트의 Synchsafe 정수로 표현된 전체 확장된 헤더의 크기이다. 따라서 확장된 헤더의 크기는 절대 6 바이트보다 작은 크기를 갖지 않는다. '플래그 바이트 수'에 의해 크기가 정해진 확장된 플래그 필드는 다음과 같이 정의된다. %0bcd0000 Each flag that is set in the extended header has data attached, which comes in the order in which the flags are encountered (i.e. the data for flag 'b' comes before the data for flag 'c'). Unset flags cannot have any attached data. All unknown flags MUST be unset and their corresponding data removed when a tag is modified. Every set flag's data starts with a length byte, which contains a value between 0 and 128 ($00 - $7f), followed by data that has the field length indicated by the length byte. If a flag has no attached data, the value $00 is used as length byte. b - Tag is an update If this flag is set, the present tag is an update of a tag found earlier in the present file or stream. If frames defined as unique are found in the present tag, they are to override any corresponding ones found in the earlier tag. This flag has no corresponding data. Flag data length $00 c - CRC data present If this flag is set, a CRC-32 [ISO-3309] data is included in the extended header. The CRC is calculated on all the data between the header and footer as indicated by the header's tag length field, minus the extended header. Note that this includes the padding (if there is any), but excludes the footer. The CRC-32 is stored as an 35 bit synchsafe integer, leaving the upper four bits always zeroed. Flag data length $05 Total frame CRC 5 * %0xxxxxxx d - Tag restrictions For some applications it might be desired to restrict a tag in more ways than imposed by the ID3v2 specification. Note that the presence of these restrictions does not affect how the tag is decoded, merely how it was restricted before encoding. If this flag is set the tag is restricted as follows: Flag data length $01 Restrictions %ppqrrstt p - Tag size restrictions 00 No more than 128 frames and 1 MB total tag size. 01 No more than 64 frames and 128 KB total tag size. 10 No more than 32 frames and 40 KB total tag size. 11 No more than 32 frames and 4 KB total tag size. q - Text encoding restrictions 0 No restrictions 1 Strings are only encoded with ISO-8859-1 [ISO-8859-1] or UTF-8 [UTF-8]. r - Text fields size restrictions 00 No restrictions 01 No string is longer than 1024 characters. 10 No string is longer than 128 characters. 11 No string is longer than 30 characters. Note that nothing is said about how many bytes is used to represent those characters, since it is encoding dependent. If a text frame consists of more than one string, the sum of the strungs is restricted as stated. s - Image encoding restrictions 0 No restrictions 1 Images are encoded only with PNG [PNG] or JPEG [JFIF]. t - Image size restrictions 00 No restrictions 01 All images are 256x256 pixels or smaller. 10 All images are 64x64 pixels or smaller. 11 All images are exactly 64x64 pixels, unless required otherwise. 3.3. Padding It is OPTIONAL to include padding after the final frame (at the end of the ID3 tag), making the size of all the frames together smaller than the size given in the tag header. A possible purpose of this padding is to allow for adding a few additional frames or enlarge existing frames within the tag without having to rewrite the entire file. The value of the padding bytes must be $00. A tag MUST NOT have any padding between the frames or between the tag header and the frames. Furthermore it MUST NOT have any padding when a tag footer is added to the tag. 3.4. ID3v2 footer To speed up the process of locating an ID3v2 tag when searching from the end of a file, a footer can be added to the tag. It is REQUIRED to add a footer to an appended tag, i.e. a tag located after all audio data. The footer is a copy of the header, but with a different identifier. ID3v2 identifier "3DI" ID3v2 version $04 00 ID3v2 flags %abcd0000 ID3v2 size 4 * %0xxxxxxx 4. ID3v2 frame overview All ID3v2 frames consists of one frame header followed by one or more fields containing the actual information. The header is always 10 bytes and laid out as follows: Frame ID $xx xx xx xx (four characters) Size 4 * %0xxxxxxx Flags $xx xx The frame ID is made out of the characters capital A-Z and 0-9. Identifiers beginning with "X", "Y" and "Z" are for experimental frames and free for everyone to use, without the need to set the experimental bit in the tag header. Bear in mind that someone else might have used the same identifier as you. All other identifiers are either used or reserved for future use. The frame ID is followed by a size descriptor containing the size of the data in the final frame, after encryption, compression and unsynchronisation. The size is excluding the frame header ('total frame size' - 10 bytes) and stored as a 32 bit synchsafe integer. In the frame header the size descriptor is followed by two flag bytes. These flags are described in section 4.1. There is no fixed order of the frames' appearance in the tag, although it is desired that the frames are arranged in order of significance concerning the recognition of the file. An example of such order: UFID, TIT2, MCDI, TRCK ... A tag MUST contain at least one frame. A frame must be at least 1 byte big, excluding the header. If nothing else is said, strings, including numeric strings and URLs [URL], are represented as ISO-8859-1 [ISO-8859-1] characters in the range $20 - $FF. Such strings are represented in frame descriptions as <text string>, or <full text string> if newlines are allowed. If nothing else is said newline character is forbidden. In ISO-8859-1 a newline is represented, when allowed, with $0A only. Frames that allow different types of text encoding contains a text encoding description byte. Possible encodings: $00 ISO-8859-1 [ISO-8859-1]. Terminated with $00. $01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All strings in the same frame SHALL have the same byteorder. Terminated with $00 00. $02 UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM. Terminated with $00 00. $03 UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00. Strings dependent on encoding are represented in frame descriptions as <text string according to encoding>, or <full text string according to encoding> if newlines are allowed. Any empty strings of type $01 which are NULL-terminated may have the Unicode BOM followed by a Unicode NULL ($FF FE 00 00 or $FE FF 00 00). The timestamp fields are based on a subset of ISO 8601. When being as precise as possible the format of a time string is yyyy-MM-ddTHH:mm:ss (year, "-", month, "-", day, "T", hour (out of 24), ":", minutes, ":", seconds), but the precision may be reduced by removing as many time indicators as wanted. Hence valid timestamps are yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddTHH, yyyy-MM-ddTHH:mm and yyyy-MM-ddTHH:mm:ss. All time stamps are UTC. For durations, use the slash character as described in 8601, and for multiple non- contiguous dates, use multiple strings, if allowed by the frame definition. The three byte language field, present in several frames, is used to describe the language of the frame's content, according to ISO-639-2 [ISO-639-2]. The language should be represented in lower case. If the language is not known the string "XXX" should be used. All URLs [URL] MAY be relative, e.g. "picture.png", "../doc.txt". If a frame is longer than it should be, e.g. having more fields than specified in this document, that indicates that additions to the frame have been made in a later version of the ID3v2 standard. This is reflected by the revision number in the header of the tag. 4.1. Frame header flags In the frame header the size descriptor is followed by two flag bytes. All unused flags MUST be cleared. The first byte is for 'status messages' and the second byte is a format description. If an unknown flag is set in the first byte the frame MUST NOT be changed without that bit cleared. If an unknown flag is set in the second byte the frame is likely to not be readable. Some flags in the second byte indicates that extra information is added to the header. These fields of extra information is ordered as the flags that indicates them. The flags field is defined as follows (l and o left out because ther resemblence to one and zero): %0abc0000 %0h00kmnp Some frame format flags indicate that additional information fields are added to the frame. This information is added after the frame header and before the frame data in the same order as the flags that indicates them. I.e. the four bytes of decompressed size will precede the encryption method byte. These additions affects the 'frame size' field, but are not subject to encryption or compression. The default status flags setting for a frame is, unless stated otherwise, 'preserved if tag is altered' and 'preserved if file is altered', i.e. %00000000. 4.1.1. Frame status flags a - Tag alter preservation This flag tells the tag parser what to do with this frame if it is unknown and the tag is altered in any way. This applies to all kinds of alterations, including adding more padding and reordering the frames. 0 Frame should be preserved. 1 Frame should be discarded. b - File alter preservation This flag tells the tag parser what to do with this frame if it is unknown and the file, excluding the tag, is altered. This does not apply when the audio is completely replaced with other audio data. 0 Frame should be preserved. 1 Frame should be discarded. c - Read only This flag, if set, tells the software that the contents of this frame are intended to be read only. Changing the contents might break something, e.g. a signature. If the contents are changed, without knowledge of why the frame was flagged read only and without taking the proper means to compensate, e.g. recalculating the signature, the bit MUST be cleared. 4.1.2. Frame format flags h - Grouping identity This flag indicates whether or not this frame belongs in a group with other frames. If set, a group identifier byte is added to the frame. Every frame with the same group identifier belongs to the same group. 0 Frame does not contain group information 1 Frame contains group information k - Compression This flag indicates whether or not the frame is compressed. A 'Data Length Indicator' byte MUST be included in the frame. 0 Frame is not compressed. 1 Frame is compressed using zlib [zlib] deflate method. If set, this requires the 'Data Length Indicator' bit to be set as well. m - Encryption This flag indicates whether or not the frame is encrypted. If set, one byte indicating with which method it was encrypted will be added to the frame. See description of the ENCR frame for more information about encryption method registration. Encryption should be done after compression. Whether or not setting this flag requires the presence of a 'Data Length Indicator' depends on the specific algorithm used. 0 Frame is not encrypted. 1 Frame is encrypted. n - Unsynchronisation This flag indicates whether or not unsynchronisation was applied to this frame. See section 6 for details on unsynchronisation. If this flag is set all data from the end of this header to the end of this frame has been unsynchronised. Although desirable, the presence of a 'Data Length Indicator' is not made mandatory by unsynchronisation. 0 Frame has not been unsynchronised. 1 Frame has been unsyrchronised. p - Data length indicator This flag indicates that a data length indicator has been added to the frame. The data length indicator is the value one would write as the 'Frame length' if all of the frame format flags were zeroed, represented as a 32 bit synchsafe integer. 0 There is no Data Length Indicator. 1 A data length Indicator has been added to the frame. 5. Tag location The default location of an ID3v2 tag is prepended to the audio so that players can benefit from the information when the data is streamed. It is however possible to append the tag, or make a prepend/append combination. When deciding upon where an unembedded tag should be located, the following order of preference SHOULD be considered. 1. Prepend the tag. 2. Prepend a tag with all vital information and add a second tag at the end of the file, before tags from other tagging systems. The first tag is required to have a SEEK frame. 3. Add a tag at the end of the file, before tags from other tagging systems. In case 2 and 3 the tag can simply be appended if no other known tags are present. The suggested method to find ID3v2 tags are: 1. Look for a prepended tag using the pattern found in section 3.1. 2. If a SEEK frame was found, use its values to guide further searching. 3. Look for a tag footer, scanning from the back of the file. For every new tag that is found, the old tag should be discarded unless the update flag in the extended header (section 3.2) is set. 6. Unsynchronisation The only purpose of unsynchronisation is to make the ID3v2 tag as compatible as possible with existing software and hardware. There is no use in 'unsynchronising' tags if the file is only to be processed only by ID3v2 aware software and hardware. Unsynchronisation is only useful with tags in MPEG 1/2 layer I, II and III, MPEG 2.5 and AAC files. 6.1. The unsynchronisation scheme Whenever a false synchronisation is found within the tag, one zeroed byte is inserted after the first false synchronisation byte. The format of synchronisations that should be altered by ID3 encoders is as follows: %11111111 111xxxxx and should be replaced with: %11111111 00000000 111xxxxx This has the side effect that all $FF 00 combinations have to be altered, so they will not be affected by the decoding process. Therefore all the $FF 00 combinations have to be replaced with the $FF 00 00 combination during the unsynchronisation. To indicate usage of the unsynchronisation, the unsynchronisation flag in the frame header should be set. This bit MUST be set if the frame was altered by the unsynchronisation and SHOULD NOT be set if unaltered. If all frames in the tag are unsynchronised the unsynchronisation flag in the tag header SHOULD be set. It MUST NOT be set if the tag has a frame which is not unsynchronised. Assume the first byte of the audio to be $FF. The special case when the last byte of the last frame is $FF and no padding nor footer is used will then introduce a false synchronisation. This can be solved by adding a footer, adding padding or unsynchronising the frame and add $00 to the end of the frame data, thus adding more byte to the frame size than a normal unsynchronisation would. Although not preferred, it is allowed to apply the last method on all frames ending with $FF. It is preferred that the tag is either completely unsynchronised or not unsynchronised at all. A completely unsynchronised tag has no false synchonisations in it, as defined above, and does not end with $FF. A completely non-unsynchronised tag contains no unsynchronised frames, and thus the unsynchronisation flag in the header is cleared. Do bear in mind, that if compression or encryption is used, the unsynchronisation scheme MUST be applied afterwards. When decoding an unsynchronised frame, the unsynchronisation scheme MUST be reversed first, encryption and decompression afterwards. 6.2. Synchsafe integers In some parts of the tag it is inconvenient to use the unsychronisation scheme because the size of unsynchronised data is not known in advance, which is particularly problematic with size descriptors. The solution in ID3v2 is to use synchsafe integers, in which there can never be any false synchs. Synchsafe integers are integers that keep its highest bit (bit 7) zeroed, making seven bits out of eight available. Thus a 32 bit synchsafe integer can store 28 bits of information. Example: 255 (%11111111) encoded as a 16 bit synchsafe integer is 383 (%00000001 01111111). 7. Copyright Copyright (C) Martin Nilsson 2000. All Rights Reserved. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that a reference to this document is included on all such copies and derivative works. However, this document itself may not be modified in any way and reissued as the original document. The limited permissions granted above are perpetual and will not be revoked. This document and the information contained herein is provided on an 'AS IS' basis and THE AUTHORS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 8. References [ID3v2] Martin Nilsson, 'ID3v2 informal standard'. <url:http://www.id3.org/id3v2.3.0.txt> [ISO-639-2] ISO/FDIS 639-2. 'Codes for the representation of names of languages, Part 2: Alpha-3 code.' Technical committee / subcommittee: TC 37 / SC 2 [ISO-3309] ISO 3309 'Information Processing Systems--Data Communication High-Level Data Link Control Procedure--Frame Structure', IS 3309, October 1984, 3rd Edition. [ISO-8859-1] ISO/IEC DIS 8859-1. '8-bit single-byte coded graphic character sets, Part 1: Latin alphabet No. 1.' Technical committee / subcommittee: JTC 1 / SC 2 [JFIF] 'JPEG File Interchange Format, version 1.02' <url:http://www.w3.org/Graphics/JPEG/jfif.txt> [KEYWORDS] S. Bradner, 'Key words for use in RFCs to Indicate Requirement Levels', RFC 2119, March 1997. <url:ftp://ftp.isi.edu/in-notes/rfc2119.txt> [MPEG] ISO/IEC 11172-3:1993. 'Coding of moving pictures and associated audio for digital storage media at up to about 1,5 Mbit/s, Part 3: Audio.' Technical committee / subcommittee: JTC 1 / SC 29 and ISO/IEC 13818-3:1995 'Generic coding of moving pictures and associated audio information, Part 3: Audio.' Technical committee / subcommittee: JTC 1 / SC 29 and ISO/IEC DIS 13818-3 'Generic coding of moving pictures and associated audio information, Part 3: Audio (Revision of ISO/IEC 13818-3:1995)' [PNG] 'Portable Network Graphics, version 1.0' <url:http://www.w3.org/TR/REC-png-multi.html> [UNICODE] The Unicode Consortium, 'The Unicode Standard Version 3.0', ISBN 0-201-61633-5. <url:http://www.unicode.org/unicode/standard/versions/Unicode3.0.htm> [URL] T. Berners-Lee, L. Masinter & M. McCahill, 'Uniform Resource Locators (URL)', RFC 1738, December 1994. <url:ftp://ftp.isi.edu/in-notes/rfc1738.txt> [UTF-8] F. Yergeau, 'UTF-8, a transformation format of ISO 10646', RFC 2279, January 1998. <url:ftp://ftp.isi.edu/in-notes/rfc2279.txt> [UTF-16] F. Yergeau, 'UTF-16, an encoding of ISO 10646', RFC 2781, February 2000. <url:ftp://ftp.isi.edu/in-notes/rfc2781.txt> [ZLIB] P. Deutsch, Aladdin Enterprises & J-L. Gailly, 'ZLIB Compressed Data Format Specification version 3.3', RFC 1950, May 1996. <url:ftp://ftp.isi.edu/in-notes/rfc1950.txt> 9. Author's Address Written by Martin Nilsson Rydsv�gen 246 C. 30 SE-584 34 Link�ping Sweden Email: nilsson at id3.org




'싹이 움트다 > MP3Tagger' 카테고리의 다른 글

MP3Tagger 프로젝트  (0) 2015.06.05

MP3Tagger Project

ID3v24 태그 분석 및 태깅을 위한 자바로 작성된 라이브러리


GitHub https://github.com/nnoco/mp3tagger

'싹이 움트다 > MP3Tagger' 카테고리의 다른 글

ID3v24 Structure 번역 - 작성 중  (0) 2015.06.05

여자친구가 Umano로 공부를 하고 있는데, Umano 개발팀이 드랍박스로 합류하게 되어 Umano 서비스가 종료되는 바람에 Umano MP3를 다운로드하고, Umano 포스트의 원문 기사의 내용을 텍스트로 추출하는 작업을 진행했다.

mp3 파일로부터 음성인식을 통해 텍스트를 추출하려고 조사를 하다보니 100% 정확하게 음성을 인식할 수도 없고, 라이브러리 차원에서 해결하기도 어려운 문제인지라 원문 기사 링크에서 기사 본문을 추출하는 방향으로 진행하기로 했다. 또한 음성인식을 통해 텍스트를 추출한다면 처리량이 쓸데 없이 많아지기도 했다.


HTML로부터 추출한 기사에는 본문 내용만이 포함되어야 하고(웹 페이지를 구성하는 기타 내용을 제외한) 텍스트로 출력될 수 있어야 했다. 즉 에버노트 크롬 확장인 Clearly와 같은 기능을 원했다.

extract contents from web page를 키워드로 찾아보니 딱 원하는 기능을 제공하는 Boilerpipe라는 자바로 작성된 라이브러리를 찾을 수 있었다.



| 기사 추출

먼저 Boilerpipe의 다운로드 페이지에서 라이브러리 파일을 받은 후 클래스패스에 추가한다. 아쉽게도 메이븐 중앙 저장소에는 없다. 2011년 7월을 끝으로 더 개발이 진행되진 않는 것 같지만 쓰고자 하는 기능상으로는 문제가 없는 듯하다.




사용 방법은 간단하다. 아래와 같이 사용한다.



| User-Agent 헤더로 인한 403 응답

Umano는 여러 뉴스 제공사의 기사를 라디오 뉴스처럼 제공하기 때문에 일부 뉴스에서는 요청 파라미터나 헤더 없이도 기사 내용을 잘 가져오지만, 일부는 403이나 OK이 외의 다른 응답과 함께 페이지 내용을 받을 수 없다.

Bolierpipe에서 HTTP 요청에 대한 커스터마이징을 제공하지 않기 때문에 OkHTTP 라이브러리를 통해 먼저 HTML 페이지의 내용을 문자열로 받은 후 ArticleExtractor의 getText(String) 메서드를 호출하여 다시 본문 내용을 추출하는 쪽으로 했다.

User-Agent는 구글 크롬에서 요청 시 사용하는 User-Agent 값을 그냥 복사하여 넣어주었다.


또한 SSL 인증서를 검증하는 과정에서 유효기간이 지난 SSL 인증서를 사용하거나 Self-signed 인증서 역시 예외를 발생시키므로 이 과정을 무시하도록 하기 위해 OkHttpClient에 SSL Context 설정한다.





※ 참고 자료

https://code.google.com/p/boilerpipe/wiki/JavaDoc

http://stackoverflow.com/questions/2529682/setting-user-agent-of-a-java-urlconnection

http://stackoverflow.com/questions/25509296/trusting-all-certificates-with-okhttp

http://www.snip2code.com/Snippet/25364/Get-OkHttpClient-which-ignores-all-SSL-e




var body = document.body,

    html = document.documentElement;


var height = Math.max( body.scrollHeight, body.offsetHeight, 

                       html.clientHeight, html.scrollHeight, html.offsetHeight );



출처 : http://stackoverflow.com/questions/1145850/how-to-get-height-of-entire-document-with-javascript

요즘은 바보가 되어버린 느낌이다.

예전에는 내가 모르는 것이 무엇이고, 알아야 할 것들이 무엇인지 안다고 생각했었는데, 돌이켜보면 방향 없이 마음 가는대로의 생각이었던 것 같다. 회의감이 많이 든다.

지쳐가는 상황일 때면 내 상태는 이렇게 되었던 것 같다.

몇 년째 고민 중인 '나는 무얼 잘하나?', '무얼 잘하게 만들어야 할까?'


Getter/Setter를 이클립스 코드 생성에서 지원해서 안쓸까하다가 가독성도 떨어지고 해서 lombok을 설정하려고 했는데 @Data 애너테이션을 적용해도 Getter/Setter가 생성되지 않는다. 몇 가지 사항을 체크해보았다.


VM 인자 설정이 잘못되었나?

-Dbootclasspath 추가 -> X


기존에 컴파일된 바이트코드가 남아있나?

메이븐 Update projects, Project Clean -> X


full path 설정이 없어서 그런가?

java -Dlombok.installer.fullpath -jar lombok.jar


config 파일을 설정해주어야 하나?

lombok.config 파일을 프로젝트 폴더에 추가 -> X


이클립스의 애너테이션 프로세싱 설정인가?

애너테이션 프로세싱을 활성화 해보았다 -> X


이클립스 버전인가?

아직 Eclipse Luna를 지원하지 않아서 그런건지 Kepler로 설치해 보았다. -> X


자바 버전인가?

JDK 8을 설치해서 쓰고 있는데, CSB.IO는 JDK 7로 되어있어 컴파일 설정에서 Java 1.7로 설정해보았다 -> 자바 버전 때문인 것 같다.

Java APT가 Java 8로 올라오면서 없어지고, JSR-269 PAPA(Pluggable Annotation Processing API)가 추가되면서 lombok에서 아직 해당 부분에 대한 대응이 되지 않은 듯 하다. (확인해볼 필요가 있음)


Lombok 이클립스 설정 exe 파일을 선택해서 그런가?

lombok.jar를 실행하고 설치된 이클립스를 선택하는데 계속 sts.ini 파일을 선택했는데 sts.exe로 선택해서 설정해보았다. (사실 바뀌는 건 sts.ini 파일 뿐이니 관련이 없을 듯하다.)


참고 링크

- http://stackoverflow.com/questions/3418865/cannot-make-project-lombok-work-on-eclipse-helios

- https://projectlombok.org/features/configuration.html

- https://groups.google.com/forum/#!searchin/project-lombok/sts$20@data/project-lombok/DXY9IKW08A0/PdNQV9y2_5AJ

+ Recent posts