반응형

 

Windows 에서의 Android Studio에서 발생하는 'unable to find valid certification path to requested target' 에러 해결방법

 

1. Chrome에서 아무 사이트 접속하여 상단의 자물쇠 모양을 마우스 우클릭한다.

2. 이 사이트는 보안 연결(HTTPS)이 사용되었습니다. 클릭

3. 인증서가 유효함 클릭

4.인증서 창에서 상단의 '인증경로'로 접속한후 '맨위의 항목'을 클릭한 다음 '인증서 보기' 클릭

5. 창이 하나 더 나타나며, 상단의 '자세히' 클릭 후 '파일에 복사' 클릭

6. 인증서 내보내기 마법사에서 먼저 다음 누른 뒤 Base 64로 인코딩된 X.509로 바탕화면이든 아무곳에 저장

반응형

7. Android Stuido에서 해당 프로젝트 우클릭 후 Open Module Settings 클릭

8. 좌측 메뉴의 SDK Location 클릭 후 JDK location 확인

'C:\Program Files\Android\Android Studio\jre'

9. C:\Program Files\Android\Android Studio\jre 폴더로 이동 후 bin폴더로 이동

-> C:\Program Files\Android\Android Studio\jre\bin 으로 이동

bin폴더에 keytools.exe가 있음

C:\Program Files\Android\Android Studio\jre\bin 에서 폴더 Windows PowerShell 관리자로 열기

10. keytool 명령어 입력

cacert 파일은 jre\lib\security 폴더에 들어가면 확인할 수 있는데 아래의 명령어를 통해 cacert에 인증서 등록

-file 옵션에는 아까 저장한 인증서 경로를 적으면되고 -alias 옵션을 통해 별칭 저장

또한, 입력하게 되면 패스워드를 입력하라고 하는데 패스워드는 changeit 이다

Password : changeit

.\keytool -import -keystore "C:\Program Files\Android\Android Studio\jre\lib\security" -file "C:\Users\root\Desktop\testcert.cer" -alias testcert

11. 저장 후 안되면 재부팅 또는 Android Studio를 종료 후 다시 실행

반응형
반응형

.

 

Jenkins 에서 Lambda Plugin을 사용한 코드배포 및 함수 실행이다.

 

1. 람다 생성 및 기본적인 플러그인 세팅

1.1) jenkinsTest 람다 함수생성

람다 함수 생성

1.2) Jenkins Lambda Plugin 세팅

젠킨스 플러그인 설치

반응형

2. 파이프라인 세팅

pipeline {
    agent any
    
    stages {
        stage('Git CheckOut'){
            steps{
                git branch: 'main', url: 'https://github.com/ / .git'
            }
        }
        stage('Make .zip'){
            steps{
                zip zipFile: 'test.zip'
            }
        }
        stage('lambda deploy'){
            steps{
                 withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'pangyeon',
                    accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]){
                    deployLambda(
                        awsRegion: 'ap-northeast-2',
                        awsAccessKeyId: "${AWS_ACCESS_KEY_ID}",
                        awsSecretKey: "${AWS_SECRET_ACCESS_KEY}",
                        functionName: 'jenkinsTest',
                        artifactLocation: 'test.zip',
                        updateMode: 'code'
                    )
                }
            }
        }
        stage('lambda invoke'){
            steps{
                withAWS(region:'ap-northeast-2', credentials:'pangyeon') {
                    invokeLambda(
                        functionName: 'jenkinsTest'
                    )
                }
            }
        }
    }
    post { 
        always { 
            sh 'rm test.zip'
        }
    }
}

 

3. 실행

 

4. 배포 확인

4.1) 이전 코드

이전 코드

4.2) 배포 후 코드

배포 후 코드

5. 실행 확인

5.1) Jenkins 실행 로그

RequestId : d019e541-92df-4fac-9021-96f150b793c2

Jenkins 실행 로그

5.2) Lambda 로그

RequestId :  d019e541-92df-4fac-9021-96f150b793c2

Lambda 로그

5.1, 5.2의 RequestId가 동일하다는 것을 볼 수 있다.

 

반응형
반응형

Groovy 에서 REST API호출을 위해 HttpBuilder란 것을 사용한다.

아래는 간단히 Groovy에서 Jenkins 빌드를 위한 예제

 

import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON

def http = new HTTPBuilder( 'http://jenkinsUrl.com' )
def crumb =''

http.request(GET) { 
  uri.path = '/crumbissuer/api/json' // CSRF 때문에 먼저 token 호출
  headers.'Authorization' = 'Basic id:paswword' // Base64Encode 해야함
 
  response.success = { resp, reader ->
    crumb = reader['crumb']
  }
 
  
  response.failure = { resp ->
    println 'Error'
  }
}

http.request(POST) {
  uri.path = '/job/test/build' // 빌드할 Jenkins Job
  headers.'Authorization' = 'Basic id:paswword' // Base64Encode 해야함
  headers.'Jenkins-Crumb' = crumb // 위에서 호출한 Token값 필요
 
  response.success = { resp, reader ->
    // 성공하면 젠킨스 빌드됨.
  }
 
  
  response.failure = { resp ->
    println 'Error'
  }
}

 

참조 : https://github.com/jgritman/httpbuilder/wiki

 

GitHub - jgritman/httpbuilder

Contribute to jgritman/httpbuilder development by creating an account on GitHub.

github.com

 

반응형
반응형

 

Window에서 Keycloak 포트 변경을 위해 아래와 같이 입력하였으나

.\standalone.bat -Djboss.socket.binding.port-offset=100

 

실행 시 아래와 같은 에러가 발생하였다.

WFLYSRV0073: Invalid option '.socket.binding.port-offset=100'

 

해결방법은 아래와 같이 옵션 양끝에 쌍따옴표를 붙여 해결 할 수 있다.

.\standalone.bat "-Djboss.socket.binding.port-offset=100"

 

 

반응형
반응형

오프라인 서버에 Nexus가 설치되어 있을 경우, Nexus Repository에 Maven 라이브러리들을 대량 업로드할 필요가 있다.

shell script를 이용한방법과 proxy repository를 이용한 방법이있다.

 

 

1. Shell Script를 이용한 방법.

1.1 mavenimport.sh

아래의 주소에 접속해서 Nexus 설치 서버에 mavenimport.sh를 다운받는다.

github.com/sonatype-nexus-community/nexus-repository-import-scripts

 

sonatype-nexus-community/nexus-repository-import-scripts

A few scripts for importing artifacts into Nexus Repository - sonatype-nexus-community/nexus-repository-import-scripts

github.com

 

1.2 Repository 이동

Window라면 User/.m2/repository에 있는 Maven폴더들을 Nexus가 설치되어 있는 서버에 옮긴다.

아래와 같이 mavenimport.sh와 같은 위치에 라이브러리들을 위치시킨다.

1.3 명령어 실행

넥서스 계정과 비밀번호 및 IP와 PORT 저장할 repository들을 지정하고 실행한다.

./mavenimport.sh -u ID -p PASSWORD -r http://IP:PORT/repository/maven-releases/

실행 후 Nexus 저장소를 확인하면 라이브러리들이 들어가있는 것을 확인할 수 있다.

반응형

2. Proxy Repository를 이용하는 방법

2.1 Local Server 또는 Online Server에 Nexus 설치

인터넷이 되는 서버에 Nexus를 먼저 설치한다.

 

 

2.2 Proxy Repository 생성

Offline으로 Nexus가 설치되어 있는 서버에 maven2 (proxy) 저장소를 생성한다.

생성하는 항목의 Remote storage 부분에 인터넷이 되는 서버의 Nexus Maven Central Repository 또는 이미 사용하고 있는 저장소의 URL을 입력한다.

 

2.3 Settings.xml 설정

Maven Settings.xml을 설정한다 Window일 경우 User/.m2/ 폴더에 있다. 만약 없으면 아래와 같이 생성한다.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">


</settings>

생성하였으면, 아래와 같이 <server> 와 <mirror>를 설정한다.

1. <servers>

<id>에는 <mirror>에 입력할 id 이므로 적절하게 사용한다.

<username>은 Nexus 아이디이다. Nexus에 anonymous가 허용되어있다면 입력해도 무관하다.

<password>는 Nexus 아이디의 비밀번호이다.

 

2. <mirros>

<id> 에는 위에 생성한 id를 입력한다

<name> 은 저장소의 설명이다.

<url> 에는 위에서 생성한 Offline Nexus Server의 maven2 (proxy) URL을 입력하면 된다.

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">


 <servers>
    <server>
      <id>nexus</id>
      <username> </username>
      <password> </password>
    </server>
  
  </servers>

  <mirrors>
    <mirror>
      <id>nexus</id>
      <name>nexus</name>
      <url>http://주소:8081/repository/home/</url>
      <mirrorOf>*</mirrorOf>
    </mirror>
  </mirrors>

</settings>

 

설정 후 프로젝트에 Maven Dependency를 추가하거나 Jenkins 빌드를 하게 되면 자동으로 Nexus에 라이브러리들이 업로드되어 Nexus Repository를 사용할 수 있는 것을 확인할 수 있다.

 

끝으로..

2가지 방법 중 하나를 선택해 적절히 사용하면 될 것 같다.

반응형
반응형

1. 이클립스 삭제 후 재설치 시 발생하는 에러

 - ERROR: org.eclipse.equinox.p2.engine code=4 An error occurred during the org.eclipse.equinox.internal.p2.engine.phases.CheckTrust phase.

 

내 문서의 .eclipse, .m2, .p2 폴더 삭제

반응형



2. 프로젝트 선택 시 발생하는 에러

- please choose another workspace as

 

해당 프로젝트의 metadata폴더 삭제

반응형
  1. dd 2021.09.22 01:20

    감사합니다

  2. 지나가는나그네 2022.08.22 15:43

    도움되었습니다. 고맙습니다.

반응형

윈도우 환경에선 아래의 주소에서 .zip 또는 .msi 파일을 다운받아 설치 가능하다. 참고로 64비트만 지원한다고 한다.

https://github.com/MicrosoftArchive/redis/releases

 

MicrosoftArchive/redis

Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes - MicrosoftArchive/redis

github.com

.msi 로 설치할 경우 

C:\Program Files\Redis 이 경로에 설치가 되며

redis-sever.exe 로 서버 실행이 가능하며 , redis-cli.exe로 클라이언트 실행이 가능하다.

.msi 로 설치 하면 바로 redis 서버가 실행이 되므로 본인이 확인하고 싶다면

관리자 권한 cmd로 들어가

net stop redis 명령어를 입력해 redis를 멈춘 뒤 redis-server.exe로 다 시실행하면 된다.

 

아주 간단한 명령어만 살펴본다.

>SET keyname "hello"
OK
>GET keyname
"hello"

set 을 통해 key와 value를 입력할 수 있고

get 을 통해 key의 value를 조회할 수 있다.

 

>TTL keyname
(integer) -1

TTL을 통해 key의 만료시간을 알 수 있다.

-1은 기한이 없는 것을 말하고 밀리초 단위로 반환한다.

 

>DEL keyname
(integer) 1

DEL 명령어를 통해 key를 삭제할 수 있고 삭제한 키의 개수를 반환한다.

 

>SET keyname "hello"
OK
>SET keyname2 "hello2"
> keys *
1) "keyname"
2) "keyname2"

keys pattern

*는 모든 키들 검색

keys 명렁어를 통해 모든 key들 또는 검색한 key들을 알 수 있으나, key가 많아지면 성능이 저하될 수 있으므로 현재 배포 중인 서비스에서는 사용하지 않는다.

(scan이라는 명령어를 사용함)

 

반응형
반응형

 

https://www.acmicpc.net/problem/12865

 

12865번: 평범한 배낭

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)가 주어진다. 입력으로 주어지는 모든 수는 정수이다.

www.acmicpc.net

 

Knapsack 알고리즘을 사용하면 풀리는 문제이다.

최근에 알고리즘 문제 풀이에 취미가 생겨 문제를 열심히 푸는 중인데, Knapsack 알고리즘을 봐도 이해가 안되어

나름 내 방식대로 이해하고 풀다 보니 Knapsack알고리즘과 똑같이 나왔다 ㄷㄷ.

 

주어진 개수 = n

주어진 무게 = weight

주어진 무게의 가치 = value

Knapsack 알고리즘은 전체 무게가 weight(주어진 무게)를 넘지 않도록 n 번째까지 항목 중에서 얻어진 최고 이익을

저장하여 Dynamic Programing으로 푸는 방식이다.

처음에 이게 무슨말인지 이해가 안되어 이해를 포기하고 그냥 내 생각대로 해보니 Knapsack알고리즘이 나왔는 데,

이 글 또한 그러한 사람들을 위해 작성 또는 내가 다시보려고 작성한 글이다.

 

문제에 나와있는 무게와 가치

6 13

4 8

3 6

5 12

말고

아래의 가치로 계산해보고 n(주어진 개수)=5 , WEIGHT(주어진 무게의 값)=15 라고 하자

weight value
1 1
2 2
3 3
4 4
5 5

 

5*15 로 2차원 배열을 잡는다. 실제로 생성할 땐 dp[n+1][value+1] 로 생성하자 dp[0][0~15]을 써야하기 때문.

또한. 값을 [1][1] 부터 집어넣자.

 

첫 번째 항목인

weight=1과 value=1을 먼저 계산한다.

 

weight=1과 주어진 무게의값 WEIGHT(15)까지 계산을 한다

계산은 각 열의 무게와 weight=1을 빼서 0보다 클경우 value를 집어 넣고

만약 작을 경우 그 이전의 값(바로 위의 행)을 집어넣는다. 그 이전의 값이란 것은 두번째 또는 세번째 항목부터 이해가 될 것이다.

 

현재 weight=1이고 첫 번째 열의 무게는 1이다 1-1>=0 이므로 1을 넣는다.

현재 weight=1이고 두 번째 열의 무게는 2이다 2-1>=0 이므로 1을 넣는다.

이런식으로 첫 번째 항목을 채운다

 

만약 첫 번째 항목의 weight=5라면 첫 번째 열에서는 1-5 >=0 이 아니므로 0을 넣는 데, 사실 0이라기보단 그 이전의 값(바로 위의 행)인 dp[0][1]값을 넣는 것이다. 두번째 또는 세번째 항목부터 이해가 될 것이다.

(행은 아이템 순번, 열은 무게)

두 번째 항목은 weight=2이고 value=2이다

 

현재 weight=2이고 첫 번째 열의 무게는 1이다 1-2>=0 이 아니다. 따라서 이 전의 값(바로 위의 행)을 넣어야한다.

이전의 값(바로 위의 행)은 dp[1][1]값인데 이는 즉, dp[n-1][j] 정도로 볼 수 있다.

 

현재 weight=2이고 두 번째 열의 무게는 2이다 2-2=>0 이므로 첫 번째 항목처럼 2를 넣는다라고 생각할 수 있지만

아니라 이전(바로 위의 행)의 값과 값을 비교해야한다.

이전(바로 위의 행)의 값은 1이고 현재 나의 값은 2이다 2가 더 크므로 2를넣는다.

 

현재 weight=2이고 세 번째 열의 무게는 3이다 3-2>=0 이고 3-2=1이다. 이제 남은 1의 값을 활용해야 한다.

이전(바로 위의 행)의 열을 사용한다. 

3-2=1 이기 때문에 이전 값(바로 위의 행)의 열은 1,1 -> dp[1][1]이다

현재 weight는 2이며, value=2이고 현재 열은 세 번째 열이다. 2, 3 -> dp[2][3]

현재 열은 이전 값(바로 위의 행)의 1번열의 값 + 현재 값 -> dp[2][3] = dp[1][1]+value -> dp[2][3]=1+2=3

dp[2][3]=3이란 것을 알 수 있다.

현재 weight=2일 때 세 번째 열의 무게가 3이라는 것을 알게 되었으면 이제 또 이전의 값(바로 위의 행)과 비교를 해야한다. 바로 위의행 dp[1][3]=1 이고 현재 dp[2][3]은 3이라는 것을 알고 3이 더크므로 3을 완전히 집어 넣는다.

 

이로써 규칙은

1. 먼저 그 열의 무게와 현재 항목의 무게를 빼고 무게가 0보다 큰지 확인한다. 

2. 0보다 작다면 이전의 값(바로 위의 행)값을 넣는다.

3. 0보다 크다면 현재 열의 무게와 현재 항목의 무게를 뺀 값을 더 한다.

더하는데 빼서 나온 값은 그 이전의 값(바로 위의 행에서 뺀 값의 열번째) 와 현재 항목의 가치를 더한다.

4. 값을 더했다면 이전의 값(바로 위의 행)의 값과 비교를 해 더 큰 값을 완전히 집어 넣는다.

 

이렇게 해서 두번째도 쭉 집어넣는다.

 

세 번째 항목은 weight=3이고 value=3이다

 

현재 weight=3이고 첫 번째 열의 무게는 1이다 1-3>=0 이 아니다. 따라서 이 전의 값(바로 위의 행)을 넣어야한다.

이전의 값(바로 위의 행)은 dp[2][1]값이다. 따라서 1을 넣는다

 

현재 weight=3이고 두 번째 열의 무게는 2이다 2-3>=0 이 아니다. 따라서 이 전의 값(바로 위의 행)을 넣어야한다.

이전의 값(바로 위의 행)은 dp[2][2]값이다. 따라서 2을 넣는다

 

현재 weight=3이고 세 번째 열의 무게는 3이다 3-3>=0 이다. 따라서 규칙대로 행동한다.

규칙의 3번인 0보다 크기 때문에 현재 열의 무게와 현재 항목의 무게를 뺀값을 더하는 데 3-3=0이다.

그리고 이 0의 값은 그 이전의 값( 바로 위의 행에서 뺀값의 열번째)는 dp[2][0]인데 이는 0이다.(dp[n+1][value+1] 로 잡았고 값을 [1][1]부터 잡았기때문에 0번쨰는 0으로 초기화 해준다.)

어쨋든 dp[2][0] + 현재 항목의 가치 -> dp[2][0]+3 -> 0+3 =3

그리고 규칙의 4번으로 와서 3과 그 이전의 값(바로 위의 행) dp[2][3]의 값과 비교해서 큰 값을 넣어준다. 둘이 값이 3으로 같기 때문에 3을 넣어준다.

 

현재 weight=4이고 네 번째 열의 무게는 4이다 4-3>=0 이다. 따라서 규칙대로 행동한다

규칙의 3번인 0보다 크기 때문에 현재 열의 무게와 현재 항목의 무게를 뺀값을 더하는 데 4-3=1이다.

그리고 이 1의 값은 그 이전의 값( 바로 위의 행에서 뺀값의 열번째)는 dp[2][1]인데 이는 1이다.

어쨋든 dp[2][1] + 현재 항목의 가치 -> dp[2][1]+3 -> 1+3 =4

그리고 규칙의 4번으로 와서 4와 그 이전의 값(바로 위의 행) dp[2][4]의 값과 비교해서 큰 값을 넣어준다. 

dp[2][4]=3이고 현재는 4이기 때문에 4가 더크므로 4를 넣어준다.

 

이런식으로 하다보면 아래의 값들이 나온다

 

 

이게 Knapsack알고리즘인데 이를 알고리즘적으로 풀이하면

dp[i][j] = Math.max(dp[i - 1][j], value[i] + dp[i - 1][j - weight[i]]);

이렇게 된다.

 

BOJ 12865 평범한 배낭 문제의 최종 소스는 아래와 같다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		String T;

		T = br.readLine();
		st = new StringTokenizer(T);

		int N = Integer.parseInt(st.nextToken());
		int K = Integer.parseInt(st.nextToken());

		int weight[] = new int[N + 1];
		int value[] = new int[K + 1];
		int dp[][] = new int[N + 1][K + 1];
		for (int i = 1; i < N + 1; i++) {
			T = br.readLine();
			st = new StringTokenizer(T);
			weight[i] = Integer.parseInt(st.nextToken());
			value[i] = Integer.parseInt(st.nextToken());
		}

		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= K; j++) {
				if (j - weight[i] >= 0) {
					dp[i][j] = Math.max(dp[i - 1][j], value[i] + dp[i - 1][j - weight[i]]);

				} else {
					dp[i][j] = dp[i - 1][j];
				}
			}
		}
		System.out.println(dp[N][K]);
	}
}

반응형
반응형


리눅스에서 ssh key로 접속하는 방법이다. 

이 글은 현재 윈도우에서 ssh key가 생성되어있다는 가정하에 쓴 글이다.


1. 서버에서 .ssh 폴더가 있는지 확인한다. 

ls ~/.ssh

없다면 만들어 준다.

mkdir .ssh


2. 만들었으면 이제 현재 윈도우에서 가지고있는 public_key를 등록해주어야 한다.

등록하기 위해선 아래처럼 authorized_keys를 생성하여 등록한다.

cd .ssh
vim authorized_keys


3. 등록하였으면 이제 putty 또는 xshell로 접속할 때 ssh로 접근하면 자동으로 인식한다.


4. 이제 ssh키로만 접속할 수 있도록 비밀번호 접근은 못하게 막을 것이다.

관리자로 접속하여 아래의 명령어를 입력한다.


sudo -s
vim /etc/ssh/sshd_config


5. 아래 사진에 나와있는 PasswordAuthentication 을 찾아 no로 변경한다.

처음에는 주석처리로 되어있고 yes로 되어있을 것이다.




6. 이제 이렇게 하면 패스워드로 접근할 경우 아래의 사진처럼 비활성화가 되며 자동으로 ssh로만 접근할 수 있게 한다.(xhell의 경우)




반응형
반응형

apache 에는 ab 라고 하는 벤치마크 툴이 있으며, 이 ab를 이용하면 서버의 성능을 테스트해 볼 수 있다.
test@:~$ sudo apt-get update 
test@:~$ sudo apt-get install apache2-utils

ex) test@:~$ ab -n 100 -c 1 http://서버주소/
※ 주의 요청 주소 앞에 항상 http와, 서버주소 뒤에는 항상 / 를 꼭 적어주어야 한다.

위 예시는 요청을 100번 주고 동시접속을 1번 하곘다는 예시이다. 도중에 ctrl+c를 통해 종료시킬 수도 있다.


반응형

+ Recent posts