SSHProtocolException 에러 해결

서버에서 다른 서버로 API 호출하던 중에 아래와 같은 에러가 발생했다.

Caused by: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name 

수신 서버가 송신 서버의 name을 알지 못한다는 내용이다.

해당 에러를 해결하기 위해서는 두가지 방법이 있다.
- System 환경변수를 설정한다. System.setProperty("jsse.enableSNIExtension", false);
- JVM 옵션을  설정한다. -Djsse.enableSNIExtension=false

한가지 방법을 선택해 설정하면 정상적으로 API 호출되는 것을 확인 할 수 있다.

'Development > Java' 카테고리의 다른 글

UnsupportedClassVersionError 에러 해결  (0) 2018.07.16
Garbage Collection 방식  (0) 2018.05.12
Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06

UnsupportedClassVersionError 에러 해결


Unsupported major.minor version 52.0

위 에러가 발생하여 찾아보니 원인은 빌드한 자바 버전보다 낮은 버전의 자바 컴파일러에서 실행시 발생한다고 한다.

    • Java SE 10 = 54
    • Java SE 9 = 53
    • Java SE 8 = 52
    • Java SE 7 = 51
    • Java SE 6.0 = 50
    • Java SE 5.0 = 49
    • JDK 1.4 = 48
    • JDK 1.3 = 47
    • JDK 1.2 = 46
    • JDK 1.1 = 45

실제로 빌드한 자바 버전은 1.8 이었고, 배포할 서버의 자바 버전은 1.7.x 였다.

$ java -version 

두 가지의 해결 방안이 있어 전자로 선택했다.

1) 배포할 서버의 자바 버전을 1.8.x로 업데이트 한다.
2) 1.7 버전으로 빌드한다.

$ yum install -y java-1.8.0-openjdk

결론빌드/배포 할 자바 버전을 동일하게 설정해야 한다.

'Development > Java' 카테고리의 다른 글

SSHProtocolException 에러 해결  (0) 2019.01.12
Garbage Collection 방식  (0) 2018.05.12
Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06

Garbage Collection 방식

Java 버전별 GC 방식 default value

    • Java 7 - Parallel GC
    • Java 8 - Parallel GC
    • Java 9 - G1 GC

GC 방식
  • Serial GC
  • Parallel GC
  • Parallel Compacting GC
  • Concurrent Mark Sweep GC
  • G1(Garbage First) GC

상세 내용은 하단 링크에 잘 설명되어 있으므로 생략!

GC 방식 상세 링크1 
GC 방식 상세 링크2

'Development > Java' 카테고리의 다른 글

SSHProtocolException 에러 해결  (0) 2019.01.12
UnsupportedClassVersionError 에러 해결  (0) 2018.07.16
Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06
가비지 컬렉션 과정

Java에서는 개발자가 메모리를 명시적으로 해제하지 않는다. 대신에 Garbage Collector가 더 이상 필요 없는 객체를 찾아 지우는 작업을 한다. 이 가비지 컬렉터는 두 가지 가설 전제 하에 만들어졌다.

Weak Generational Hypothesis
        1. 대부분의 객체는 금방 접근 불가능 상태가 된다. 할당되고 짧은 시간 내에 사용이 종료되어 불필요한 상태인 것이 거의 대부분이다.
        2. 오래된 객체에서 젊은 객체로의 참조는 거의 발생하지 않는다.

이 가설의 장점을 최대한 살리기 위해서 메모리를 몇가지 영역으로 분리하여 관리하는 것이 효과적이다.

JVM Memory 영역
- Young 영역 : 새롭게 생성한 객체의 대부분이 여기에 위치한다. 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 매우 많은 객체가 Young 영역에 생성되었다가 사라진다.
Old 영역 : 접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사된다. 대부분 Young 영역보다 크게 할당하며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다. 
- Perm 영역 : Method 영역이라고도 부른다. Class, Method 등 메타 데이터가 저장된다. 

GC 종류
        - Minor GC : Young 영역에서 발생하는 GC
        - Major(Full) GC : Old 영역에서 발생하는 GC

GC 발생 과정
1. 새로 생성한 대부분의 객체는 Eden 영역에 위치한다.
2. Eden 영역이 가득 차 Minor GC가 발생하면 살아남은 객체가 Survivor 영역 중 하나로 이동해서 Age가 증가한다.
3. 다시 Eden 영역이 가득 차 Minor GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역으로 이동해서 Age가 증가한다.
4. 그 Survivor 영역이 가득 차면 그 중에서 살아남은 객체가 다른 Survivor 영역으로 이동해서 Age가 증가한다.
5. 이 과정을 반복하다가 계속해서 살아남은 객체의 Age가 threshold 설정 값(default 16)이 되면 Old 영역으로 이동한다.
6. 이 과정을 반복하다가 Old 영역이 가득 차면 Major GC가 발생한다.

이 절차를 확인해 보면 두개의 Survivor 영역 중 하나는 반드시 비어 있는 상태로 남아 있어야 한다. 만약 두 Survivor 영역에 모두 데이터가 존재하거나, 두 Survivor 영역 모두 사용량이 0이라면 시스템이 정상적인 상황이 아니라고 생각하면 된다.


참조 링크 - Java Garbage Collection

'Development > Java' 카테고리의 다른 글

UnsupportedClassVersionError 에러 해결  (0) 2018.07.16
Garbage Collection 방식  (0) 2018.05.12
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06
반복문 성능 비교  (0) 2017.07.27
가비지 컬렉션 용어 정리

GC (Garbage Collection)
- Java Application에서 사용하지 않는 메모리를 자동 수거하는 기능

STW (Stop-The-World)
- GC가 메모리 정리를 위해서 어플리케이션의 실행을 중지시키는 행위
- GC 튜닝을 한다면 이 시간을 줄여야 함

OOM (Out Of Memory)
- Heap 메모리 부족 시 발생되는 에러 상황 및 메시지

Mark
- Object가 현재 사용되고 있는지에 대한 검사
- Referrer가 존재하는지 확인하는 것으로 Minor GC단계에서 주로 수행됨

Sweep
- Mark 대상에 대해서 회수 작업 (메모리상에 미사용으로 처리)
- Minor GC단계에서 주로 수행됨

Compact
- 디스크 조각모음 하듯이 메모리 공간 확보 Major GC시에 수행됨 


'Development > Java' 카테고리의 다른 글

Garbage Collection 방식  (0) 2018.05.12
Garbage Collection 과정  (0) 2018.04.28
AES256 암호화 오류 해결  (4) 2017.10.06
반복문 성능 비교  (0) 2017.07.27
List 중복 제거  (0) 2017.07.13

AES256 암호화시 java.security.InvalidKeyException: Illegal key size 해결 방안

JAVA의 기본 정책으로 AES128 암호화 방식까지만 사용 가능하다. (미 통상법에 의해 자국내에서만 AES256 방식 허용)
그래서 AES256 방식으로 암호화하게 되면 아래와 같은 Exceptioin이 발생한다.
java.security.InvalidKeyException: Illegal key size

이를 해결하기 위해 $JAVA_HOME/jre/lib/security 경로에 아래의 unlimited strength crypto file을 덮어써야한다.
local_policy.jar, US_export_policy.jar

* 해당 파일 다운로드 경로
  - Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 (JDK7)
  - Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 (JDK8)

OpenJDK로 설치한 서버에서는 문제가 없어 확인해보니 정책이 아래와 같았다.
OracleJDK, OpenJDK v8 이전 - AES128 까지 허용 (모듈 교체 필요 O)
OpenJDK v8 이후 - AES256 까지 허용 (모듈 교체 필요 X)


JDK 1.8u151 버전? 부터 방법 변경

1) $JAVA_HOME/jre/lib/security 경로로 이동
2) java.security 파일 오픈.
3) crypto.policy 프로퍼티 수정. (limited -> unlimited)

$JAVA_HOME/jre/lib/security/policy 경로에 limited, unlimited 디렉토리로 구분되어져 있다.
crypto.policy 프로퍼티에 설정한 디렉토리명에 따라 전환되는듯 하다.


'Development > Java' 카테고리의 다른 글

Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
반복문 성능 비교  (0) 2017.07.27
List 중복 제거  (0) 2017.07.13
Reflection 클래스 정보  (0) 2017.07.12
반복문 성능 비교

반복문에는 크게 for, while 문이 있다. while 문은 잘못하면 무한 루프에 빠지기 쉬우므로 for문을 권장한다.
또한  반복문 안에서 꼭 필요하지 않은 소스는 반복문 밖으로 추출시키도록 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Sample {
 
  public static void main(String args[]) {
 
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
      list.add(i);
    }
 
 
    for (int i = 0; i < list.size(); i++) { // #1
      System.out.println(list.get(i).toString());
    }
 
    int size = list.size();
    for (int i = 0; i < size; i++) { // #2
      System.out.println(list.get(i).toString());
    }
 
    for (Integer integer : list) { // #3
      System.out.println(integer.toString());
    }
 
  }
}
cs

위와 같은 반복문의 경우, 어떤 것이 가장 빠를까?
빠른 순서로 나열하면 다음과 같다. #2 > #1 > #3 

#1처럼 조건식에 list.size()를 사용하면 size() 메소드가 반복 호출된다. #2처럼 변수로 선언하여 사용하는 것이 좋다.
#3은 JDK 1.5부터 지원하는 향상된 for문이다. 배열이나 컬렉션에 저장된 요소들을 별도의 형변환이나 get 메소드가 필요없어 편리하게 처리할 수 있다.
단, 처음부터 끝까지 모든 요소를 반복할 때에 권장한다. 순서를 반대로하거나 특정 요소부터 탐색할 때에 부적절하다. 

물론 성능 차이가 얼마나지 않는다. 하지만 규모가 크거나 반복 횟수가 큰 경우 성능에 지장을 줄 수 있다.

'Development > Java' 카테고리의 다른 글

Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06
List 중복 제거  (0) 2017.07.13
Reflection 클래스 정보  (0) 2017.07.12
List 중복 제거

자바에서 List에 있는 값들 중에 중복된 값만 제외시키고 싶은 경우가 있다.
루프를 돌면서 유니크한 값인지 비교하는 로직을 사용하고 싶지 않았다.
중복을 허용하지 않는 HashSet으로 변환시키고 다시 List로 변환시키면 유니크한 값으로 이루어진 List를 만들 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Sample {
 
    public static void main(String args[]) {
 
        List<String> items = new ArrayList<>();
        items.add("a");
        items.add("b");
        items.add("c");
        items.add("b");
        items.add("c");
        System.out.println(items); // ["a", "b", "c", "b", "c"]
 
  items = new ArrayList<>(new HashSet<>(items)); 
        System.out.println(items); // ["a", "b", "c"]
    }
}

cs

대소문자까지 중복된 값을 제외시킬 수 있는 좋은 방법 있으시면 피드백 부탁드립니다~

'Development > Java' 카테고리의 다른 글

Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06
반복문 성능 비교  (0) 2017.07.27
Reflection 클래스 정보  (0) 2017.07.12
Reflection 클래스 정보


Java에서 제공하는 Relfection API를 통해 동적으로 클래스에 관련된 정보를 가져올 수 있다.

* Class 클래스 주요 메소드
String getName() : 패키지 포함 해당 클래스명 리턴
String getSimpleName() : 해당 클래스명 리턴
Field[] getFields() : public으로 선언된 변수 목록 리턴
Field[] getDeclaredFields() : 해당 클래스에 선언된 모든 변수 리턴
Method[] getMethods() : public으로 선언된 메소드 목록 리턴(해당 클래스에서 사용 가능한 상속 받은 메소드 포함)
Method[] getDeclaredMethods() : 해당 클래스에 선언된 모든 메소드 리턴
Constructor[] getDeclaredConstructors() : 해당 클래스에 선언된 모든 생성자 리턴
int getModifiers() : 해당 클래스의 접근자 정보 리턴
String toString() : 해당 클래스 객체를 문자열로 리턴

* Method 클래스 주요 메소드
String getName() : 해당 메소드명 리턴
int getModifiers() : 해당 메소드의 접근자 정보 리턴
String toString() : 해당 메소드 정보 리턴
Object invoke(Object obj, Object... args) : 해당 메소드 수행
Class<?> getDeclaringClass() : 해당 메소드가 선언된 클래스 정보 리턴
Class<?> getReturnType() : 해당 메소드 리턴 타입 리턴
Class<?>[] getExceptionTypes() : 해당 메소드 예외 타입들 리턴
Class<?>[] getParameterTypes() : 해당 메소드 매개변수 타입들 리턴

* Field 클래스 주요 메소드
String getName() : 해당 변수명 리턴
int getModifiers() : 해당 변수의 접근자 정보 리턴
String toString() : 해당 변수 정보 리턴

Modifier.toString(int modifier) : int 타입으로 리턴받은 modifier 값을 문자열로 리턴

* 참고사항
- 로그 선언시 클래스 이름을 알아내기 위해 this.getClass().getName() 사용한다고 성능이 크게 저하되지는 않는다. 
  하지만 클래스 객체를 얻는 방법 보다는 클래스명을 직접 명시하는 것을 권장한다.
- 클래스의 이름으로 해당 객체의 타입인지 비교하는 방법 보다 instanceof 키워드를 사용하는 것이 성능이 우수하다.
클래스의 메타 데이터 정보는 JVM의 Perm 영역에 저장된다. 
   Class 클래스를 사용하여 많은 양의 클래스를 동적으로 생성하면 Perm 영역을 더 이상 사용할 수 없게 되어 OutOfMemoryError가 발생한다.

참고서적 - 자바 성능 튜닝 이야기


'Development > Java' 카테고리의 다른 글

Garbage Collection 과정  (0) 2018.04.28
Garbage Collection 용어 정리  (0) 2018.04.26
AES256 암호화 오류 해결  (4) 2017.10.06
반복문 성능 비교  (0) 2017.07.27
List 중복 제거  (0) 2017.07.13

+ Recent posts