본론부터 가자

양방향 암호화 (복호화 가능) 과 단방향 Hash 데이터가 있다.

 

우선 Hash 에 대해 간단히 설명하자

 

- Hash Algorithm을 이용하여 원문 데이터 길이와 무관하게 항상 고정된 길이로 Hash 데이터를 생성한다.

 

- Hash Algorithm 은 모두 공개되어 있기 때문에 사용해서는 안되는 Algorithm 이 있다.

  ( 권장되지 않는 Hash Algorithm : MD5, SHA-1, HAS-180 )

 

- 위에서 언급한 대로 원문(입력값) 은 무한대 이지만 Hash 된 값은 항상 고정된 길이 값으로

   나타내기 때문에 중복되는 Hash 값이 나올 수가 있다. (확률은 낮고, 중복 최소화를 위해 Algorithm 이 생겨난듯...)

 

- Hash 데이터는 복호화가 되지 않는다. 즉 데이터의 무결성을 검증 할 수 있는 Signatrue 데이터 이다. 

 

여기서는 Hash 데이터 생성 방법 중 SHA-256HMAC 에 대한 간단한 샘플을 기재한다. 

 

[ SHA-256 ]

 

: SHA ( Secure Hash Algorithm )

import java.security.MessageDigest;

import java.securit.NoSuchAlgorithmException;

import java.util.Base56;


public class SHA256Test
{
    public static void main( String[] args )
    {
        String plainData = "ABCDEFG^1234^!@#$";
        
        SHA256Test shaTest = new SHA256Test();
        String hashData = shaTest.sha256Hash( plainData );

        System.out.println( "SHA_256 : " + hashData );
        System.out.println( "SHA_256.len : " + hashData.getBytes().length );
    }

    public String sha256Hash( String plainData )
    {
        try {
            MessageDigest md = MessageDigest.getInstance( "SHA-256" );
            md.update( plainData.getBytes() );
            return bytesToHex( md.digest() );
        } catch( NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    // byte 데이터를 16진수 String 데이터로 변환    
    public String bytesToHex( byte[] btArrData )
    {
        StringBuffer strBuf = new StringBuffer();
        
        for( byte bt : btArrData )
        {
            strBuf.append( String.format( "%02x", bt ) );
        }

        return strBuf.toString();
    }
    
}

 

[ SHA256 결과 ]

SHA_256 : 218d186.................................~~.......................................2835ceeb
SHA_256.len : 64

위와 같은 결과가 나온다. 

위에서 plainData 값을 늘리거나 줄이거나 하여도 길이는 항상 64가 나온다. 

이유는 간단하다.

sha-256 알고리즘은 데이터를 hash 할 때 항상 256 bit 로 변환이 된다. 

 

16진수는 1자리가 4 bit 이며, sha-256 문자열 길이가 64 byte 이면

64 * 4 = 256 bit 가 되기 때문이다.

 

 

[ HMAC ]

 

HMAC : Hash based Message Authentication Code - 인증된 메세지 코드 라는 뜻이다

- 위 처럼 HMAC 는 hash 기반의 인증이 포함된 메세지이다.

  HMAC 은 위 SHA-256 과 달리 Key가 필요하며, Hash based 의 무결성과 Key 을 이용한 인증 

  2가지를 다 제공하고 있다. 

 

아래 예제는 HMAC_SHA256 데이터를 만드는 샘플이다. 

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class HMAC_SHA256Test
{
    public static final String HMAC_ALG = "HmacSHA256";


    public static void main( String[] args )
    {
        String plainData = "ABCDEFG^1234^!@#$";
        String hmacKey  = "TEST1234567890";
        
        HMAC_SHA256Test hmacTest = new HMAC_SHA256Test();

        String hmacData= hmacTest.getHMacData( plainData, hmacKey );

        System.out.println( "HMAC_SHA_256 : " + hashData );
        System.out.println( "HMAC_SHA_256.len : " + hashData.getBytes().length );
    }


    public String getHMacData( String plainData, String hmacKey )
    {
        try {

            // HMAC Hash 알고리즘 & Key 설정
            Mac mac = Mac.getInstance( HMAC_ALG );
            mac.init( new SecretKeySpec( hmacKey.getBytes(), HMAC_ALG ) );

            // HMAC 데이터 생성.
            byte[] btArrHmacData = mac.doFinal( plainData.getBytes() );

            String hmacData = bytesToHex( btArrHmacData );


        } catch( NoSuchAlgorithmException e ) {
            e.printStackTrace();
            return null;
        } catch( InvalidKeyException e ) {
            e.printStackTrace();
            return null;
        }

    }


    // byte 데이터를 16진수 String 데이터로 변환    
    public String bytesToHex( byte[] btArrData )
    {
        StringBuffer strBuf = new StringBuffer();
        
        for( byte bt : btArrData )
        {
            strBuf.append( String.format( "%02x", bt ) );
        }

        return strBuf.toString();
    }


}

 

위 main 함수 실행 시 다음과 같은 결과가 나온다. 

HMAC_SHA_256 : 1424fe73f7e ~~~  426b87b
HMAC_SHA_256.len : 64

 

결론 : Hash 를 암호화라고 생각할 수 있으나 위에서 언급했던것 과 같이 Hash 는 복호화가 불가능하며, 

        Hash 데이터 검증을 위해서는 원문데이터가 필요하거나 또는 원문 + Key 값이 필요하다. 

 

이렇게 간단히 Hash 데이터를 만드는 방법을 알아보았다. 

이 방식 외 공개키 개인키로 Signatrue 데이터를 만들어 verify 하는 방법도 있으나, 해당 내용은

다음에 알아보도록 하겠다. 

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

Oracle OpenJDK 11 버그로 인한 AdoptJDK 다운  (0) 2021.01.16
java 날짜 계산 (java.time)  (0) 2020.11.03
PKCS 표준 정보  (0) 2020.10.26
Open JDK 다운로드  (0) 2020.04.22
Java Caller & Callee 확인하기  (0) 2020.04.17

OpenJDK 를 이용해서 서비스를 개발해야 했다. 

예전에 JDK 1.8 에서 Licence 문제로 인하여 OpenJDK 로 바꿔야 하는 이슈였다. 

 

OpenJDK 는 아래 사이트에서 다운받았다. 

 

Java Platform, Standard Edition 11 Reference Implementations

Java Platform, Standard Edition 11 Reference Implementations The official Reference Implementation for Java SE 11 (JSR 384) is based solely upon open-source code available from the JDK 11 Project in the OpenJDK Community. This Reference Implementation a

jdk.java.net

참고로 밴더사는 Oracle 로 알고 있다. 

위 사이트에서 openjdk-11+28_windows-x64_bin 파일을 받아 실행하였고, 

서비스를 운영중 뜻하지 않는 문제를 발견하였다. 

 

바로 TCP 통신을 위하여 Connection 객체를 생성하였고, 통신 완료 후 SSLSocket 을 종료 시키려 해더

종료가 되지 않는것이다.

( Finally 에서 close() 를 선언하였는데도 Socket 이 여전히 살아 있다. )

 

때문에 FD 에  ( 리눅스 CentOS 환경에서 운영중.. ) 에 해당 Process 가 사라지지 않고 누적되었으며, 

결국 FD 가 Full 되서 서버가 다운되는 현상이었다. 

 

위 이슈는 해당 버그 Fix 페이지에 나와 있다. 

URL : bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8246031

 

재미있는건 Oracle Licence 가 적용된 JDK 11.0.8 버전에서는 해결을 했다고 하나, 내가 사용하는

OpenJDK 11 ( openjdk-11+28_windows-x64_bin ) 에서는 문제가 발생되고 있는것이다. 

 

Oracle 벤더에서 OpenJDK 명명법이 어떻게 되는지 모르겠다. ( 다시 말하지만 파일 명은 openjdk-11+28... 이다. )

아무튼 해당 이슈를 해결하기 위하여 OpenJDK 를 바꾸었다.

 

벤더사는 Adopt 이며 버전은 OpenJDK 11

Adopt 의 OpenJDK 11.0.9 (LTS) 를 사용 후 문제는 사라졌다. 

 

AdoptOpenJDK

AdoptOpenJDK provides prebuilt OpenJDK binaries from a fully open source set of build scripts and infrastructure. Supported platforms include Linux, macOS, Windows, ARM, Solaris, and AIX.

adoptopenjdk.net

P.S)  LTS (Long Term Support ) : 장기간 해당 버전에 대한 지원을 하는것이다. 

 

 

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

SHA-256 & HMAC  (0) 2021.04.19
java 날짜 계산 (java.time)  (0) 2020.11.03
PKCS 표준 정보  (0) 2020.10.26
Open JDK 다운로드  (0) 2020.04.22
Java Caller & Callee 확인하기  (0) 2020.04.17

java에서는 날짜를 추출/계산 할 수있는 여러가지 방법이 있지만, 익히 알고 있는 방법은

Calendar 클래스를 이용하는 것이다. 

 

Calendar 은 JDK 1.1 부터 제공되었고 유용하게 사용되었으나, 몇가지 문제점이 있다. 

- Calendar 인스턴스는 불변 객체가 아니어서 수정이 가능하다. 

- 윤초와 같은 특별한 상황은 고려되지 않았다. 

- Calendar 은 1월 ~ 12월 을 0 ~ 11 로 표현해야 한다. 

 

JDK 8 이후 버전부터는 새로운 날짜와 시간 API 인 java.time 패키지를 제공한다. 

아래는 java.time 이하 에서 제공되는 하위 패키지 들이다. 

아래 내용은 gbsb.tistory.com/302에서 발췌하였다. 

 

- chrono : ISO-8601 에 정의된 표준달력 외 달력시스템 사용 시 이용되는 클래스 패키지

- format  : 날짜와 시간에 대한 데이터를 분석하고 형식화 하는 클래스 집합 패키지.

- temporal : 날짜와 시간에 대한 연산에 사용되는 보조 클래스들 집합 패키지

- zone : Time-Zone 에 관련 클래스 집합 패키지

 

패키지 외 여러 클래스들이 존재하지만 자주 사용되는 몇가지에 대해 정의한다. 

- LocalDate : 날짜를 표현 시 사용. ( 타임존에 따른 시간 변환 불가 )

- LocalTime : 시간을 표현 시 사용 ( 타임존에 따른 시간 변환 불가 )

- LocalDateTime : 날짜와 시간을 한 번에 표현 시 사용. ( 타임존에 따른 시간 변환 불가 )

- ZonedDateTime : 특정 Time-zone 에 해당하는 날짜와 시간을 다룰 때 사용.

- Instant : 특정 시점의 날짜와 nanosecond 단위로 표현하는 time-stamp 다룰 때 사용.

- Period : 두 날짜 사이의 차이를 표현 시 사용

- Duration : 두 시각 차이를 표현 시 사용

- TemporalField : 월(month-of-year) 과 시(hour-of-day) 와 같이 날짜, 시간과 관련된 필드를 정의한 인터페이스.

                     이 인터페이스를 구현하여 날짜와 시간을 나타낼 때 사용하는 열거체가 ChronoField 이다

 

앞서 얘기한데로 Canendar 클래스는 1월 - 0 , 12월 - 11 로 표현하였으나, 

java.time 부터는 1월 - 1, 12월 - 12로 표현한다.  또한 요일은 월요일 - 1, 일요일 - 7 로 

표기한다. 

 

[ LocalDate 생성 & 사용 ]

위 클래스들은 public 생성자를 제공하지 않기 때문에 객체를 생성할 때 now(), of(), parse() 과 같은 

정적 메소드를 사용해야 한다. 

LocalDate currDate = LocalDate.now();

System.out.println( "Today : " + currDate ); 

>>> 2020-11-06

LocalDate targetDate = LocalDate.of(1981, 2, 9);
System.out.println( "targetDate : " + targetDate );
>>> 1981-02-09

LocalDate parseDate = LocalDate.parse("1981-02-09");
System.out.println( "parseDate : " + parseDate );>>> 1981-02-09

now()  : 현재 날짜 또는 시간을 이용하여 새로운 객체를 생성 및 리턴

of()     : 지정한 날짜와 시간을 표현하는 객체를 생성 및 리턴

parse() : 지정한 날짜와 시간을 표현하는 객체를 생성 및 리턴

 

[ LocalTime 생성 & 사용 ]

- LocalDate 와 매우 유사하며, 기본 포멧은 HH:mm:ss.SSS  이다.

LocalTime currTime = LocalTime.now();

System.out.println( "currTime : " + currTime );

>>> 02:30:27.123

LocalTime seoulTime = LocalTime.now( ZoneId.of("Asiz/Seoul") ) );

System.out.println( "seoulTime : " + seoulTime );

>>> 02:30:27.124

LocalTime targetTime = LocalTime.parse( 02, 30, 10 );

System.out.println( "targetTime : " + targetTime );

>>> 02:30:10

LocalTime targetPlusTime = targetTime.plusHour(8);

System.out.println("targetPlusTime : " + targetPlusTime );

>>> 10:30:10

LocalTime targetMinusTime = targetTime.minusHour(1);

System.out.println( "targetMinumTime : " + targetMinumTime );
>>> 01:30:10

위 샘플들은 LocalDate, LocalTime 으로 분리하였으나 실제 사용되는 함두는 두 클래스(LocalDate, LocalTime)

다 유사하다.

즉, LocalDate 클래스에도 plusDays(..), plus(..), plusHours(..) 등 plusXxxx(...) 와 minusXxxx(...) 함수들이 제공된다. 

 

[ LocalDateTime 객체 생성 & 사용 ]

- LocalDateTime 클래스는 LocalDate 와 LocalTime 2개의 기능을 모두 제공하는 클래스라고 생각하면 된다. 

  또한 제공되는 함수도 유사하다. ( 기본 포멧은 yyyy-MM-ddTHH:mm:ss.SSS 이다. )

LocalDateTime currLDT = LocalDateTime.now();

System.out.println( "currLDT : " + currLDT );

>>> 2020-11-05T02:30:10.235

LocalDateTime targetLDT = LocalDateTime.parse("2020-11-05T02:30:10.123");

System.out.println( "targetLDT : " + targetLDT );

>>> 2020-11-05T02:30:10.123

LocalDateTime targetLDT2 = LocalDateTime.of(1891, 2, 9, 6, 10, 11);

System.out.println( "targetLDT2 : " + targetLDT2 );

>>> 1981-02-09T06:10:11

 

with() : 생성된 객체( Local.... ) 의 특정 필드값을 변경하기 위해서 사용.

 

- with(TemporalField field, long newValue) : LocalDate 객체에서 특정 필드(TemporalField) 를 새로운 값(long)

     으로 설정한 객체를 반환한다. 

- withYear(int year) : LocalData 객체에서 연도 필드를 새로운 값(int) 로 설정 및  반환

- withMonth(int month) : LocalDate 객체에서 월(MONTH_OF_YEAR) 필드를 새로운 값(int) 으로 설정 및 반환 

- withDayOfMonth(int dayOfMonth) : LocalData 객체에서 일(DAY_OF_MONTH) 필드를 새로운 값(int) 으로 설정 및 반환.

- withDayOfYear(int dayOfYear) : LocalDate 객체에서 DAY_OF_YEAR 필드를 새로운 값(int) 으로 설정 및 반환

 

LocalTime 에서는 with(...) withHour(...), withMinute(...), withSecond(...), withNano(...) 등이 존재한다. 

 

with..(...) 함수 외에 plus(), minus() 함수도 제공하고 있다. 

 

[ 날짜 & 시간 객체의 비교 ]

- isEqual() : 오직 날짜가 같은지 비교하며, LocalDate 클래스에서만 제공. ( boolean )

- isBefore() : 객체를 비교하여 이전인지 여부 확인 ( boolean )

- isAfter() : 객체를 비교하여 이후 인지 여부 확인 ( boolean )

 

 

[ java.time.Instant ]

 

Instant.now() 를 호출 시 현재 시간 Instant 를 획득할 수 있다. (UTC 기준 ISO 포멧이다.)

또한 초단위 또는 밀리초 단위의 Timestamp 값을 long 타입으로 얻을 수 있다. 

Instant currInstant = Instant.now();

System.out.println( "UTC+0 기준 현재 시간 : " + currInstant );
--> 2020-11-09T23:20:46.80619700Z    

( 현재 한국 시간은 2020-11-10 08:21 이다. )

System.out.println( "UTC+0 기준 현재 시간 Timestamp (초) : " + currInstant.getEpochSecond() );
--> 1604964046

System.out.println( "UTC+0 기준 현재 시간 Timestamp (밀리초) : " + currInstant.toEpochMilli() );
--> 1604964046806

 

 

Instant 클래스와 ZoneDateTime 클래스는 특정 메서드를 통해 객체가 서로 변환이 가능하다.

바로 atZone(..) 메소드와 toInstant() 메소드 이다. 

Instant currInstant = Instant.now();
ZoneDateTime zdt = currInstant.atZone( ZoneId.of("Asia/Seoul") );

System.out.println( "한국 현재 시간 : " + zdt );
--> 2020-11-10T08:21:45.403111800+09:00[Asiz/Seoul]

Instant korInstant = zdt.toInstant();
System.out.println( "한국 현재 시간 Instant: " + korInstant );
--> 2020-11-09T23:20:46.80619700Z

 

[ java.time.ZoneDateTime ]

ZoneDateTime 클래스는 타임존 또는 시차가 적용되는 필요한 날짜와 시간정보를 나타낼 때 사용하면 용이하다. 

public 생성자는 제공하지 않으며, 정적 메소드를 통하여 객체를 생성한다. 

또한 format() 메소드에 DateTimeFormatter 객체를 사용하여 원하는 문자열로 포멧 변환이 가능하다.

DateTimeFormatter 은 ofPattern(...) 을 이용하여 원하는 포멧을 정의하거나 DateTimeFormatter 에서 제공하는

정적 필드( Ex: DateTimeFormatter.ISO_DATE_TIME.. ) 를 이용할 수 있다. 

날짜 시간에 대한 언어 표현은 withLocale( Locale.~ ) 함수를 사용하여 다양하게 구현할 수 있다. 

System.out.println( "한국 현재 시간 ZoneDateTime: " + ZoneDateTime.now() );
--> 2020-11-10T08:38:51.751179300+09:00[Asia/Seoul]

String zdtFormat = ZoneDateTime.now().format( DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss") );
System.out.println( "ZoneDateTime.format: " + zdtFormat  );
--> 2020.11.10 08:43:49

DateTimeForamtter dtf_1 = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss a z");
System.out.println("DTF_1 : " + ZoneDateTime.now().format( dtf_1 ) );
--> 2020.11.10 08:43:49 오전 KST

DateTimeForamtter dtf_2 = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss a z").withLocale(Locale.ENGLISH);
System.out.println("DTF_2 : " + ZoneDateTime.now().format( dtf_2 ) );
--> 2020.11.10 08:43:49 AM KST

 

[ ZoneId & ZoneOffset ]

ZoneId 는 타임존으로 지정한 지역의 시간코드, ZoneOffset 은 UTC 기준 시간차 (양수/음수) 를 나타낸다.

예로 한국 서울의 ZoneId : Asia/Seoul & ZoneOffSet : +0900 이다. 

System.out.println( "ZoneOffset.of('+09:00') : " + ZoneDateTime.now(ZoneOffset.of("+09:00")) );
--> 2020-11-10T08:38:51.751179300+09:00

System.out.println( "ZoneDateTime.format: " + ZoneDateTime.now( ZoneId.of("Asia/Seoul")  );
--> 2020-11-10T08:38:51.751179300+09:00[Asiz/Seoul]

 

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

SHA-256 & HMAC  (0) 2021.04.19
Oracle OpenJDK 11 버그로 인한 AdoptJDK 다운  (0) 2021.01.16
PKCS 표준 정보  (0) 2020.10.26
Open JDK 다운로드  (0) 2020.04.22
Java Caller & Callee 확인하기  (0) 2020.04.17

출처 : ko.wikipedia.org/wiki/%EA%B3%B5%EA%B0%9C_%ED%82%A4_%EC%95%94%ED%98%B8_%ED%91%9C%EC%A4%80

약어 버전 이름 설명
PKCS #1 2.1 RSA 암호 표준(RSA Cryptography Standard) RFC 3447에 기술되어 있다. RSA의 공개 키와 비밀 키(ASN.1 으로 인코딩됨)에 대한 수학적 성질과 규격에 대해 정의하고 있으며, 또한 RSA 암호화와 복호화, 서명 검증을 구현하는 데에 필요한 알고리즘과 인코딩/패딩 등의 규격을 정의한다.
PKCS #2 - (철회됨) 현재는 사용하지 않는다. 메시지 다이제스트를 RSA 암호화하는 부분을 다루고 있었으며, 해당 내용은 PKCS #1으로 합쳐졌다.
PKCS #3 1.4 디피-헬만 키 교환 표준(Diffie-Hellman Key-Agreement Standard) 디피-헬만 키 교환 방법을 이용한 통신에 대해 정의한다.
PKCS #4 - (철회됨) 현재는 사용하지 않는다. RSA 키를 표현하는 규격을 다루고 있었으며, PKCS #1으로 합쳐졌다.
PKCS #5 2.0 비밀번호 기반 암호화 표준(Password-based Encryption Standard) 비밀번호에 기반한 암호 시스템을 구현할 때 고려해야 할 점을 설명한다. RFC 2898에 기술되어 있다.
PKCS #6 1.5 인증서 확장 문법 표준(Extended-Certificate Syntax Standard) X.509 인증서 규격의 v1을 확장했다. 현재는 X.509 v3가 있어 사용되지 않는다.
PKCS #7 1.5 암호 메시지 문법 표준(Cryptographic Message Syntax Standard) RFC 2315에 기술되었다. 암호화한 데이터를 표현하는 방식에 대한 표준이다.
PKCS #8 1.2 개인키 정보 문법 표준(Private-Key Information Syntax Standard) RFC 5208에 기술되었다. 공개키 암호에서 사용되는 비밀키 값에 대한 문법을 정의한다.
PKCS #9 2.0 Selected Attribute Types 다른 PKCS에서 사용하는 속성값들에 대하여 정의한다.
PKCS #10 1.7 인증서 요청 표준(Certification Request Standard) RFC 2986에 기술되었다. 인증 기관에 인증서를 요청할 때 사용하는 프로토콜을 정의한다.
PKCS #11 2.20 암호 토큰 인터페이스(Cryptographic Token Interface)[1] Cryptoki라고도 부른다. 암호 토큰(Hardware Security Module 참고)에 대한 범용 인터페이스를 정의하는 API이다. 주로 Single Sign-On, 공개 키 암호 방식, 디스크 암호화[2] 시스템에 사용한다.
PKCS #12 1.0 공개 키 인증서 교환 문법 표준(Personal Information exchange syntax standard) 비밀번호로 보호된, 대칭키와 공개 키 인증서에 동봉된 개인 키들을 저장하는 데 일반적으로 사용되는 파일 형식을 정의한다. .pfx는 pkcs #12 파일형식 확장자이다.

이 파일 형식은 여러 개의 개체(예: 다중 인증서, 다중 키)를 포함할 수 있으며 보통, 비밀번호로 보호되거나 암호화된,. java 키 저장소의 형식으로 사용된다.

PKCS #13 타원 곡선 암호 표준(Elliptic Curve Cryptography Standard) (버려진 것으로 보인다)
PKCS #14 유사난수 생성기(Pseudo-random Number Generation) (버려진 것으로 보인다. 관련 문서가 존재하지 않음)
PKCS #15 1.1 암호 토큰 정보 형식 표준(Cryptographic Token Information Format Standard) 응용프로그램의 암호토큰인터페이스(#11)이나 다른 API와 무관하게, 암호 토큰의 사용자가 응용프로그램에서 자신을 식별할 수 있는 표준을 정의한다.

RSA는 이 표준의 IC카드 관련된 부분을 ISO/IEC 7816-15에 넣기를 포기했다.

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

SHA-256 & HMAC  (0) 2021.04.19
Oracle OpenJDK 11 버그로 인한 AdoptJDK 다운  (0) 2021.01.16
java 날짜 계산 (java.time)  (0) 2020.11.03
Open JDK 다운로드  (0) 2020.04.22
Java Caller & Callee 확인하기  (0) 2020.04.17

OpenJDK 홈페이지 : https://openjdk.java.net 

해당 URL 에서는 OpenJDK 의 정보만 확인하고 OpenJDK 를 다운로드 할 수는 없다. 

 

OpenJDK

Download and install the open-source JDK for most popular Linux distributions. Oracle's free, GPL-licensed, production-ready OpenJDK JDK 14 binaries are at jdk.java.net/14; Oracle's commercially-licensed JDK 14 binaries for Linux, macOS, and Windows, based

openjdk.java.net

OpenJDK 다운로드 링크 : https://jdk.java.net 

아래 페이지에서 OpenJDK를 버전별로 다운 받을 수 있다. 

 

JDK Builds from Oracle

 

jdk.java.net

아래는 Oracle JDK 와 Open JDK 의 차이점에 대해 자세히 설명해 놓았다. 

https://recipes4dev.tistory.com/173

 

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

SHA-256 & HMAC  (0) 2021.04.19
Oracle OpenJDK 11 버그로 인한 AdoptJDK 다운  (0) 2021.01.16
java 날짜 계산 (java.time)  (0) 2020.11.03
PKCS 표준 정보  (0) 2020.10.26
Java Caller & Callee 확인하기  (0) 2020.04.17

Java 로 프로그램시 특정 메소드를 누가 호출하는지 헷갈릴때가 있다. 

개인적으로 기억력의 문제라고 생각하지만 공통 Class 생성 후 공통 메소드 (이하 comTest() )를 호출

할 때, 어떤 클래스 또는 어떤 메소드가 호출되는지 확인하고 싶어질 때가 있다. 

 

즉, caller & callee 를 로그상으로 남기고 싶은것이다. 

그럴경우 StackTraceElement 를 활용하면 쉽게 알 수 있다. 

StackTraceElement[] traceElement = Thread.currentThread().getStackTrace();

for( StackTraceElement tmpElement : traceElement )

{

    System.out.println( "className = " + tmpElement.getClassName() );

    System.out.println( "methodName = " + tmpElement.getMethodName() );

}

위 코딩은 com 패키지를 생성 Test 라는 클래스를 만들어 main 함수에서 수행하였다. 

수행 시 일반적으로 traceElement.length = 3 이며, 각 배열별 데이터는 다음과 같다.

 

Index : 0 -> className = java.lang.Thread , MethodName = getStackTrace

Index : 1 -> className = com.Test          , MethodName = comTest

Index : 2 -> className = com.Test          , MethodName = main

 

0번지는 StackTrace 에 관한 정보

1번지는 Callee ( StackTraceElement.. 을 코딩한 부분 ),

2번지는 Caller ( main - 호출한 주체)에 대한 정보를 보여준다. 

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

SHA-256 & HMAC  (0) 2021.04.19
Oracle OpenJDK 11 버그로 인한 AdoptJDK 다운  (0) 2021.01.16
java 날짜 계산 (java.time)  (0) 2020.11.03
PKCS 표준 정보  (0) 2020.10.26
Open JDK 다운로드  (0) 2020.04.22

+ Recent posts