Spring XML vs Annotation

스프링은 크게 3가지 방식의 설정을 할 수 있다. DB, 빈, 기타등등 스프링 관련 설정들 말이다.

XML             MIXED           ANNOTATION
<---------------------------------------->

그럼 ARABOJA.

XML

스프링의 전통적인 설정 방법이며, 구성을 포함해 모든 자바 빈들을 XML에 정의한다.

  • 원하는 빈만 XML에 담궈 놓고 클래스 목록을 한 번에 볼 수 있다.
  • 필요 시 특정 빈만 주석처리 하는 등 활성화/비활성화가 용이하다.
  • 빈 생성 시 반드시 XML에 정의해줘야 하며, 그렇지 않으면 일반 클래스가 되버린다.
  • 신규 작성시에는 많은 공수시간이 요구되지만, 유지보수 시 부담이 적다.

매우 큰 프로젝트일 경우, 여러 스프링 프로젝트를 운영할 경우 XML 방식을 선호하는 게 이 때문이다.
어노테이션을 쓰게 되면 클래스가 많을 수록 스캔 시간이 길어지지만, 완전 XML에서는 정의된 빈만 스캔하기 때문에 그럴 걱정이 없다.

Mixed

현재 대부분 스프링 프로젝트에서 사용하는 방법이며, 전자정부에서도 기본적으로 이 설정으로 시작하도록 유도하고 있고,
가장 흔한 방식으로, 기본 구성은 XML, 빈 등 가장 많이 차지하는 구성을 어노테이션으로 정의한다.

  • 기본적인 구성 설정(DB, 웹의 경우 Resolver 등)은 XML에 정의한다.
  • 나머지 빈은 패키지 범위를 정해놓고 어노테이션에 맡긴다 (annotation-driven)
  • 이후 빈 생성은 어노테이션만 정의하면 바로 클래스 작성 후 배포할 수 있다.
  • 신규 작성 시 XML보다 공수 시간은 줄어들지만, 수정 및 비활성화가 필요할 경우 재컴파일하여 배포해야 한다.

사실 완전 XML에 비해서 크게 단점으로 작용할 만한 요소는 없다. 대부분 많이 바뀌는 게 바로 기본 구성 성정인 DB나 메시지 정의들이니.
대신 스프링 앱 시작 시 스캔을 시작한다. 여기서 패키지 범위 내 클래스가 많을 수록 스캔 시간은 어쩔 수 없이 길어지게 된다.

Annotation

아예 XML을 쓰지 않고 모든 구성과 빈을 자바에 맡겨놓는 방식이다.

  • 기본 구성 설정부터 @Configuration 어노테이션을 정의한 기본적 클래스로 설정할 수 있다.
  • 이 때 가장 강점은, Strong Type에 가장 부합해 빈 클래스의 무결성을 가장 빨리 검사하고 보장할 수 있다.
  • Java 기반 구성 설정은 Spring 3.0부터 지원하기 때문에 이하 버전에서는 할 수 없다.
  • 자바만 쓰기 때문에 개발생산속도는 가장 빠르지만, 변경 시마다 재컴파일 해야 하기 때문에 유지보수 속도는 매우 떨어진다.

JRebel 같이 실시간 핫스왑으로 개발하거나, 이제 아예 Spring Boot 내부 기능을 통해 재시작 없이 개발할 수 있는 기술의 발달로
더이상 완전한 어노테이션 개발의 문제점은 사라진 상태. 하지만 구성 설정부터 빈까지 모두 스캔해야 하기 때문에 시작속도는 당연히 더 느린 편.
게다가 사소한 수정조차 재컴파일을 거쳐야 하기 때문에 대응속도가 빠르게 요구되는 프로젝트에서는 어려움이 따를 수 있다.

공통

역시 정적 문자열 정의는 properties 가 진리. 텍스트 바꾸고 배포만 하면 되니까.
Spring 4.0 부터는 yml 방식의 구성 또는 메시지도 지원한다고 하니, 좀 더 읽기 쉽고 구조적 구성을 원하면 이거 쓰는것도 나쁘진 않다.

결론

  • 대규모 프로젝트이거나 분산 프로젝트인가? 신규개발은 어렵지만 유지보수가 용이한 XML 설정을 사용하라
  • 별다른 특이사항이 없을 경우 가장 흔히 사용하는 Mixed 방식은 스프링에 접근하기 딱좋다.
  • 가볍고 빠른 생산성으로 소규모 서비스를 원한다면, Spring Boot를 통한 Annotation 기반이 도움이 될 것이다.
  • 프로토타입이나 목업인가? 데모 앱이 필요한가? 그러면 제발 스프링 쓰지마 병시나.

끗.

composite / 2017년 9월 12일 / Piss Development / 0 Comments

자바스크립트 콜백함수 관리 아이디어

Vue를 공부하다가 갑자기 생각나서 글 싸지른다.

자스에서는 가변인자 값은 가져올 수 있는데, 인자명은 못가져온다.
일단 자스에서 개체 까는 API인 ReflectProxy가 있는데,
대체적으로 개체 속성과 생성 관리를 담당할 뿐이다. 물론 유용하긴 하지만.
함수 내에서도 인자를 까는 메소드도 없고, API도 없다.
함수 내 arguments 개체 또한 인자값을 가져올 뿐이고.
최신인 ES2017에서도 이를 대응할 API는 없다…

물론 불가능한 건 아니다. 한가지 확실한 점은, 네이티브 함수(예: Object, Array 등)만 아니면
Function.prototype.toString() 메소드를 실행 시 함수 전체가 까발려진다.
거기서 함수명과 인자, 함수 내용이 모두 나오게 된다. 그 어떤 브라우저든 간에.

그래서 이를 이용해 인자 이름을 가져올 수 있는 방법이 있다.
출처: How to get function parameter names/values dynamically?

var STRIP_COMMENTS = var STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,\)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,\)]*))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
function getParamNames(func) {
  var fnStr = func.toString().replace(STRIP_COMMENTS, '');
  var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
  if(result === null)
     result = [];
  return result;
}

그러하다. 함수 내용을 파싱해서 코멘트 제거하고 인자명만 쏙 가져올 수 있다.

getParamNames(getParamNames) // returns ['func']
getParamNames(function (a,b,c,d){}) // returns ['a','b','c','d']
getParamNames(function (a,/*b,c,*/d){}) // returns ['a','d']
getParamNames(function (){}) // returns []
getParamNames(function (a=4*(5/3), b) {}) // returns ['a']

완벽하게 대응이 되는 것 같진 않아보여도 대부분 케이스에 대응이 가능하다.
굳이 대응 안되는 케이스가 있다면… 아무래도 화살함수(Arrow Function)가 되겠는데,
(a=>b).toString() 호출하면 크롬의 경우 "a=>b" 이렇게 나온다…
가장 쉬운 대응 방법은 babel로 강제 변환해서 써버리는 것이다… asyncawait 나오면 묵념…

추가로 명명된 가변인자(function(...args))도 대응할 수 없다. 근데 일반 가변인자처럼 대응이 더 어렵다. 패스.

어쨌든, 이제 내가 말하고자 하는 아이디어 예제를 내겠다.
document sandbox 예제다. 함수인자 까는 함수는 위에 것을 그대로 활용한다.

function sandbox(func){
    var anames = getParamNames(func);
    anames = anames.map(function(method){
        return function(){ return document[method].apply(document, arguments); };
    });
    return func.apply(window, anames);
}

sandbox(function(createElement, getElementById, createTextNode){
    var a, b;
    a = createElement('p');
    a.innerHTML = "hello world!";
    document.body.appendChild(a);
    b = getElementById('out');
    b.appendChild(createTextNode('YAY~!'));
});

참고로 document 객체의 모든 요소는 참조를 허용하지 않기 때문에, 어쩔 수 없이 함수로 감싸 꼼수를 썼다.
실행 결과는 jsfiddle 에서 볼 수 있다.
만약 Array.prototype.map 메소드가 실행되지 않는 구닥다리 브라우저의 경우는… jQuery.map() 으로 알아서 수정해서 테스트 해보라.

뭐 내가 말하려는 게 대충 이런 식이다. 이런 샌드박스형 콜백을 활용하면 더 유연한 콜백 대응이 가능할 거라 믿기 때문이다.
근데 왜 ECMA에서는 인자명에 관심을 가지지 않는걸까? 의문을 가지며 이것으로 마치도록 하겠다.

끗.

composite / 2017년 9월 7일 / Piss Development / 0 Comments

웹 사이트 프로젝트(Web Site Project)와 웹 응용프로그램 프로젝트(Web Application Project)의 차이

혹시 알고 넘어가는지 모르겠지만, 닷넷에서 웹 앱을 만드는 데 2가지 프로젝트 형식이 있다.
바로 웹 사이트 프로젝트와 웹 앱 프로젝트인데, 이 둘의 차이점은 간단하게 짚어보는 시간을 갖겠다.

웹 사이트 프로젝트(Web Site Project)

타 언어 웹 사이트로 치자면, ASP, PHP, 일반 JSP 페이지를 만드는 꼴이라고 보면 된다. VS 2005부터 소개되었다.
폴더 루트를 잡고, 거기에 페이지와 리소스, 백엔드 코드를 특정 폴더인 App_Code 에 넣는 방식이다.
프로젝트 생성이 빠르고, 단순하다. 그리고 프로젝트 파일도 생성하지 않는다. 그럼 구성 설정은 어디다가 저장하냐?
바로 솔루션 파일과 구성 설정 파일인 web.config에다 저장한다. 각기 역할은 당연히 틀리고 대부분 설정은 web.config에다 저장한다.
개발만 하고 폴더 그대로 IIS에 배포할 수 있다. 사이트 설정만 하면 작동을 시작한다. 나머진 IIS가 파싱하여,
각 페이지마다 변경 사항이 생길 때마다 컴파일 후, 각기 페이지마다 DLL 파일이 생성되어 페이지를 렌더링 한다.
그렇기 때문에 빠른 배포와 수정이 장점으로 통한다. 하지만 이런 특성이 단점으로 작용하는데,
이렇게 될 경우 각 페이지 내에서 클래스 네임 중복을 확인하지 않는다, IIS는 그걸 인식하지 않고 파일마다 컴파일 하기 때문에,
클래스 이름이 중복되더라도 다른 이름으로 클래스를 생성 후 컴파일하기 때문에 참조 등에서 어떤 문제가 나올 지 파악이 어렵다.
이런 불상사를 예방하기 위해 “게시” 기능이 있다. 게시할 때 “미리 컴파일(Precompiled)” 개념이 있으며, 최적화하고 정리하여 깔끔한 백엔드와 성능을 보장받을 수 있다.

이럴 때 웹 사이트를 쓰면 좋다. 프로토타입, 시연, 데모, 단순한 소개 사이트.

웹 응용프로그램 프로젝트(Web Application Project)

웹 앱을 아예 응용 프로그램처럼 프로그램 단위로 관리하고 운영하는 프로젝트로, VS2005 SP1부터 내장되었으며, 이런 개념은 이미 VS 2003부터 도입이 되었다.
폴더 루트에 .csproj.vbproj 등의 프로젝트 파일이 생기며, 프론트엔드 코드와 백엔드 코드를 아무 곳이나 넣을 수 있으며, 예외 설정 등이 가능하여
관리적 측면에서 아주 유리한 프로젝트이다. 왠만한 구성 설정은 프로젝트 파일에 저장하기 때문에 web.config 파일엔 서버 운영에 필수적인 구성 설정밖에 없는 것도 장점이다.
단점이라면, 매 수정시마다 빌드(컴파일)해줘야 하고, 당연히 컴파일된 상태로 배포를 해야 한다. 물론 아예 “게시”하여 배포할 수 있다.
빌드 후에는 모든 백엔드 코드가 하나의 DLL에 담게 된다. 배포 방식이야 웹 사이트처럼 폴더째로 담으면 땡이지만, 백엔드 코드를 DLL에서 바로 불러오기 때문에 성능 측면에서 이득이다.
또한 게시 기능을 통해 웹 사이트처럼 모든 페이지의 백엔드 코드까지 퉁쳐서 하나의 DLL로 담은 후 배포할 수 있기 때문에,
성능과 안정성 측면에서 당연히 가장 추천되는 웹 앱 프로젝트 방식이다.

이럴 때 웹 응용 프로그램을 쓰면 좋다. 웹 사이트에서 소개한 거 빼고 전부 다. 모든 서비스들 말이야.

결론?

참고로 ASP.NET Core 프로젝트는 웹 사이트 프로젝트가 아직 없다. 웹 앱 프로젝트 방식이다. ASP.NET 팀에서는 ASP.NET Core Web Pages 으로 만들고 있다.
닷넷 코어는 IIS 종속이 아니기 때문에 어떤 방식으로 배포하고 운영할 지는 모르겠으나, 어자피 정식 웹 앱을 만드는 데에는 웹 앱 프로젝트 만큼 관리가 좋은 건 없으니 그거 쓰자.
어자피 WebMatrix는 VS Code가 그 뒤를 계승 이미 끝났으니 신경 끄고.

composite / 2017년 8월 30일 / Piss Development / 0 Comments

WSL에서 리눅스 프로세스 관리하기

리눅스 프로세스 또한 윈도우 작업 관리자에서 관리할 수 있다.
물론 속성 확인 등 윈도우 특화 기능은 지원하지 않는다. 오로지 끝내기 뿐.

아이콘이 있을 리 없으니 흰 아이콘만 뜰 뿐이다.
그리고 Sysinternals 에서 제공하는 Process Explorer 에서도 볼 수 있다.

대체적으로 맨 아래로 내리나 보다.

다음으로는 서비스를 확인해 보도록 하겠다.

composite / 2017년 8월 25일 / Piss Development / 0 Comments

WSL(윈도우 내 리눅스) 에서 데몬 유지 및 sshd 서버 돌리기

먼저 WSL의 특징을 설명하겠다.
일단 리눅스기 때문에 백그라운드 서비스, 즉, 데몬도 존재하며, 똑같이 돌아간다.
하지만 윈도우에서 bash 프로세스가 하나도 없으면, 리눅스 서비스는 다 죽고 리눅스 전원이 꺼진 것이나 다름없다.
그래서 윈도우를 키자마자 리눅스 서비스를 돌리고 싶으면 윈도우 시작하자마자 bash 프로세스를 돌려야 한다.
이를 기초하여 SSH 서버 데몬을 돌림으로 리눅스의 기능을 윈도우 시작 때부터 유지하는 방법을 설명하도록 하겠다.
이를 잘 정리한 링크로부터 출처를 가져왔다.

How to run sshd as a windows service ? #612
How to run Ubuntu service on Windows (at startup)?

  1. 윈도우에서 bash 실행한다.
  2. sudo dpkg-reconfigure openssh-server 실행하여 SSH 호스트 재구성한다.
  3. sudo nano /etc/ssh/sshd_config 실행하여 SSH 설정 파일 편집에 들어간다.
  4. UsePrivilegeSeparation 항목을 찾아 옆에 yesno로 변경
    (이유는 UsePrivilegeSeparation 옵션은 chroot() 호출을 WSL에서 아직 지원하지 않기 때문)
  5. 비번으로 접속하고자 할 경우 PasswordAuthentication 항목을 찾아 (없으면 추가) yes로 세팅.
    (만약 없으면 SSH 접속할 경우 키 파일을 요구함. 유저 파일에 키를 생성하고 클라이언트도 가지고 있어야 함.)
  6. ctrl+O 단축키로 저장 후 ctrl+X 로 편집기를 빠져나간다.
  7. sudo visudo 실행하여 sudo 권한설정 파일을 편집한다.
  8. 적당한 줄을 찾아 $USER ALL = (root) NOPASSWD: /usr/sbin/sshd -D 문구를 추가한 후, $USER를 로그인 이름으로 바꾼다.
    (로그인 이름 알고싶으면 pwd ~/ 쳐서 /home/ 뒤 명칭을 봐라.)
  9. 단축키로 저장 후 나가서 메시지 뜬 게 있는지 확인하고, 메시지 나올 경우 visudo 오류이므로 적절히 수정하여 해결한다. (모르면 검색해라.)
  10. (옵션) SSH 서버를 외부에서 접속하고 싶은 경우, 윈도우에서 방화벽에서 포트번호 22를 허용한다. (개인 및 도메인 범위까지 한다. 공용 말고)
  11. 윈도우 시작 시 SSH 서버를 돌리기 위해 (적당한파일명).vbs 파일을 메모장이나 아무 편집기로 생성 후 아래 내용을 넣는다.
set ws=wscript.createobject("wscript.shell")
ws.run "C:\Windows\System32\bash.exe -c 'sudo /usr/sbin/sshd -D'",0
  1. 저장했으면, 모든 bash 프로세스를 끄고(리눅스 실행 모두 다 종료) vbs 파일을 더블클릭 후 PuTTY 등으로 SSH 접속 되는지 확인한다.
  2. 성공했으면 bash.exe 프로세스 종료 후, 위 vbs 파일을 작업 스케줄러에 등록한다. (모르면 좀 검색하고). 물론 “시스템 시작시”에.
    (시스템 시작 시, 파일은 vbs파일 다이렉트 호출, 사용계정은 반드시 로그인할 계정. LOCAL SERVICE 같은 시스템계정 말고. 암호 저장 안해도 됨.)
  3. 윈도우 껐다 킨 후 PuTTY로 SSH 접속 되는지 확인해서 접속 되면 이제 윈도우와 리눅스는 한몸으로 실제처럼 돌아갈 것이다. 서비스도 다.

왜 굳이 vbs로 하냐고? 물론 bat 파일 쓰거나 직접 작업 스케줄러에 등록할 수는 있어.
근데 작업 스케줄러던 bat 등록하던 뭘 하던 도스창 뜬다. 너같으면 좋겠냐? vbsws.run 에 두번째 0 인자가 바로 창 안띄워 주는 고마운 인자다.
내가 필요 시 즐겨쓰는 놈이기도 하지. 이제 리눅스 VM으로 깔 필요도 없다. 편리하다.

끗.

composite / 2017년 8월 25일 / Piss Development / 0 Comments

WSL(윈도우 서브시스템 리눅스) 에서 node.js 개발하기

오늘 좀 골때리는 경험을 했기에 글 싸지른다. 왜인지는 후에 설명한다.
이 글은 윈도우 10 레드스톤 2(크리에이터즈 업데이트) 이상에서 리눅스 서브시스템을 설치한 사용자에 해당된다.
안깔았으면 이전 글을 참고하고, 해당사항 없으면 씹기 바란다.

1. node.js 설치

먼저 apt-get 공식 리포지토리의 node 는 옛날 버전이다.
원하는 버전을 설치하고자 할 경우 리포지토리를 추가하여 설치해야 한다.
설치 버전별 목록은 여기서 볼 수 있다.
여기서는 가장 최신 버전인 7.x 버전을 설치하도록 하겠다.
별거 없다.

curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -  
sudo apt-get install -y nodejs  

끗. 사실 윈도우에 별도로 node.js 깐 적 없다면 1번에서 끝나면 된다.
URL 끝 setup_(메이저버전).x 파일명 부분에 자신이 원하는 버전 숫자로 바꾸면 된다.
하지만 윈도우 내 개발환경에서 node.jsPython 등을 설치했을 경우 골때리는 문제가 발생할 것이다.
이제부터 들어간다.

2. 환경변수 관리

이 글을 쓰는 이유이기도 한데, 기본적으로 리눅스 서브시스템을 실행하면 윈도우 환경변수가 리눅스로 공유된다.
그래서 윈도우 PATH 변수가 먼저 들어간 뒤, 리눅스 PATH 변수 내용이 짬뽕된다.
이 때문에, 예를 들어 윈도우 내 node.js를 설치한 상태일 경우, npm 실행 시 아래 메시지가 나올 것이다.

$ npm
: not foundram Files/nodejs/npm: 3: /mnt/c/Program Files/nodejs/npm:
: not foundram Files/nodejs/npm: 5: /mnt/c/Program Files/nodejs/npm:
/mnt/c/Program Files/nodejs/npm: 6: /mnt/c/Program Files/nodejs/npm: Syntax error: word unexpected (expecting "in")

물론 환경변수 공유는 편리할 수 있으나, 대부분 독립형 운영체제라 가정하고 설계하고 개발하기 때문에
개발자 입장에서는 난처하면서도 골 안때릴 수가 없다. 몇가지 방법이 있는데 취향껏 따라하면 된다.

윈도우 환경변수 공유하지 않도록 설정

윈도우 아니랄까봐 리눅스 서브시스템 옵션을 레지스트리에 등록하고 있다.
따라서 만약 윈도우 환경변수를 리눅스로 옮기기 싫으면 아래 레지스트리 소스를 메모장 등으로 붙여넣은 후,

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss]
"AppendNtPath"=dword:00000000

참고로 레지파일은 반드시 빈 행이 하나 들어가도록 한 뒤 끝내야 한다.
원하는 파일명.reg 로 저장한 뒤 걍 실행해버리면 된다. 물론 되돌리고 싶으면 값 부분에 dword:00000001 로 바꿔 실행하면 된다.

Github Issue 출처

.bashrc 파일에 원치 않는 변수내용 삭제

윈도우 환경 변수를 포기 못할 경우에 간단한 팁이다.
PATH 환경변수에 특정 내용을 지우는 식으로 처리할 수 있다.
아래 쉘 스크립트를 ~/.bashrc 파일 내용에 추가하면 원치 않는 변수 내용을 삭제할 수 있다.

### remove unnecessary Win PATHs
# This can prevent extension-less commands from bleeding into BASH.
# (eg. "ng" would execute the Win bin if "@angular/cli" wasn't installed on Linux.)
#
function path_remove {
  # Delete path by parts so we can never accidentally remove sub paths
  PATH=${PATH//":$1:"/":"} # delete any instances in the middle
  PATH=${PATH/#"$1:"/} # delete any instance at the beginning
  PATH=${PATH/%":$1"/} # delete any instance in the at the end
}

path_remove '/mnt/c/Users/me/AppData/Roaming/npm'
path_remove '/mnt/c/Users/me/AppData/Local/Yarn/bin'
path_remove '/mnt/c/Program Files (x86)/Yarn/bin'
path_remove '/mnt/c/Program Files/Git'
path_remove '/mnt/c/Program Files/Git/cmd'
path_remove '/mnt/c/Program Files/nodejs'
path_remove '/mnt/c/OpenSSL-Win32/bin'
path_remove '/mnt/c/Program Files (x86)/Python27'

이후 bash를 빠져나가고 다시 bash 실행하면 원치 않는 명령어 실행을 방지하여 조금은 더 깨끗한 환경에서 개발할 수 있을 것이다.
Github Issue 출처

composite / 2017년 8월 24일 / Piss Development / 0 Comments

윈도우 10 우분투 Bash를 탐색기 메뉴로 추가하기

제목 참 거창하지만 사실 별 거 없다.
어자피 오른쪽 마우스 메뉴와 별 다를 거 없기 때문이다.

윈도우 10 레드스톤 2(크리에이터즈 업데이트) 이상에서 우분투 서브시스템 설치 방법은 구글에 널리고 널렸으니 찾아봐라.
거기게 모든 게 다 있으니. 아니면 걍 링크 뿌린다. 여기가 친절한 듯.
(주: 스토어 단독 계정 등록만 해도 우분투 받는데 지장 없다. 특히 회사컴일 수록 로컬계정 관리가 정신건강에 이롭다.)

레지스트리 편집귀 귀찮게 건드릴 거 없다.
출처는 https://github.com/Manouchehri/bash-WSL-context-menu 이다.

bash 레지스트리 추가 (원문 컨텍스트 메뉴)
bash 레지스트리 추가 (한글 컨텍스트 메뉴)

됐다. 탐색기 오른쪽 클릭으로 잘들 써봐. 끗.

composite / 2017년 8월 22일 / Piss Development / 0 Comments

.NET Standard 2.0 관전 포인트

올 가을 .NET Standard 2.0이 출시된다.
이번 업데이트에서는 .NET Framework에서 꿀빨던 많은 API들을 최대한 수용하여 .NET Core로 이식 가능성을 중점으로 삼았다.
또한, Mono와 Unity 접근성을 최대한 확보하여 Mono에서 .NET Core 로 이동하여 통합 개발이 가능하도록 유도하였다.
그렇다면 대체 .NET Standard 2.0 에서 주의깊게 봐야 할 요소는 무엇이 있을 지, 알아보도록 하겠다.

1. .NET Framework와 .NET Core 간 상호작용

NETStandard20Libraries.png
출처: .NET Standard 2.0 – Making Sense of .NET Again

닷넷코어는 최신 표준인 1.6조차 .NET Framework 에서 .NET Core로 옮기는 데 부족한 API로 많은 어려움이 있었고,
게다가 Reflection API의 상당한 변경, AppDomain API 부재로 이를 사용한 라이브러리 이식에 많은 어려움이 있었다.
이번에 2.0의 메인 변경점이 바로 .NET Framework와 호환 가능한 API가 대거 추가된다는 점이다.
하지만 AppDomain 은 잘 쓰지 않는다. 이 글을 보고 있는 당신도 왜 AppDomain을 쓰는지 잘 모를 수 있을 것이다.
주로 플러그인 동적 로드 용도(라이브러리 동적 로드)로 쓰는데, .NET Core에서는 굳이 없어도 동적 라이브러리 로드 및 관리에 지장이 없다.
물론 .NET Core 에 API는 있지만 뭔 짓을 해도 PlatformNotSupportedException 예외가 나올 것이다.
어찌저찌 얘기해도 결론적으론 필요성이 전무하다는 거다. 이는 공식 FAQ에 나와 있다.
뱀발로, 기본적으로 닷넷 앱을 실행하면 자동적으로 1개의 AppDoamin 안에서 실행된다. 그리고 닷넷코어는 1개만 쓰도록 강제한다고 생각하면 된다.
어쨌든, 이런 아주 특이한 케이스를 제외하고는 최대한의 호환성 확보로 .NET Framework 와 .NET Core 간 호환에 지장이 없도록 했다는 것이 포인트.
그럼 이식 가능한 라이브러리(Portable Class Library)는 어떻게 되냐고? 일단은 살아있다. 일종의 플랫폼 간 다리로. 아직 이렇다 할 사안은 공식적으로 없다. 쓰고 싶은 사람은 쓰도록.
아무래도 한국 닷넷 개발자가 .NET Core로 이식한다면, 가장 맨붕 올 주는 부분이 바로 System.Data의 부족함일 것이다.
일단 추상 클래스는 원래대로 제공하되, ODBC 같은 특정 플랫폼용 API는 제공할 계획이 없다고 하니 이 점을 유의하면 되고,
특히 MSSQL 연동 시 .NET Framework에서는 아예 기본 제공이었던 점과는 달리 따로 분리되어 따로 불러와야 한다는 점만 주의하면 되겠다.
WCF나 WPF같은 경우 애초부터 윈도우 종속이기 때문에 절대 기대는 하지 말자. 다시말해, 닷넷 자체 플랫폼 종속 기능과, Remoting 기능을 기대하지 말라는 거다.
(단, XAML 자체는 독립 플랫폼 표준이 생겼기 때문에 플랫폼별로 Xamarin 등으로 새로 만들어야 하는 거 빼면 스펙 문제는 없다.)
이런 몇가지 예외 사항을 제외하면 대부분이 이식 가능하도록 배려했다고 한다.

2. .csproj 부활

앞서 닷넷코어 팀이 1.0 Preview에 예고한 것처럼, project.json 방식에서 다시 .csproj 방식으로 돌아온다.
.csproj 방식은 XML 으로 관리하는 방식인데, 닷넷 팀도 기존에 강력한 프로젝트 관리 형식을 버린다는 건 낭비라고 판단한 듯 하다.
분명 JSON 방식은 사람이 읽기가 쉽고 간결하며, 프로젝트 관리에 지장은 크게 없었지만, 닷넷의 모든 것을 수용하기엔 해결해야 할 과제가 많았기에 돌아온 것으로 보면 된다.
그래서 .NET Framework 에서 .NET Core로 이식하거나 그 반대로 마이그레이션 하는 접근성을 한층 더 높여줬다고 보면 된다.

3. 뭐야? 이게 다야?

그렇다. 이게 다다. 공식적으로 닷넷 2.0 최종 버전의 소개는 이게 다다.
뭘 더 바랬는지 모르겠지만, .NET Standard 는 스펙이다. 구현체는 .NET Framework 와 .NET Core다.
스펙에서는 플랫폼 간 이식에 중점삼아 스펙을 구성하여 이걸 .NET Framework 와 .NET Core 으로 구현한 것이다. 이게 다다.
C# 표준도 향상된다. 하지만 이는 .NET Standard와는 상관이 없다. C#은 언어 스펙이기 때문이다. 당연히 최신 언어 스펙을 .NET Standard 1.x 사용하는데 크게 지장이 없다.
.NET Framework 4.5 부터는 언어 스펙이 올라가도 사용하는 데 지장이 없다는 걸 C# 6.0에서 보여주었다. 그렇기에 따로 봐야 할 문제다.
물론 가능하면 새로운 앱을 만들거나 마이그레이션을 해야할 경우가 생기면 .NET Standard 최신 버전을 따르는 게 유리할 수밖에 없다. 1.x 는 API 텀이 너무 많기 때문이다.

글 쓴 나도 허무하다. 하지만 이번 업데이트 만큼은 기대해도 좋다. 왜냐면 닷넷 그대로 덜 만져서 탈윈도우 플랫폼을 꾀할 수 있는 기회가 되기 때문이다.
지금 당장 테스트하고 싶으면 .NET Core 2.0 Preview를 설치하면 된다. 거기서 크게 달라질 거 없다고 한다.
이 글을 쓰고 4일 뒤 정식 버전으로 나왔다. .NET Core 2.0 링크 가서 다운받고 설치하면 된다. 아, 위 프리뷰 깔았던 사람은 구조는 비슷하기 때문에 걍 재설치하면 된다.
미안. 1주일 뒤에 지인을 통해 알아차렸다… 페북에서도 소식이 없다니 ㄷㄷ

여담으로, Standalone 프로젝트(사내용 앱 등)은 특정 플랫폼, 특정 API를 쓰는 경우가 많기 때문에 그 프로젝트 자체를 마이그레이션하려는 멍청한 짓은 하지 말자. 어자피 갈아 엎어야 한다.

composite / 2017년 8월 11일 / Piss Development / 2 Comments

nw.js 한국어 활동을 중단하다.

다들 Electron 쓰는 거 안다. 그래서 단도직입적으로 말하겠다. nw.js 활동 관뒀다.
시간에 쫓기고 관련 프로젝트도, 수요도 없으며, nw.js 쓰던 개발자들도 모두 Electron으로 옮긴 데는 이유가 있다.
뭐, 어찌보면 나의 변명을 싸지르는 글이기도 하다. 일단 나열하겠다.

미미한 수요

현재 많은 개발자들은 데스크탑 앱을 간편하게 제작하는 데 Electron 으로 개발하고 있을 것이고, nw.js 라는 놈이 있었나 하는 사람들은 깊게 파기 시작하다보면 아하 할 것이다.
당연하겠지만, Electron은 개발자 친화적인 프레임워크를 구축하였기에 더 많이 채택된 것이다. 즉, 이런 이유로 Electron을 선택한 것이다.

  • node.js 에 익숙한 개발자들의 익숙한 개발환경 구축 용이
  • ASAR 패키징을 통한 기본적으로 손쉬운 패키징
  • 많은 사용자 커뮤니티 층과 Issues
  • 성능과 기술 수용속도가 유리
  • 견고하고 안정적인 업데이트 주기

당연하겠지만 첫번째 이유가 가장 큰 이유 되시겠다.
물론 nw.js도 나름대로 장점이 있다.

  • node.js 에 익숙하지 않아도 구축 가능한 개발 환경
  • 자바스크립트 소스코드 보호를 위한 nwjc 제공

둘 다 오픈소스다. 그리고 하나는 Github, 하나는 Intel 이 주도한다.
결국 nw.js 의 업데이트 속도와 Issue는 느려졌고, Intel의 보수적 개발 덕분에
수요자들을 충족시키지 못했다. 자연스레 Electron의 압승으로 현재 진행중이다.

여기서 Electron을 선택할 수밖에 없는 수요층이 있는데, 바로 실시간 처리를 하는 업자들이다.
대표적인 예로 메신저, 화상 회의나 채팅 등이 있다. 그리고 여러분이 많이 쓰는 Slack이 대표적 업체다.
개발하던 패턴대로 개발하면 되기 때문이다. node.js 관련된 여러 기술들을 그대로 가져다 쓸 수 있다.
물론 네이티브로 갈 땐 얘기가 달라지지만.

기술적으로 Electron은 nw.js에 비해 프론트엔드와 백엔드 컨텍스트가 완전히 분리되어 있다.
이 때문에 명확한 컨텍스트 관리라는 평가를 받고 있기도 하다.

랜섬웨어 프레임워크???

파일을 무작정 암호화 하고 파일을 인질삼아 금품을 요구하는 랜섬웨어.
이 프로그램을 만드는 데스크탑 프레임워크의 쌍벽이 있는데,
하나는 .NET WinForm이고, 또 하나는 nw.js 다.
그래서 보안개발자들 입장에서는 nw.js 는 비트코인처럼 혐오하는 프레임워크일 지도 모른다.
당연하겠지만 node.js 에 익숙하지 않은 개발자들에게 nw.js는 접근성이 용이하다.
왜냐면 그냥 웹 페이지만 띄우고 package.json 쓰고 실행만 하면 땡이기에.
그래서 어느 백신은 nw.js 들어가기만 해도 걸러내는 오진을 선보이기도 했다.
결국 nw.js 는 Electron 개발자 중 아는 개발자들에게 웃음거리가 됐고 불명예스러운 프레임워크가 됐다.

Github의 윈윈전략

Electron은 Github의 주요 기술이다. Atom Editor는 그 기술을 통해 제공하는 컨텐츠일 뿐이다.
거리낌없이 Electron을 오픈했고, 기업들은 이를 선택했다. MS도 거리낌없이 선택했다.
이리하여 Github은 거대한 플랫폼 시장을 형성하는 데 성공했고, 이제 Github 종속된 대기업이 많아졌으며,
세계적 브랜드 네이밍을 어마어마하게 키운 업체가 되었다. 한국 직원이 아직도 없다는 건 무시하자.
(참고로 중국과 일본은 있는데 한국은 없다는 점에 카타르시스를 느끼는 병신이 본인이다. Github Enterprise는 중국과 일본에 현지 서비스가 가능하지만 한국은 없다고 한다. 지금도.)

그에 반해 nw.js 도 많은 노력을 기울였고 Electron을 탄생시킨 프로젝트였지만,
이제 말하는데 nw.js 프로젝트를 인텔이 이끄는 걸 아는 사람도 별로 없더라. 허..

브랜드 파워는 이런 단순한 곳에서 출발하여 거대한 시장을 이끌어내고 있다.

나 이제 뭐하냐…

일단 Electron 에반젤리스트들은 한국에도 꽤 많아졌다. 물 들어올 때 노 저어 이름 석자 알린 사람도 꽤 있다.
그런 면에서 나는 비주류에 노를 젓다 썰물 다 가 고립된 상태인 것이다.
지금 내 꼬라지를 짤방으로 마무리하며 시간상 여기까지 싸지르도록 하겠다.

둠가이

composite / 2017년 7월 11일 / Dog's bullshit, Piss Development / 0 Comments

자, 자바커들아, 게이물 시작하지. Porject Jigsaw 통과.

지난 6월 27일, 내 예상과는 달리 직쏘가 통과되어, JDK 9에 당당히 포함할 수 있게 되었다.
직쏘 반대하느라 A4용지 30여페이지를 날린 레드헷만 끝가지 반대 입장을 고수했고, 나머지는 오라클 영업력에 뻑이 갔는지 모두 찬성했다고 한다.

자바 개발자들에게 여태까지 버텨왔던 하위 호환성. 이제 개나 주게 생겼다.
하지만 그건 문제가 아니다. 왠만한 언어 스펙도 이런 고통을 안고 업그레이드 했다.
가장 대표적인 게 Python인데, 유니코드 지원이 강화한 대신 유용(?)한 API를 삭제했다고 원성을 높여
아직도 2.7을 쓰는 프로젝트와 제품이 즐비한 상황이다.
자바도 뭐 이미 그꼴 날 건 뻔할 뻔자지만, 당분간 자바개발자들은 임베디드나 모바일 계통이 아닌 이상은
계속 Java 8을 보고 있을 것으로 보인다.

직쏘를.araboja

정식 명칭으로 “자바 플랫폼 모듈 제계(Java Platform Modulule System)”라는 이름을 가지게 되었으며, JSR-277 번호를 가지고
2011년 프로젝트를 시작하여 원래 자바 7에 추가할 예정이었다. 하지만 구조적 문제가 해결되지 않아 자바 8에서도 보류하는 아픔을 겪었다.
직쏘에 기대를 거는 이유는 하나다. 여태까지 고질적인 자바의 문제를 해결할 핵심 기능을 가지고 있었기 때문이었다.
자바의 고질적인 원흉인 캡슐화 문제는 뭐 이미 옛날부터 제기해왔지만, 당시 닫혀 있었던 구조상 해결할 수 없어 그저 수용만 했던 개발자들이 대부분이었다.
하지만 자바의 오픈 이후 이를 개선할 수 있는 움직임이 생겼으며, 이 중 하나가 바로 직쏘다.

대부분의 자바 개발자는 이런 반응을 보일 것이다.

  • 크로스 플랫폼으로 잘만 돌아가고 있는데 왜?
  • 메모리 문제? 그저 사양만 늘려주면 빠르고 깔끔하잖아?
  • 경량화? 경량화 할 디바이스가 어딨다고…

근데, 리조트 프로젝트 했었는데, POS를 자바로 개발하려는 시도가 있었다. 하지만 낮은 사양에 높은 처리능력을 요구하기에 자바는 맞지 않았고 닷넷으로 갔다.
관련 프로젝트를 해본 사람이라면 안다. 왜 자바를 POS에 접목시키는 게 쉽지 않았는지. 웹 말고.
하지만 모듈 시스템을 탑재하면 더 가벼워진 이미지로 적은 메모리로도 POS 시스템을 돌릴 수 있다고 생각해보자.
속 시원하지 않겠는가?

이 중 큰 원인이 바로 자바의 상속 시스템인데. rt.jar 파일 아는가? 자바에 모든 API가 있는 라이브러리다.
그만큼 무겁다. 더럽게 무겁다. 모든 자바 프로그램은 절대 이 라이브러리를 거역할 수가 없다.
닷넷의 경우 얘기가 틀린데, 닷넷은 GAC이라는 레지스트리급 쓰레기가 있지만, 대신 모듈이 분리되어 필요한 것만 갖다가 쓸 수 있다.
그래서 시작 속도 뿐 만 아니라 성능 면에서도 유리하다. 예를 들어,
자바는 웹을 아예 안 써도 웹 API를 가지고 가야 한다. 하지만 닷넷은 안쓰면 안가져가도 된다. 이 차이인 것이다.
그러나 직쏘와 함께하면 자바도 웹 안쓰면 웹 안들고 가도 동작하도록 할 수 있다. 말 다했다.

한마디로 자바의 입지를 한 층을 넘어 더 다양한 분야에 뛰어들게 해주는 샘물같은 존재다. 그걸 모르는 자바 개발자들은 지금에도 만족하며 잘 개발하고 있겠지만.
게다가 이런 현상을 유지하는 데 한몫한 업체가 바로 의외에 있었는데, 구글이다. 그렇다. 안드로이드다.
하지만 안드로이드는 개발 시 자바를 언어로 쓸 뿐, 오라클의 JVM을 쓰지 않고 아예 독립적으로 개발한 JVM으로 돌리고 있다.
게다가 딸려나오는 라이브러리도 많다. 그리고 이들 모두를 상속받아야 안드앱 개발이 가능하다.
따라서 모듈 시스템에 수혜를 받기엔 가상머신부터 틀려서 일단 패스하고.

이클립스 실행하는 데 느리다고 생각하는 사람 많을 거다. 더럽게 무겁기도 유명한 비주얼 스튜디오보다도 느리다. 인텔리제이도 시작 속도 예외는 없다.
그걸 빠르게 해 주겠다는데. 왜?

직쏘가 어떻게 구현되고 돌아가는지는 얘기가 너무 길어지니 직접 검색해서 보도록 하자. 한글 블로그에도 많이 소개되어 있다.

직쏘의.problem

이렇게 자바에게 날개를 달아주는 녀석이지만, 많은 자바 개발자들이 우려하고 있는 점이 있다면 바로 하위 호환성을 꼭 빼놓을 수 없다.
자바 1.5부터 추가된 제네릭의 경우는 객체 소멸(Type Erasure)을 통해 컴파일 때에만 제네릭을 검사하고 런타임 상는 제네릭 없이 돌아가도록 구현하였다.
그래서 닷넷과는 달리 Map 클래스와 Map<Key, Value> 클래스. 제네릭이 있던 없던 같은 클래스로 취급하는 것이다. 닷넷은 다른 클래스로 취급한다.
결국 1.4 때 제네릭 없었던 클래스처럼 써도 무방할 정도인 것이고, 성능상 이점이 없으며, 그저 자바의 방향인 Strong Typed에 부합될 뿐이었다.
그리고 자바 1.8부터 도입된 람다식의 경우 이미 익명 클래스로 충분히 소화해낼 수 있기 때문에 간소화된 것만 빼면 하위 호환성에 큰 지장은 없다는 것이다.
하지만 직쏘는 그 이전 버전에 대체할 수 있는 환경이 아예 없다. 하위 호환성을 유지하려면 직쏘를 아예 쓰지 말아야 할 정도이다.
여태까지 하위 호환성을 최대한 생각했기에 개발자 입장에서는 큰 난관이 아닐 수 없다.
만약 버전을 올리고 개발했을 때, 문제가 생기면 해당 버전에 맞게 개발하고 컴파일 하면 됐다. 하지만 직쏘는 그게 안된다. 다 버려야 한다는 것이다.
그래서 자바 API를 닷넷에 쓰게 해주는 IKVM.NET 개발자는 모듈 시스템의 복잡도 때문에 더 이상 새 자바에 대응하지 않겠다는 공식 입장을 피력할 정도.
그리고 이 불안은 현재진행형이며, 정식 버전이 나오면 1.9를 바라볼 사람이 얼마나 될 지 의문이다.

자, 자바 개발자들이여, 이제 게임을 시작하지. 직쏘.

composite / 2017년 7월 5일 / Piss Development / 0 Comments

1 2 3 6