반응형
반응형

ionic app이 initialize되는 과정에서 npm install만 하기 때문에, 발생하는 문제이다.


app 폴더에 가서 package.json파일을 열어보면 아래와 같이 "devDependencies"라고 적혀있는 부분이 별도로 존재하는데, npm install 명령어로 설치 시에 얘네들이 빠져서 설치가 되버림.

{
  "name": "helloIonic",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "4.4.3",
    "@angular/compiler": "4.4.3",
    "@angular/compiler-cli": "4.4.3",
    "@angular/core": "4.4.3",
    "@angular/forms": "4.4.3",
    "@angular/http": "4.4.3",
    "@angular/platform-browser": "4.4.3",
    "@angular/platform-browser-dynamic": "4.4.3",
    "@ionic-native/core": "4.3.0",
    "@ionic-native/splash-screen": "4.3.0",
    "@ionic-native/status-bar": "4.3.0",
    "@ionic/storage": "2.0.1",
    "ionic-angular": "3.7.1",
    "ionicons": "3.0.0",
    "rxjs": "5.4.3",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.18"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.0.0",
    "typescript": "2.3.4"
  },
  "description": "An Ionic project"
}


아래 명령어를 입력하여, devDependencies에 있는 모듈들도 설치를 해주면 해결이 된다.

$ npm install --only=dev


매번 저렇게 해주는 게 귀찮을 수 있으니, 프로젝트를 자주 만들어야 한다면, 아예 글로벌로 설치해버리는 것도 답이다.

반응형
,
반응형

JDK9가 드디어 정식 릴리즈 됨.

http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html


다운받아서 설치하고 환경변수를 잡은 뒤 STS를 실행했으나, 아래와 같은 에러가 발생함.

eclipse.buildId=3.9.0.201707061823-RELEASE-e47
java.version=9
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=ko_KR
Framework arguments:  -product org.springsource.sts.ide
Command-line arguments:  -os win32 -ws win32 -arch x86_64 -product org.springsource.sts.ide

!ENTRY org.eclipse.osgi 4 0 2017-09-22 09:53:56.501
!MESSAGE Application error
!STACK 1
org.eclipse.e4.core.di.InjectionException: java.lang.NoClassDefFoundError: javax/annotation/PostConstruct
	at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:410)
	at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:318)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:162)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createDefaultHeadlessContext(E4Application.java:491)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createDefaultContext(E4Application.java:505)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createE4Workbench(E4Application.java:204)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:614)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:594)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:148)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:151)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1499)
Caused by: java.lang.NoClassDefFoundError: javax/annotation/PostConstruct
	at org.eclipse.e4.core.internal.di.InjectorImpl.inject(InjectorImpl.java:124)
	at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:399)
	... 22 more
Caused by: java.lang.ClassNotFoundException: javax.annotation.PostConstruct cannot be found by org.eclipse.e4.core.di_1.6.100.v20170421-1418
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:433)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:395)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:387)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:150)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
	... 24 more

!ENTRY org.eclipse.e4.ui.workbench 4 0 2017-09-22 09:53:56.515
!MESSAGE FrameworkEvent ERROR
!STACK 0
java.lang.NoClassDefFoundError: javax/annotation/PreDestroy
	at org.eclipse.e4.core.internal.di.InjectorImpl.disposed(InjectorImpl.java:450)
	at org.eclipse.e4.core.internal.di.Requestor.disposed(Requestor.java:156)
	at org.eclipse.e4.core.internal.contexts.ContextObjectSupplier$ContextInjectionListener.update(ContextObjectSupplier.java:78)
	at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:111)
	at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.handleInvalid(TrackableComputationExt.java:74)
	at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:178)
	at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.dispose(EclipseContextOSGi.java:99)
	at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.bundleChanged(EclipseContextOSGi.java:141)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:908)
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
	at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:213)
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:120)
	at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:112)
	at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:168)
	at org.eclipse.osgi.container.Module.publishEvent(Module.java:476)
	at org.eclipse.osgi.container.Module.doStop(Module.java:634)
	at org.eclipse.osgi.container.Module.stop(Module.java:498)
	at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:202)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:165)
	at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.ClassNotFoundException: javax.annotation.PreDestroy cannot be found by org.eclipse.e4.core.di_1.6.100.v20170421-1418
	at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:433)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:395)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:387)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:150)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
	... 21 more


해결책은 eclipse.ini 또는 sts.ini 파일을 열어서 -vmargs 하위에 아래와 같은 argument를 넣어주면 된다.

-vmargs
--add-modules=java.se.ee


이렇게까지 했는데도 동일하게 에러가 발생한다면, IDE자체에서 JDK9를 싫어하는 것이므로, Eclipse Oxygen 이상의 버전으로 올려야 한다.


그런데... IDE 정상 구동까지는 잘되지만, IDE 내부에서 Compiler 지원을 JDK8까지밖에 하지 않기 때문에, Eclipse Marketplace에 가서 별도로 Java 9 Support (BETA) for Oxygen 4.7 플러그인을 설치해서 사용해야 한다. 


본인은 BETA!!라고 써있는 것을 보고, 억지로 맞춰서 쓰는 느낌이라 그냥 새로운 IDE 배포를 기다리기로 했다; 

반응형
,
반응형

무료한 삶을 달래기위해 / 요즘 대세라는 Actor모델을 경험하기 위해 Scala를 파보기로 했는데, scala.io.StdIn.readLine 예제를 실행하던 중, io패키지에는 StdIn이라는 애가 없다는 에러가 발생하였다.


구글링을 해보니, 사용하는 스칼라 버전이 낮아서 그런거라고..

그래서 sbt 콘솔에서 scalaVersion을 변경하는 방법을 찾아서 아래와 같이 현 포스팅 기준 최신버전인 2.12.3으로 적용해보았다.

> set scalaVersion := "2.12.3"
> session save


session save를 하지 않으면, 매번 저짓을 해주어야 한다.

session save를 해주면 build.sbt 파일에 scalaVersion이 저장되어, 이후에는 동일하게 이용할 수 있다.

반응형
,
반응형

컴파일해서 설치한 Apache2 (정확한 버전은 2.2.17)이 설치되어 있는, 머신의 OS를 Ubuntu 12.04에서 14.04로 업그레이드 할 일이 생겨서 OS에서 제공하는 커맨드로 OS 업그레이드 후에는 문제가 없었지만, 재부팅 이후에 httpd 데몬을 띄우려고 하면, 아래와 같은 에러 메시지가 발생하였다.

[emerg] (22)Invalid argument: Couldn't set permissions on cross-process lock; check User and Group directives


12.04에서는 아래와 같이 유저 / 그룹이 설정 되어 있었는데 잘 동작을 했었지만, 14.04에서는 계정정책이 뭔가 바뀐 듯 하다.

# httpd.conf
...
User nobody
Group #-1
...


정확한 원인은 모르겠지만, nobody라는 계정이 httpd 데몬을 띄우는데 뭔가 권한이 부족한 것으로 판단하여, 새로운 그룹과 유저를 생성 한 후, User와 Group을 변경하니 해결되었다.


반응형
,
반응형

JIRA에서 사용자 관리를 모두 하게 하기 위해, JIRA에 사용자 서버를 생성하고, Confluence에서 동기화를 하는 방식으로 사용을 했더니, 기본 동기화 시간이 3600초라서 Confluence 사용만 하고 싶은 유저에게는 문제가 많았다.


동기화 시간을 Web UI에서 조절은 못하게 되어있기 때문에, DB에 직접 붙어서 수정을 해야 한다.

SELECT attribute_value 
FROM cwd_directory_attribute 
WHERE attribute_name = 'directory.cache.synchronise.interval';


위 쿼리를 날려서, 현재 시간을 확인하고 알맞게 조절 후 Confluence를 재시작해주면 반영된다.

반응형
,
반응형

Atlassian 제품들은 기본적으로, 로그인에 여러번 실패하면, Captcha 문자를 추가로 입력받게끔 되어있다.


근데 Hosting으로 운영하는 경우 Confluence에서 Captcha가 보이지 않는 현상이 발생하였다. Jira는 문제없음.


이런 현상이 있는 경우, 아래와 같은 시스템 파라미터를 {Install Directory}/bin/setenv.sh에 추가해주고, Confluene를 재시작하면 해결된다.

...
CATALINA_OPTS="-Dfile.encoding=UTF-8"
...
반응형
,
반응형

100GB정도 사용하는 Cloud Jira에서 Host Jira로 Migration 계획을 세워서 진행중인데, Cloud Jira는 북미서버고 Host Jira는 한국에 있다보니, 백업 -> 다운로드 -> 업로드 과정이 하루에 넘는 불상사가 일어났다.


결국 주말 이틀에 평일 하루까지껴서 작업이 계획되었는데, 다운로드 -> 업로드 과정을 없애고 Host서버에서 직접 다운로드 받으면, 시간이 몇 배는 줄어들 것 같아서, Atlassian에 선 문의를 했더니, Bitbucket URL을 하나 알려주며, 본인들은 그 스크립트로 자동으로 백업하고 다운로드 받으니 참고해서 다운로드 받아라! 라는 답변이 왔다.

(참고 링크 : https://bitbucket.org/atlassianlabs/automatic-cloud-backup)


소스 분석을 간단히 해보면 이렇다.


1. JIRA Rest API를 이용하여 인증을 하고, 로컬에 쿠키로 저장을 한다. (Curl 이용)

2. 로컬에 저장된 쿠키를 이용해서 백업을 뜬다. (인증정보가 담겨진 쿠키)

3. 백업을 뜨면서, 진행상황을 Rest API를 이용하여 수시로 체크하고, 완료되면 파일명을 추출하여, 로컬에 저장된 쿠키를 이용하여 다운로드 받는다. (Wget 이용)


그런데 내 환경에서는 이상하게 잘 동작을 하지 않아서, Curl이랑 Wget이랑 동시에 사용하다보니 발생하는 문제라고 판단을 하고,

인증과 다운로드 둘 다 Wget을 사용하도록, 아래와 같이 쉘을 만들어서 사용 했다.

#!/bin/bash

# 쿠키가 저장될 위치
COOKIE_FILE_LOCATION=jiracookie

# 사전에 있던 쿠키를 지운다.
rm -f $COOKIE_FILE_LOCATION

# 인증하고, 쿠키를 지정된 위치에 저장한다.
wget --save-cookies $COOKIE_FILE_LOCATION --keep-session-cookies --post-data '{"username":"Atlassian ID 입력", "password":"패스워드 입력"}' --header 'Content-Type: application/json' "https://JIRA인스턴스.atlassian.net/rest/auth/1/session" -O /dev/null

# 백업파일을 다운로드 받는다
wget --load-cookies $COOKIE_FILE_LOCATION -t 0 --retry-connrefused --show-progress "백업 URL" -O "저장할 위치"


이로써 PC에서 다운로드 받았다가, 원격에 업로드하는 미련한 짓은 안할 수 있게 되었고, 시간을 많이 절약하게 되었다. 

그나마 JIRA 인증 API를 제공하고 있어서 다행이지, 이마저 없었다면 답이 없었을 뻔했다.

반응형
,
반응형

JIRA같은 경우, WebUI에서 편리하게 변경이 가능한데,

Confluence는 WebUI에서 제공을 하지 않고, tomcat의 CATALINA_OPTS에 파라미터를 줘서 변경을 해주어야 한다.

(참고 링크 : https://confluence.atlassian.com/kb/setting-the-timezone-for-the-java-environment-841187402.html)


{Confluence가 설치된 폴더(홈 폴더 아님)}/bin/setenv.sh를 열어서 export CATALINA_OPTS라고 써있는 라인을 찾아서, 바로 위에다가 파라미터를 추가해주면 된다.

아래 예제에선 미국시간 기준으로 세팅을 한다. (위에 언급한 참고 링크에 보면 Confluence에서 지원하는 타임존 표가 있음)

...
CATALINA_OPTS="-Duser.timezone=America/Los_Angeles"
export CATALINA_OPTS
...


위와 같이 추가해준 후 Confluence를 재시작하면 반영된다.

Jira나 Confluence나 같은 회사에서 판매하는 제품인데 왜케 다름;;

반응형
,
반응형

클라우드에서 사용하던 Jira를 호스트 서버로 옮겨오게 되면서, Backup Manager에서 호스트 서버를 위한 백업을 제공하길래, 한 번에 될줄 알았는데, 거의 한 달째 Atlassian 고객센터와 씨름을 하며 주의할 점을 정리해본다.


[Cloud에서 주의할 점]

  1. 백업뜨기 전에, 무조건 re-index는 한 번 해준다.
    • (Cloud는 수시로 버전 업 및 버그 fix가 되기 때문에, 버그가 있던 버전에서 쌓였던 데이터는 key가 없는 등 문제가 많을 수 있음)
  2. 백업은 하루에 한 번만 뜰 수 있으니, 신중하게 백업한다.
    • (유지 기간은 일주일)
  3. 1년이상 열심히 사용한 경우, 백업에 걸리는 시간은 상상을 초월하므로, 업무 시간 마무리 직전에 걸어두는 것이 좋다. (아침에 보면 가끔 뻗어있기도 함;;)


[Host에서 주의할 점]

  1. Cloud에서 백업을 떠서 나온 zip파일엔, xml 2개와 avatar, attachment가 포함이 되어 있는데, 콘텐츠 내용 중 특수문자가 껴있었고, MySQL DB를 사용중이라면 특수문자를 넣을 수 없다는 에러가 발생한다.
  2. Cloud에서 가져온 데이터는 Full Restore(XML복원)만 지원하고, 프로젝트 가져오기 (Migration)는 불가능하다. (Atlassian Support의 답변)
  3. 백업 zip파일에 포함된 attachments폴더는 압축을 풀어서 따로 JIRA HOME/import/attachments폴더에 넣어주어야 한다. (안그러면 파일 다 깨짐)
  4. 가끔 3번처럼 했는데도 깨지는 경우는, 압축 파일에 들어있던 attachment, avatar에 들어있는 파일을 JIRA HOME/data 경로에 수동으로 넣어주면 원상복귀됨.
  5. 모든 과정을 거쳐 복원에 성공하였다면, 계정 관리를 조금 해야 한다. Cloud의 경우 계정 패스워드 관리가 Atlassian에서 통합관리 되기 때문에, 백업 간 계정 정보만 포함되고, sysadmin을 제외한 모든 계정이 DB에 (nopass)로 들어가게 된다.
    • 아래와 같이 SQL문으로 패스워드 보정을 해주자. (admin으로 들어가게되며, jira를 재시작해주어야 반영될 수도 있다.)
    • UPDATE cwd_user
      SET CREDENTIAL = '{PKCS5S2}8WEZjkCbLWysbcbZ5PRgMbdJgJOhkzRT3y1jxOqke2z1Zr79q8ypugFQEYaMoIZt'
      WHERE user_name = 'sysadmin';
      

비싼 돈 주고 사용하는 제품인데.. (뭐 내 돈은 아니지만;;)
마이그레이션 하기가 너무 힘든 것 같다.

말이 마이그레이션이지 그냥 데이터 가져다가 엎어치우는 것 밖에 안되고, 진짜 마이그레이션을 하려면, 기존에 쓰던 데이터를 백업떠서 다른 곳에 모셔다 놓고, Cloud데이터를 Full Restore(XML복원)한 후, 원래 있던 데이터를 프로젝트 가져오기로 넣어주어야 하는 것 같긴한데, 뭐 이리 복잡한지;;


반응형
,
반응형

Cloud에 있는 데이터를 Hosting된 Confluence로 땡겨올 일이 있었는데, Cloud에서 백업을 뜬 후, Hosting Server에서 Restore를 하니 한글이 전부 깨지는 현상이 발견되었다. (현재 포스팅 당시 최신버전 기준 6.3.1에서 발생하였으며, MySQL을 사용)


Confluence같은 경우 MySQL의 jdbc string에 인코딩에 대한 고려가 되어 있지 않아 발생하는 현상으로, Confluence Home 폴더에 있는 confluence.cfg.xml를 열어서 jdbc string에 유니코드(useUnicode) 및 인코딩 옵션(characterEncoding)을 utf-8로 추가해주고, 재시작해주면 해결된다.

...
    <properties>
     ...
         <property name="hibernate.connection.url">jdbc:mysql://localhost/confluencedb?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf8</property>
     ...
    </properties>
...


기본 DB가 H2 DB이기 때문에, 외부 DB를 사용하는 경우에 대한 고려가 잘 안되어 있는 것 같고, MySQL 뿐만 아니라 다른 DB도 비슷하게 발생할 것으로 예상된다.

반응형
,
반응형