Programming Language 57

scala에러 Unable to make private java.nio.DirectByteBuffer 해결 방법

Unable to make private java.nio.DirectByteBuffer(long,int) accessible: module java.base does not "opens java.nio" 와 같은 코드가 떠서 놀랬다. intellij에서 sbt로 빌드한 스칼라코드가 실행되지 않을 때가 있는데, 이 오류는 jvm컴파일 버전 때문에 생기는 이슈이다.  https://stackoverflow.com/questions/70153343/unable-to-make-private-java-nio-directbytebufferlong-int-accessible Unable to make private java.nio.DirectByteBuffer(long,int) accessibleI'm using P..

Redis-go를 interface화 하여 사용하기

golang에서 Redis를 사용할 때는 보통 go-redis 라이브러리를 많이 사용합니다. 이 때, 바로 메서드를 사용하기 보다는 내부 비즈니스 로직이 포함된 RedisClient 인터페이스를 만들어 사용하곤 하는데요. 아래는 그 예시 입니다. redis.go package main import ( "context" "fmt" "github.com/go-redis/redis/v8" // go-redis import ) // RedisClientInterface 인터페이스 정의 type RedisClientInterface interface { Set(key string, value interface{}) error Get(key string) (string, error) } // RedisClient ..

json value가 null일때 golang은 Unmarshal을 잘 할 수 있을까?

golang은 JSON Format 데이터를 struct로 변환할 수 있는데 이것을 Unmarshal이라고 부릅니다. 예를 들어 다음과 같은 함수로 구현될 수 있습니다. func getStructFromJSON(jsonData string, valuePtr interface{}) error { return json.Unmarshal([]byte(jsonData), valuePtr) } jsonData : json포맷으로된 String 데이터 valuePtr : struct타입 예를 들어 다음과 같이 호출할 수 있습니다. type SampleStruct struct { A int32 `json:"a"` B int32 `json:"b"` } func main() { var valuePtr SampleStru..

map[string]interface 데이터를 avro 포맷으로 파일 저장하는 방법

package main import ( "encoding/json" "fmt" "github.com/linkedin/goavro" "os" "time" ) func main() { // Avro 스키마 정의 schemaJSON := `{ "type": "record", "name": "Example", "fields": [ {"name": "username", "type": "string"}, {"name": "age", "type": "int"} ] }` codec, err := goavro.NewCodec(schemaJSON) if err != nil { panic(err) } // 파일 생성 file, err := os.Create("avro_data.avro") if err != nil { pan..

golang struct type을 JSON으로 Print 하기

package main import ( "encoding/json" "fmt" ) type Person struct { Name string Age int } func main() { myStruct := Person{"dvwy", 145} fmt.Println("=======") fmt.Println(myStruct) fmt.Println(prettyPrint(myStruct)) } func prettyPrint(i interface{}) string { s, _ := json.MarshalIndent(i, "", "\t") return string(s) } 결과는 다음과 같습니다. {dvwy 145} { "Name": "dvwy", "Age": 145 } 출처 : https://stackoverflo..

spring boot HttpServletRequest 사용 쿠키 구현시 HttpSession.getAttribute(String) is null 에러 발생 대응

spring boot에서 쿠키/세션 로그인 기능 구현시 다음과 같은 에러를 만났습니다 ...HttpSession.getAttribute(String)" is null 분명히 다음과 같이 attribute를 제대로 설정했는데 왜그랬을까요? HttpSession session = request.getSession(true); session.setAttribute("LOGIN_MEMBER", 123); 이유는 다음과 같습니다. 제가 가진 특수한 상황 때문이였는데요. - server : localhost:8080 - client : localhost:3000 - client는 server로 axios 요청을 함 위 상황은 여러가지 문제가 있었고 해결방안은 다음과 같습니다. 1) CORS 문제 크로스 도메인에 대..

golang prviate repository에서 디펜던시 가져오는 방법

golang private repository를 하위 모듈로 가져올 때 그냥 import를 실행하고 나면 다음과 같은 이슈가 종종 발생하곤합니다. $ go get github.com/AndersonChoi/my-private-repo go: downloading github.com/AndersonChoi/my-private-repo v0.0.0-20230306053459-dec1333da9d3 go: github.com/AndersonChoi/my-private-repo@v0.0.0-20230306053459-dec1333da9d3: verifying module: github.com/AndersonChoi/my-private-repo@v0.0.0-20230306053459-dec1333da9d3: re..

goroutine 함수 여러번 실행 결과값 기다리는 2가지 방법 - js callback 처럼

WaitGroup을 사용하는 방법 1) sync.WaitGroup을 사용하여 대기 2) go func 사용하여 goroutine 함수 호출 위 2가지 방법을 사용하면 여러번 실행된 결과값을 병렬 처리한 뒤 한개의 결과값으로 추출할 수 있습니다. 예제 코드는 다음과 같습니다. package main import ( "fmt" "math/rand" "strconv" "sync" "time" ) func main() { result := 0 count := 10 var wg sync.WaitGroup // WaitGroup 선언 wg.Add(count) // Wait 개수 지정 for i := 1; i

go gin framework graceful shutdown 예제

https://gin-gonic.com/docs/examples/graceful-restart-or-stop/ Graceful restart or stop Do you want to graceful restart or stop your web server? There are some ways this can be done. We can use fvbock/endless to replace the default ListenAndServe. Refer issue #296 for more details. router := gin.Default() router.GET("/", handler) // [...] end gin-gonic.com gin은 golang에서 많이 쓰이는 웹프레임워크입니다. graceful..

intellij에서 golang 프로젝트 인식이 잘 안될때

intellij에서 golang을 최초로 실행 시키고 난뒤에 $ go mod init myapplication 프로젝트가 정상적으로 라이브러리들을 Import시키지 못할 때가 있습니다. 그럴 경우에는 cmd + , 를 눌러서 Preferences로 간 뒤 Go Modules의 Enable Go modules integration을 체크하면 싱크됩니다. 싱크가 완료된 go.mod 파일 모습 module myapplication go 1.19 require ( github.com/gin-gonic/gin v1.9.0 github.com/prometheus/client_golang v1.14.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.co..

실행 가능한 자바 jar 패키지 만들기(with gradle)

실행 가능한 자바의 jar 패키지를 만들기 위해 shallowjar 등을 사용했었다. 그러나 아래와 같은 코드를 사용하여 uberJar(디펜던시가 모두 포함된)을 만들 수도 있다. task uberJar(type: Jar) { from sourceSets.main.output dependsOn configurations.runtimeClasspath from { configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } } manifest { attributes "Main-Class": "com.example.Main" } } - package명 : com.example - public static ..

현재 Unixtime 가져오기 in 자바

Unixtime으로 현재시간을 가져오고 싶다면 아래와 같이 수행합니다. System.currentTimeMillis() Returns the current time in milliseconds. Note that while the unit of time of the return value is a millisecond, the granularity of the value depends on the underlying operating system and may be larger. For example, many operating systems measure time in units of tens of milliseconds. See the description of the class Date for a ..

golang 동시성 예제

golang은 동시성 프로그램을 위해 태어난 언어라고 해도 과언이 아닙니다. 예제를 통해 golang이 동시성을 만족하는 코드를 작성하여 보여드리겠습니다. 동시성을 위해 goroutine과 channel 개념을 사용합니다. 각 개념은 아래 링크에서 확인할 수 있습니다. - goroutine : golang.site/go/article/21-Go-%EB%A3%A8%ED%8B%B4-goroutine Go루틴(goroutine)은 Go 런타임이 관리하는 Lightweight 논리적 (혹은 가상적) 쓰레드(주1)이다. Go에서 "go" 키워드를 사용하여 함수를 호출하면, 런타임시 새로운 goroutine을 실행한다. goroutine은 비동기적으로(asynchronously) 함수루틴을 실행하므로, 여러 코드를..

자바와 스칼라 차이점

자바와 스칼라 둘다 JVM위에서 돌아간다는 공통점이 있다. 그러나 객체지향적 언어와 함수형 언어라는 점이 매우 다르다. 어떤 다른점이 있는지 개략적으로 살펴보자. TRAIT 스칼라의 trait는 자바의 인터페이스와 유사한 역할을 한다. 스칼라에서는 interface가 없다. trait는 변수를 선언하고 메서드를 구현할 수 있다는 점이 인터페이스와 차이점이다. 물론 자바 8부터는 인터페이스에서 default 메서드형태로 구현할 수 있는 점이 동일하다. 그러나 자바8의 인터페이스는 변수를 선언할 수 없고 메서드만 선언할 수 있기 때문에 trait와 차별점을 가진다고 볼수 있다. 그럼 추상클래스와 비슷하다고 볼 수 있지 않을까? 자바의 추상클래스는 2개 이상 상속가능하고 trait도 클래스에 2개 이상의 tr..

go get으로 특정 github 레포지토리의 태그 가져오기

go get을 통해 레포지토리 코드를 가져오고 해당 레포지토리의 태그를 가져오는 방법입니다. 이 방법은 golang 1.15버전을 기준으로 작성하였습니다. 1. 레포지토리 가져오기 $ go get github.com/grafana/grafana package github.com/grafana/grafana: build constraints exclude all Go files in /root/go/src/github.com/grafana/grafana 2. 디렉토리 가기 $ cd /root/go/src/github.com/grafana/grafana 3. git명령어로 체크아웃 $ git checkout v7.2.2

인증서란? openJDK의 cacerts 설명

인증서(Certificate) 디지털 인증서라고도 부른다. 유저 -> 브라우저 또는 서버 -> 서버 간에 암호화된 연결을 수립하는데 사용된다. 인증되지 않는 사용자의 네트워크 데이터 탈취를 막기 위한 용도. SSL 인증서는 공개키 방식을 사용한다. 공개키 방식은 공개키와 비밀키 방식이 있다. 공개키 방식으로 암호화하고 비공개키로 복호화한다. 비공개키가 없으면 복호화할 수 없다. CA(Certificate authority) 인증서를 보장하는 기업들을 CA 또는 Root Certificate라고 부른다. CA는 신뢰성이 업격하게 공인된 기업들만이 참여할 수 있다. 대표적인 기업으로는 Symantec, Comodo, GlobalSign 등이 있다. 암호화된 통신을 제공하려는 서비스는 CA를 통해서 인증서를 ..

log4j에서 DailyRollingFileAppender 사용시 반드시 선언 순서를 지켜야한다.

log4j는 properties파일을 통해 로깅 파일을 어떻게 활용할 것인지 선언할 수 있습니다. 그런데 이 파일에서 DailyRollingFileAppender를 사용할 경우 순서를 반드시 지켜야합니다. 그 순서란 아래와 같습니다. log4j.appender.outAppender=org.apache.log4j.DailyRollingFileAppender log4j.appender.outAppender.DatePattern='.'yyyy-MM-dd log4j.appender.outAppender.File=${router.logs.dir}/application.log log4j.appender.outAppender.layout=org.apache.log4j.EnhancedPatternLayout log4j..

JVM 기반 애플리케이션 운영시 스레드 덤프를 통한 이슈 해결

JVM기반 애플리케이션을 개발하다가 이슈가 생겼을때 다양한 방식으로 이슈를 확인하고 처리할 수 있습니다. 그중 한가지인 스레드 덤프를 사용하여 이슈를 해결한 사례를 공유하겠습니다. 제가 운영하고 있는 애플리케이션은 Scala로 이루어져 있고 JDK 1.8에서 돌아가는 Multithread application입니다. 카프카 컨슈머를 스레드로 작게는 10개 많게는 100개이상 띄워서 운영하고 있습니다. 이 애플리케이션은 안전하게 중지하기 위해 Shutdown hook을 받도록 개발했습니다만, 언제부턴가 Shutdownhook을 통해 중지요청을 하더라도 애플리케이션이 중지하는 절차를 진행하지 않는 현상이 발생했습니다. 또다시 shutdown hook을 kill -term 명령어와 함께 명령내렸으나 응답이 없..

sbt 실행시 '/modules/java.base/java/lang/String.class' is broken 이슈 해결 방법

sbt를 실행했을 경우 아래와 같은 에러가 발생하였습니다. 위 에러는 java13을 사용하기 때문에 발생하는 오류인데요. 공식 sbt download 홈페이지에서도 이 에러에 대해 처리하는 방법에 대해 자세히 나와 있습니다. ⚠️ Homebrew maintainers have added a dependency to JDK 13 because they want to use more brew dependencies (brew#50649). This causes sbt to use JDK 13 even when java available on PATH is JDK 8 or 11. To prevent sbt from running on JDK 13, install jEnv or switch to using SD..

Java GC 종류별 도식화

이 포스트는 https://blog.voidmainvoid.net/190에서 이어지는 내용입니다. 자바 가비지 컬렉션 설명 및 종류 Getting Started JVM 기반 언어와 C, C++과 가장 큰 다른점은 free()와 같은 메모리접근을 통한 명시적 메모리 해제 여부이다. 자바는 OS메모리 영역에 직접 접근하지 않고 JVM이라는 Process이자 가상머신을 통해.. blog.voidmainvoid.net Garbage Collection은 Heap memory에 존재하는 unreachable object를 삭제하는 과정입니다. Java에서는 여러 버젼을 업그레이드 해가는 동안 다양한 GC알고리즘을 적용했었습니다. 오늘은 각 GC별 동작을 도식화하여 설명드리도록 하겠습니다. GC 도식화 설명에 앞선..

Java PermGen의 역사

오늘은 Java PermGen에 대해서 알아보겠습니다. PermGen은 JDK 1.7 이하 버젼에서 존재하였습니다. 이곳은 클래스 메타 데이터가 들어갈 곳인데, 이 공간의 크기는 예측하기가 어려웠습니다. 자바에서는 클래스의 메타데이터를 읽고 해당 메타데이터를 통해 객체를 생성할 수 있습니다. 클래스 메타데이터란? : 클래스의 이름, 생성정보, 필드정보, 메서드 정보 등 그 때문에 아래와 같은 에러가 종종 일어나곤 했습니다. java.lang.OutOfMemoryError: PermGen space PermGen영역은 OS, JVM버젼마다 각기다른 default값을 가지고 있으며 대부분 매우 작게 할당되어 있었습니다. 그렇기 때문에 클래스 로딩을 많이하다보면 PermGen이 부족할때 위와 같은 에러가 발생..

스레드풀(Thread Pool)이란? 종류, 설명

자바에서 스레드를 생성하고 제거하며, 다수의 스레드를 관리할 수 있도록 자바에는 java.util.concurrent.Executors 를 통해 스레드풀 기능을 제공하고 있습니다. public class Executors { public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); } ... 스레드풀의 종류 - newFixedThreadPool : 주어진 스레드 개수만큼 생성하고 그 수를 유지. 생성된 스레드 중 일부가 종료되었으면 스레드를 다시 생성. - ne..

JVM 버젼별 Scala 하위호환표(JDK Compatibility for scala)

이 포스트는 2020년 2월 18일 기준입니다. Scala는 JVM위에서 돌아가는 언어이며, Scala버젼별로 JVM 버젼의 호환성이 있으므로 아래 표를 기준으로 Scala버젼을 운영해야합니다. Scala 공식홈페이지에 따르면, Java 8 이상에서 scala를 compile하는 것을 권장합니다. JVM은 하위호환성이 있으므로, Compile은 옛날버젼으로 하되, 실제 code를 Running할때는 최신버젼의 JVM버젼을 사용하는게 일반적입니다. Java 8으로 compile된 Scala code는 JVM 8 이상에서 정상적으로 돌아야만 합니다. 만약 Java8으로 compile했음에도 불구하고 이슈가 생긴다면 이는 긴급수정 사항입니다. 일부 오래된 JVM버젼은 scala code의 compile과 ru..

Python AES 암호화하기(AES/CBC/PKCS5Padding)

Python으로도 암호화를 손쉽게 할 수 있습니다. 이번 포스팅에서는 AES/CBC/PKS5Padding으로 암호화 하는 Python code를 보여드리겠습니다. 먼저 필요한 module은 아래와 같습니다. from Crypto.Cipher import AES 위 모듈을 사용하기 위해서는 아래와 같이 pip를 통해 모듈을 설치해줍니다. $ pip install pycrypto 모듈 사이트 : https://pypi.org/project/pycrypto/ pycrypto Cryptographic modules for Python. pypi.org AES encrypt를 하기 위해서는 key와 iv가 필요하므로 선언하며, 암호화 길이가 32보다 작을경우 padding으로 빈공간을 채워주는 로직을 사용합니다..

DateTimeFormatter에서 년도표시에 yyyy대신 uuuu를 사용해야하는 이유?

DateTimeFormatter는 Java에서 datetime을 표시할때 가장 많이 사용하는 코드중 하나입니다. 보통 아래와 같은 코드로 표기하여 사용하는데요. LocalDate m = LocalDate.of(2018,12,31); String str = m.format(DateTimeFormatter.ofPattern("yyyy-MM"); //2018-12 선언한 pattern에 따라 LocalDate가 변경되어 String으로 반환되는 모습을 볼 수 있습니다. 위 pattern은 아래와 같은 특징을 가지는데요. 위 특징에 따라 보통 년도를 표시할때 yyyy를 사용하곤 합니다. 그런데 stackoverflow의 이 질문(링크)에서는 yyyy대신 uuuu를 사용하라고 합니다. 왜일까요? 서기, 기원전 표..

인도 온라인 교육업체에서 제공하는 무료 빅데이터 튜토리얼

DataFair는 인도의 교육업체이다. 2014년 11월에 창업한 업체로 여러 프로그래밍언어, 프레임워크 등의 튜토리얼, 교육영상을 제공한다. 그 중 무료 튜토리얼은 무료로 제공되는데 이 내용이 아주 잘 분류되어있고 쉬운 영어로 되어있다. 그렇다고 내용이 부실한것도 아니고 내용이 알차다. 또한 인터뷰 질문에 나올만한 내용을 또 정리해뒀기 때문에 튜토리얼을 한번더 wrap-up하기 좋다. 아래는 Bigdata에서 사용하는 application 종류별 튜토리얼이다. Apache Kafka https://data-flair.training/blogs/apache-kafka-tutorial/ Apache Kafka Tutorial - Door to Gain Expertise in Kafka - DataFlair..

Spring boot Resttemplate 사용시 HttpComponentsClientHttpRequestFactory 옵션 설명(setConnectTimeout, setConnectionRequestTimeout, setReadTimeout)

개요 Spring boot에서 rest call을 위해 Resttemplate를 사용한다. 이때 여러 옵션(connection timout 등)을 사용하기 위해 아래와 같이 Restemplate에 RequestFactory를 주입하여 사용하는 경우가 있다. 이 경우 각 옵션이 어떤 역할을 하는지 알아보자 HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setConnectionRequestTimeout(30000); requestFactory.setConnectTimeout(30000); requestFactory.setReadTimeout(300..

Resttemplate으로 PATCH 사용시 에러나는 경우 해결방법 - Invalid HTTP method: PATCH; nested exception is java.net.ProtocolException: Invalid HTTP method: PATCH

Spring boot 내에서 Resttemplate를 사용하여 타 url을 호출하는 경우가 있다. 사용하던 도중 아래와 같은 오류가 날 때가 있다. RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); URI uri = new URI(Api.patchJob(host)); String active = "{\"active\":true}"; headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity(active, headers); ResponseEntity response = restTemplate.exchan..