J2ObjC 는 API 의 클라이언트 개발 도구다
구글은 최근 J2ObjC 라는 이름의 오픈 소스 도구를 발표했습니다. 자바코드를 iOS용 Objective-C 로 번역하는 기능을 제공한다고 하는데, 아직 베타수준이라고 하는군요. 사이트에서는 프로젝트의 목표와 기능을 아주 간략히 정의하고 있기 때문에 첫눈에는 좀 모호한 구석이 없지 않습니다. API 도구일 수도 있겠다는 느낌이 들어 좀 자세히 살펴봅니다.
UI 이외의 코드를 자바로 작성하여 Xcode 프로젝트에 포함시킬 수 있다.
이렇게 작성된 자바코드는 안드로이드나 웹 앱과 공유할 수 있다고 합니다. UI 코드는 여전히 iOS SDK 를 사용하여 Objective-C 로 작성해야 하고요. 다시 말하면 플랫폼간의 UI 차이를 추상화하려는 의도는 없다는 뜻이네요. UI 개발에는 쓸 수 없다고 하면 도대체 무슨 용도가 있을까요?
J2ObjC 는 API 의 클라이언트 개발 도구다.
구글 앱 엔진(GAE - Google App Engine) 과 구글 웹 툴킷(GWT - Google Web Toolkit)을 함께 사용할 경우 Data Transfer Object 라는 것을 자바코드로 작성합니다. 주로 서버와 클라이언트가 주고받는 데이터 클래스들을 대상으로 하는데, 이 코드는 GAE 와 GWT 가 공유합니다. 이클립스 프로젝트의 경우 아예 `shared` 라는 이름의 폴더로 구분하여 공유를 보장합니다. GAE 의 경우는 이 자바코드를 그대로 사용하여 서버에서 실행하고, GWT 의 경우는 자바스크립트로 번역한 후 웹 브라우저에서 실행하게 됩니다. 서버와 공유하지 않는 클라이언트만의 코드 역시 자바로 작성될 수 있습니다. 같은 방법을 iOS 로 확장하려면 GWT 를 J2ObjC 로 바꾸면 됩니다. 안드로이드는 따로 번역기를 준비할 필요가 없고, 통신 부분만 준비하면 되겠지요. 때문에 API 의 서버 구현은 GAE 로 작성하고, API 의 클라이언트 구현은 자바로 작성하며, 안드로이드 클라이언트는 자바 라이브러리를, iOS 클라이언트는 J2ObjC 가 번역한 Objective-C 라이브러리를, 웹 앱은 GWT 가 번역한 자바스크립트를 사용할 수 있습니다. 이런 구성을 실제 프로젝트에 적용해본 후에 다시 소개하기로 하고, 도구의 현재 배포 판을 살펴보는 것으로 마무리하겠습니다. 프로젝트 사이트에서 배포하는 바이너리를 사용하려면 대충 Xcode 가 설치된 Mac OS X 가 있으면 됩니다. 소스코드를 받아서 빌드 하려면 Maven 이 추가로 필요하다고 합니다만, 저는 바이너리만 설치했습니다. ZIP 파일로 배포되는 바이너리는 풀어서 아무 곳에나 폴더 채로 복사해두면 됩니다. 자주 사용하실 거면 `PATH` 를 걸어두시고, 한번만 해 보실 거라면 필요 없습니다. 이런 `Hello.java` 코드가 있습니다.
public class Hello {
public static void main(String[] args) {
System.out.println("hello, world");
}
}
이 자바코드를 Objective-C로 번역하려면 쉘에서 이런 명령을 실행합니다. `PATH` 설정을 하지 않으셨으면 `j2objc` 경로를 정확히 적어주셔야겠지요.
j2objc Hello.java
`Hello.h` 와 `Hello.m` 파일이 만들어지는데 내용은 이렇습니다.
//
// Generated by the J2ObjC translator. DO NOT EDIT!
// source: Hello.java
//
// Created by flowdas on 12. 9. 17.
//
@class IOSObjectArray;
#import "JreEmulation.h"
@interface Hello : NSObject {
}
@end
//
// Generated by the J2ObjC translator. DO NOT EDIT!
// source: Hello.java
//
// Created by flowdas on 12. 9. 17.
//
#import "Hello.h"
#import "IOSObjectArray.h"
@implementation Hello
@end
int main( int argc, const char *argv[] ) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
IOSObjectArray *args = JreEmulationMainArguments(argc, argv);
NSLog(@"%@", @"hello, world");
int exitCode = 0;
[pool release];
return exitCode;
}
iOS 는 명령 행을 제공하지 않기 때문에 표준출력과 표준에러출력은 모두 `NSLog` 로 보냅니다.