전체 글 (358)

💻 Programming

brew update 오류 (couldn't find remote ref)

토이프로젝트 진행하면서 MongoDB를 로컬환경에 설치하는 와중에 brew update 명령어를 실행했더니 아래와 같이 에러가 발생했습니다.

 

% brew update

==> Updating Homebrew...

fatal: couldn't find remote ref refs/heads/master

Error: Fetching /opt/homebrew/Library/Taps/dart-lang/homebrew-dart failed!

Error: Some taps failed to update!

The following taps can not read their remote branches:

  dart-lang/dart

This is happening because the remote branch was renamed or deleted.

Reset taps to point to the correct remote branches by running `brew tap --repair`

 

에러메시지를 읽어보니 dart-lang/dart 의 원격 브랜치를 읽을 수 없다고하면서 이름이 변경됐거나 삭제되었을테니 brew tap --repair 를 실행하라고 하네요. 그래서 dart-lang/dart 를 타겟으로 주어 실행하니..

 

% brew tap --repair dart-lang/dart

remote: Enumerating objects: 1226, done.

remote: Counting objects: 100% (1226/1226), done.

remote: Compressing objects: 100% (199/199), done.

remote: Total 1226 (delta 1086), reused 1133 (delta 1006), pack-reused 0

Receiving objects: 100% (1226/1226), 193.80 KiB | 1.15 MiB/s, done.

Resolving deltas: 100% (1086/1086), completed with 12 local objects.

From https://github.com/dart-lang/homebrew-dart

 * [new branch]      dependabot/github_actions/github-actions-9c54b75f35 -> origin/dependabot/github_actions/github-actions-9c54b75f35

 * [new branch]      dependabot/pub/googleapis-13.2.0 -> origin/dependabot/pub/googleapis-13.2.0

 * [new branch]      dependabot/pub/test-1.25.7       -> origin/dependabot/pub/test-1.25.7

 * [new branch]      main                             -> origin/main

==> dart-lang/dart: changed default branch name from master to main!

 

이렇게 default 브랜치가 master 에서 main 으로 변경됐다고 친절히 알려줍니다.

 

 

오랜만에 개인 프로젝트를 시작했는데 쉬는 텀이  길다보니 매번 시작할때마다 git 관련 오류때문에 구글링하는 시간이 아까워 기록용으로 남깁니다.

 

소스 코드 작성하고 이런저런 테스트 해보고 github repo 생성후에 push 하려고 했는데 

% git init

% git remote add origin {github url}

% git push --set-upstream origin main
Password for 'https://aaaaaa@github.com': 
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aaaaaa/test.git/'

 

이렇게 에러가 난다면 Password 란에 Personal Access Token(PAT) 값을 넣어주면 됨.

PAT 는 github계정설정 (repo 설정 아님) > Developer Settings > Personal access tokens (classic) 에서 발급받을 수 있음.

 

 

그리고 브랜치 이슈로 아래와 같은 에러가 발생한다면..

 % git checkout main
branch 'main' set up to track 'origin/main'.
Switched to a new branch 'main'
% git merge prod
fatal: refusing to merge unrelated histories

 

% git merge prod --allow-unrelated-histories

이 명령어로 해결할 수 있음

💻 Programming

Spock Test Framework 실행 오류 해결

(SpringBoot3 + Correto 17 (java 17) 환경에서 spock test 시 발생한

TestEngine with ID 'spock' failed to discover tests 오류 해결방안 공유합니다.

 

IntelliJ 에서 Spring Initializer를 이용하여

스프링부트3 + 자바 17 기반의 신규 프로젝트를 생성,

빌드가 정상적으로 되는지 확인 후

spock 테스트를 위한 라이브러리를 아래 3개 추가했습니다.

testImplementation 'org.spockframework:spock-core:2.4-M1-groovy-4.0'
testImplementation 'org.spockframework:spock-spring:2.4-M1-groovy-4.0'
testImplementation 'org.apache.groovy:groovy-all:4.0.13'

 

 

그리고 샘플 테스트 클래스를 만들었습니다.

class SampleSpec extends Specification {

    def "where with variables: #size"() {
        when:
        def list = new ArrayList(size)

        then:
        list.size() == 0

        where:
        size << [1, 2, 3, 4, 5]
    }

    def "using data tables for calculating max, Max of #a and #b is #max"() {
        expect:
        Math.max(a, b) == max

        where:
        a | b || max
        1 | 2 || 2
        7 | 4 || 7
        0 | 0 || 0
    }
}

 

 

실행을 해보았더니 아래와 같은 에러가 발생했습니다.

Internal Error occurred.
org.junit.platform.commons.JUnitException: TestEngine with ID 'spock' failed to discover tests
...중략...

Caused by: org.junit.platform.commons.JUnitException: ClassSelector [className = 'com.project.SampleSpec', classLoader = null] resolution failed
...중략...

Caused by: org.junit.platform.commons.PreconditionViolationException: Could not load class with name: com.project.SampleSpec
...중략...

Caused by: java.lang.ClassNotFoundException: com.project.SampleSpec

 

 

구글링 결과 build.gradle 파일의 plugins 에 id 'groovy' 를 추가해주면 되는 문제였습니다.

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.1'
    id 'io.spring.dependency-management' version '1.1.4'

    id 'groovy'  <-- 이게 있는지 확인
}

 

최근 2년정도 IntelliJ에서 Java 11 기반의 AWS Correto 11 을 사용해왔습니다

그래서 현재 JAVA_HOME 은 AWS Correto 11 의 위치를 가리키고 있었습니다.

신규 프로젝트 구성할 일이 생겼고

AWS Correto 17 을 미리 다운받아둔 상태에서

IntelliJ 에서 SpringBoot Initializer 를 이용해서

아래와 같은 설정(Java 17 + gradle groovy)으로 프로젝트를 생성하고

빌드를 하니 오류가 발생했습니다.

스프링부트 신규 프로젝트 생성 설정화면 (Java 17 설정)

 

아래는 빌드시 발생했던 오류 메시지

A problem occurred configuring root project 'my-new-springboot3-project'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve org.springframework.boot:spring-boot-gradle-plugin:3.2.1.
     Required by:
         project : > org.springframework.boot:org.springframework.boot.gradle.plugin:3.2.1
      > No matching variant of org.springframework.boot:spring-boot-gradle-plugin:3.2.1 was found. The consumer was configured to find a library for use during runtime, compatible with Java 11, packaged as a jar, and its dependencies declared externally, as well as attribute 'org.gradle.plugin.api-version' with value '8.5' but:
          - Variant 'apiElements' capability org.springframework.boot:spring-boot-gradle-plugin:3.2.1 declares a library, packaged as a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component for use during compile-time, compatible with Java 17 and the consumer needed a component for use during runtime, compatible with Java 11
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.5')
          - Variant 'javadocElements' capability org.springframework.boot:spring-boot-gradle-plugin:3.2.1 declares a component for use during runtime, and its dependencies declared externally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its target Java version (required compatibility with Java 11)
                  - Doesn't say anything about its elements (required them packaged as a jar)
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.5')
          - Variant 'mavenOptionalApiElements' capability org.springframework.boot:spring-boot-gradle-plugin-maven-optional:3.2.1 declares a library, packaged as a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component for use during compile-time, compatible with Java 17 and the consumer needed a component for use during runtime, compatible with Java 11
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.5')
          - Variant 'mavenOptionalRuntimeElements' capability org.springframework.boot:spring-boot-gradle-plugin-maven-optional:3.2.1 declares a library for use during runtime, packaged as a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component, compatible with Java 17 and the consumer needed a component, compatible with Java 11
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.5')
          - Variant 'runtimeElements' capability org.springframework.boot:spring-boot-gradle-plugin:3.2.1 declares a library for use during runtime, packaged as a jar, and its dependencies declared externally:
              - Incompatible because this component declares a component, compatible with Java 17 and the consumer needed a component, compatible with Java 11
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.5')
          - Variant 'sourcesElements' capability org.springframework.boot:spring-boot-gradle-plugin:3.2.1 declares a component for use during runtime, and its dependencies declared externally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its target Java version (required compatibility with Java 11)
                  - Doesn't say anything about its elements (required them packaged as a jar)
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.5')

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 1s

 

에러 메시지의 내용을 읽어보니, 일단 Could not resolve xxx 의 경우 xxx 라이브러리가 없다라는 메시지인데

신규 생성한 프로젝트에서 필수라이브러리를 dependency에 안넣을 이유가 없다는 생각이 우선 들었습니다.

그런거라면 springboot initializer 의 버그일테니까요.

그래서 더 읽어봤습니다.

그리고 "requierd compatibility with Java 11" 문구가 눈에 띄었습니다.

난 자바17을 쓰려고 17버전으로 JDK와 Java 설정을 넣었는데 왜 Java 11 관련메시지가 뜨는건지 이상했습니다. 🤔

에러메시지 내용으로 구글링을 좀 해보니 아래 부분들을 확인해보라는 내용들이 있었습니다.

  • 현재 시스템에서 사용하는 Java 버전 확인 (java -version)
  • build.gradle 파일의  sourceCompatibility 확인
  • IntelliJ 의 project SDK 설정 확인
  • gradle JVM 설정 확인

일단 빌드시에 발생했고, 빌드툴은 gradle 이라는 걸 이미 프로젝트 생성시 설정을 해주었고, IntelliJ에 gradle 이 사용할 자바버전을 설정하는 내용이 있다는 것을 알고있었기에 gradle JVM 설정을 먼저 확인해봤습니다.

gradle JVM 설정이 기존 설정 그대로 Java 11을 사용하도록 되어있었습니다. 😭

프로젝트 생성시 correto 17, Java 17 버전을 설정해주었기에 sourceCompatibility 와 project SDK 는 17버전을 사용하도록 되어있었고, JAVA_HOME에 설정되어있는 현재 시스템에서 기본으로 사용중인 Java 버전과는 관계가 없었습니다.

 

gradle JVM 설정 확인 방법

Preferences/Settings (⌘ + , ) > Build, Execution, Deployment > Build Tools > Gradle

Gradle JVM 설정 화면

project SDK 설정 확인 방법

File > Project Structure.. (⌘ + ; )

Project SDK 설정 화면

build.gradle 파일의 sourceCompatibility 확인 방법

build.gradle 파일에서 sourceCompatibility 설정 방법

💻 Programming

SpringBoot 2.3 -> 2.5 업그레이드 후기

SpringBoot 버전을 업그레이드 해야할 일이 생겨서 2.3 버전을 2.5 버전으로 업그레이드한 경험담을 공유합니다.

개발인생 처음으로 해보는 레거시 시스템의 프레임워크 업그레이드 작업이었습니다.

대부분은 신규 프로젝트를 만들거나 deprecate 된 상태로 유지하는 정도였죠.

그래도 해보고 싶었던 부분이었습니다. 업무가 많이 지루해진것도 한 몫 했죠.

저는 주기적으로 반기에 한번정도는 라이브러리 업그레이드 작업을 진행해야한다고 생각하지만

저희 개발팀은 이상하게 라이브러리 업그레이드 작업을 안합니다. 

그런데 갑자기 프레임워크 업그레이드를 하려니 dependency 가 많이 걸려있을거라 예상했죠.

 

우선 2.3 -> 2.4 로 올라가면서 어떤 부분에 변화가 생겼는지를 확인하고 대응하고,

2.4 -> 2.5 에서는 어떤 변화가 있었는지 확인하여 대응하면 될거라 생각했고 

아래 2개의 spring boot release note 를 하나하나 살펴봤습니다.

2.3 -> 2.4 에서 변경된 부분

  • JUnit 5’s Vintage Engine Removed from spring-boot-starter-test
  • Config File Processing (application properties and YAML files)
  • Config Data Imports
  • Embedded database detection
  • User-defined MongoClientSettings no longer customized
  • Logback Configuration Properties
  • Default Servlet Registration
  • HTTP traces no longer include cookie headers by default
  • Undertow Path on Forward
  • Neo4j
  • Hazelcast 4
  • Elasticsearch RestClient
  • R2DBC
  • Flyway
  • Removal of Plugin Management for Flatten Maven Plugin
  • Version management for exec-maven-plugin
  • Spring Boot Gradle Plugin
  • Metrics export in integration tests
  • Deprecations from Spring Boot 2.2 and 2.3

2.4 -> 2.5 에서 변경된 부분

  • SQL Script DataSource Initialization
  • Flyway and Liquibase JDBC URLs
  • Spring Data JPA
  • Spring Data Solr
  • Secure Info Endpoint
  • Task Scheduling Harmonization with Spring Integration
  • Default Expression Language (EL) Implementation
  • Messages in the Default Error View
  • Logging Shutdown Hooks
  • Gradle Default jar and war Tasks
  • Cassandra Throttling Properties
  • Customizing jOOQ’s DefaultConfiguration
  • Groovy 3
  • Minimum Requirements Changes
  • Hibernate Validator 6.2

위에 나온 내용 이외에도 업그레이드 되면서 deprecated 되는 것들에 대한 부분들, 그리고 새로 추가 된 부분들에 대한 설명을 하나하나 읽어보고 현재 내가 담당하는 프로젝트에서 사용되는 것들과 연관된 것들을 모두 읽어보았습니다.

그리고 spring boot 버전을 변경한 뒤 오류가 발생하는 부분은 없는지 배포는 잘 되는지를 확인했습니다.

boot 업그레이드 작업하면서 변경했던 부분은 아래 내용들이었습니다.

  • spring.config.use-legacy-processing = true 설정을 추가
  • fasterxml.jackson.databind.PropertyNamingStrategy -> PropertyNamingStrategies 클래스 변경
  • third-party dependency 들 중에서 업그레이드가 필요한 것들 확인 및 업그레이드
  • gradle 버전 업그레이드 6.7 -> 6.9

작업 내용만보면 진짜 별거 아니었던 작업으로 보이네요. 작업시간보다 문서 읽어보는 시간이 더 오래 걸렸던것 같습니다. 링크를 타고타고 들어가야 확인할 수 있는 것들이 많다보니..

아무튼 로컬환경에서 잘 돌아가는 것까지 확인 하고 개발에 올려 테스트를 해보니 애플리케이션이 정상적으로 실행되지 못하는 현상이 확인되었습니다. 왜 그런가 봤더니 jar 파일명이 이상하게 바뀌어있었습니다. 끝에 -plain postfix가 붙은 파일명이 배포된 것을 확인했고 이게 뭔가 싶어 구글링을 해보니 release note 에서 설명을 찾아볼 수 없었지만(내가 못 본 걸수도?) 2.5버전부터 발생하는 현상이었고 gradle 설정에서 jar task를 비활성화 시키거나 배포파일을 만드는 task 에서 해당 파일을 exclude 처리하면 되는 문제였습니다.

 

매일 반복되는 특별하지 않은 업무들만 하다가 처음으로 해본 프레임워크 업그레이드 작업은 너무 재미있었고 좋은 경험이었습니다.

 

내년에는 java 17 + SpringBoot 3 기반의 신규 프로젝트를 하나 만들어야 하는데 벌써부터 기대되고 현재 사용중인 java 11 에서 17까지 어떤 변화들이 있었는지 확인하는 시간을 가져야 할 것 같습니다.

 

개인프로젝트를 하다보면 한동안 작업진행을 못하다가 다시 재개하는 경우가 많은데

이때 노트북을 새로 바꾸었거나, 프로젝트 디렉토리를 잘못해서 삭제했다가

다시 git clone 할 때 Invalid username or password 를 보게 된다.

github 에서 https 주소로 clone 을 하거나

토근유효기간을 넘겨서 git push를 하게되면

invalid 오류가 발생하게 된다.

1년에도 여러번 이런 일이 발생하는데

어떻게 처리해야하는지 자꾸 까먹어서 기록용으로 남깁니다.

Github 계정의 Settings > Developer Settings 로 가서

Personal Access Token(이하 PAT) 을 재생성(regenerate)합니다.

그리고 git clone 의 경우 아래처럼 clone 명령을 입력합니다.

https://계정명:PAT@github.com/클론할_repo의 주소

git push 의 경우 username과  password 를 입력하는 프롬프트가 뜨게되는데

이때 password 에 github 웹 로그인시 입력하는 password 가 아닌 PAT 를 입력하면됩니다. 

포스팅을 너무 오랜만에 하네요.

요즘은 회사사정도 별로고 회사업무에서 배우는 것도 뭐 없다보니 블로그에 글을 잘 안쓰게 되네요.

하지만!!!! 성장에 대한 욕구는 아직도 초심과 같다는... ㅎㅎ

flutter 에 매료된 올해 초부터 flame 을 이용하여 게임개발을 진행했었습니다.

1일차 이후로 포스팅을 하지 않았지만

flutter와 flame 공식문서 읽어가면서 짬짬이 개발을 진행했고

5월 31일 구글플레이에 출시됐습니다.

대략 주 2회 밤샘 작업으로 진행을 했으니 실제 개발기간은 2개월정도 될 것 같네요

일단 결과물이 어떻게 나왔는지 보고 싶으실 것 같아 구글플레이 링크를 하나 남깁니다

https://play.google.com/store/apps/details?id=com.keichee.exterminate_mosquitoes&hl=ko-KR

 

모기 헌터 - Google Play 앱

인류 최대의 해충! 모기를 박멸하고 지구를 구해주세요

play.google.com

 

모기를 잡으면서 여섯가지 종류의 모기들을 수집하고,

능력치를 향상시키면서 더 높은 stage 로 올라가고,

광고시청으로 레벨업에 필요한 코인(?)을 추가획득 할 수 있습니다.

리더보드도 추가해볼 예정입니다.

💻 Programming/Flutter & Dart & Flame

[Flame] 게임 개발 1일차

요즘 flutter & flame 으로 1인게임 개발을 진행하고 있는데 알아야 할게 너무나도 많아 문서 찾아보고 유툽 영상 찾아보면서 얕은 지식을 조금씩 조금씩 모으다가 지겨워져서 엊그제 하루 날 잡아서 퇴근하고 밤새워 구글링해가면서 만들어봤습니다.

인트로 화면도 로비화면도 없고 그냥 모기 날아다니게 만들고 터치하면 HP 줄어들면서 사라지고 단계별로 정해진 모기들을 모두 잡으면 다음 단계로 넘어가도록 했습니다. 아래는 샘플 영상입니다.

 

원래 단계별로 일정 마리수의 모기가 나오도록 해놓았으나 단계별로 모기마리수를 제외하면 특별할게 없어서 단계당 한마리씩만 출몰하도록 설정을 변경한 뒤 녹화했습니다. 단계별로 모기의 HP도 늘어납니다. ㅎㅎ

아직 해야할게 많이 있지만 중간중간 기록을 위해 포스팅합니다.

앞으로 해야할 것들은... HP바 만들기... 유저 로그인 및 최종게임상태 저장하기, 리더보드, 모기의 유저공격 기능, 유저 및 모기 공격력, 장비&스킬, 보스급모기, 보스출현시 애니메이션 등등 기획하기 및 그림그리기 등등... 너무 많이 있지만 천천히 끝까지 가보려고 합니다 ㅎ

 

flutter 에 입문한지 2주정도 되가는것 같네요

우연히 유툽통해서 접한뒤로 반해가지고 실제 업무에서 쓸일은 없을 것 같지만 모바일앱이든 웹이든 1인개발용으로 너무 좋을 것 같아 입문했습니다.

한 2주동안 책 구입해서 읽고, 공식문서 읽고, 책 예제와 코드랩 예제들 그리고 유툽 예제들 따라해보고나서,

간단한 타자연습 앱을 만들어 봤는데 어떤 위젯을 사용할지부터해서 처음부터 끝까지 오로지 제 생각만으로 하나 만들어보았습니다. (예제 따라하기는 코드랩이 제일 배우기 좋았던 것 같습니다)

타수계산할때 한글은 영어보다 까다로울 것 같아 영문버전으로만 만들었습니다.

이것저것 더 추가하고 싶은 기능(리더보드, 실시간 배틀)들도 있고 flame 을 이용해서 타자를 이용한 여러 게임모드들을 추가하는 등 좀더 게임스럽게 꾸며보고도 싶은데 일단 그냥 기록용도로 남겨봅니다.

매우 간단한 앱이지만 flutter와 더 친숙해질 수 있었던것 같아 매우 유익했던 시간이었네요.

모바일 앱 버전과 웹 버전을 분기태워서 조금 다르게 가져갈 수도 있었는데 아직은 웹보다는 앱개발에 더 최적화된 프레임워크인 것 같습니다.

이제 슬슬 flame 으로 넘어가보려 합니다 :)

자판 연습용 앱

 

아래 영상은 첫 날 설치해서 실행해본 데모앱의 내용을 다 지우고 처음부터 작성하면서 화면 이동, 각종 버튼 추가, 그리고 버튼에 이벤트 핸들링 기능을 넣어보는 기초적인 부분에 대해서 빠르게 가르쳐 주고있습니다. 처음 플러터를 접하는 분들에게 딱 좋은 영상인것 같아서 공유합니다.

 

https://www.youtube.com/watch?v=C-fKAzdTrLU 

 

그리고 플러터 공식문서에서도 Cookbook 에서 기본적으로 필요한 기능들에대해 어떻게 구현해야하는지 예제샘플들을 갖추고 있고, codelab 이라는 단계별 따라해보기와 같은 자료도 제공해주고 있습니다. 코드랩을 따라해보면 앱을 개발할때 어떻게 개발이 진행되는지 그 순서도 배울 수 있습니다.

구글에서 엄청나게 밀고있다는게 느껴질 정도로 기반자료들이 매우 많이 있네요.