자바 백엔드 실무
들어가며
대한민국의 중견/대기업 시스템을 다루다 보면 필연적으로 마주치는 거대한 산이 있습니다. 바로 SAP ERP입니다. 자산관리 시스템에서 구매 요청을 하거나, 자산 취득 후 회계 전표를 생성하려면 반드시 ERP와 통신해야 합니다.
일반적인 REST API라면 HttpClient를 쓰면 그만이지만, SAP는 그들만의 독자적인 프로토콜인 RFC(Remote Function Call)를 사용합니다. Java 개발자가 SAP와 대화하기 위해서는 SAP JCo(Java Connector) 라이브러리가 필수적입니다.
이번 글에서는 채용 공고의 핵심 키워드인 ‘RFC 연계 개발’을 위해, Spring Boot 환경에서 JCo를 설정하고 데이터를 주고받는 실무 패턴을 정리합니다.
1. 환경 설정: JCo 라이브러리의 특이점
JCo는 순수 자바 라이브러리가 아닙니다. OS에 맞는 네이티브 라이브러리(sapjco3.dll 혹은 libsapjco3.so)가 시스템 경로(System Path)에 함께 존재해야만 동작합니다.
- 개발 환경(Windows):
C:\Windows\System32에 dll 파일 배치 - 운영 환경(Linux):
LD_LIBRARY_PATH환경 변수에 so 파일 경로 추가
이 설정이 누락되면 UnsatisfiedLinkError라는 악몽 같은 에러를 마주하게 됩니다. 배포 스크립트 작성 시 이 부분을 가장 먼저 체크해야 합니다.
2. 연결(Connection) 관리: DestinationDataProvider
JCo 3.0부터는 .jcoDestination 파일을 사용하는 대신, 메모리상에서 연결 정보를 관리하는 DestinationDataProvider를 구현하는 것이 정석입니다.
1
2
3
4
5
6
7
8
// SAP 연결 설정 프로퍼티 예시
Properties connectProperties = new Properties();
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "192.168.0.10"); // SAP 호스트
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, "00"); // 시스템 번호
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, "100"); // 클라이언트
connectProperties.setProperty(DestinationDataProvider.JCO_USER, "RFC_USER"); // 계정
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, "password"); // 암호
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, "KO"); // 언어
이 설정 정보는 보안상 매우 중요하므로, 소스 코드에 하드코딩하지 않고 암호화된 설정 파일이나 환경 변수에서 읽어오도록 구성해야 합니다.
3. RFC 호출 실전 코드: 전표 생성 예제
자산 취득 정보를 ERP로 보내 전표를 생성하는 RFC 함수 Z_FI_CREATE_DOC를 호출한다고 가정해 봅시다.
Step 1: 함수 가져오기
1
2
3
4
5
6
JCoDestination destination = JCoDestinationManager.getDestination("ABAP_AS_WITHOUT_POOL");
JCoFunction function = destination.getRepository().getFunction("Z_FI_CREATE_DOC");
if (function == null) {
throw new RuntimeException("Z_FI_CREATE_DOC 함수를 찾을 수 없습니다.");
}
Step 2: Import Parameter (입력값) 세팅
SAP는 변수 타입을 엄격하게 따집니다. 특히 날짜(YYYYMMDD), 금액, 숫자 타입 변환에 주의해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
// 단일 파라미터 세팅
function.getImportParameterList().setValue("I_COMP_CODE", "1000"); // 회사코드
function.getImportParameterList().setValue("I_DOC_DATE", "20251114"); // 증빙일
// 테이블(Table) 파라미터 세팅 (Multi row)
JCoTable inputTable = function.getTableParameterList().getTable("T_ITEM_LIST");
for (AssetItem item : items) {
inputTable.appendRow(); // 행 추가
inputTable.setValue("ITEM_TEXT", item.getName());
inputTable.setValue("AMT_DOC", item.getAmount()); // 금액
}
Step 3: 실행 및 결과 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try {
function.execute(destination); // RFC 실행
} catch (AbapException e) {
// SAP 내부 로직 에러 처리
log.error("SAP Error: " + e.toString());
}
// Export Parameter (리턴값) 확인
String resultType = function.getExportParameterList().getString("E_TYPE"); // S:성공, E:실패
String message = function.getExportParameterList().getString("E_MESSAGE");
if ("S".equals(resultType)) {
String docNo = function.getExportParameterList().getString("E_DOC_NO"); // 생성된 전표번호
log.info("전표 생성 성공: " + docNo);
} else {
throw new RuntimeException("전표 생성 실패: " + message);
}
4. 데이터 타입의 늪: Padding과 Conversion
SAP와의 연동에서 가장 많이 겪는 문제는 데이터 길이와 패딩(Padding) 문제입니다.
- Zero Padding: 사원번호가 DB엔 ‘1234’로 저장되어 있지만, SAP는 ‘00001234’를 요구할 수 있습니다.
StringUtils.leftPad등을 활용해 포맷을 맞춰야 합니다. - 날짜: Java의
LocalDate를 SAP가 요구하는String(8)(“20251114”) 형태로 변환하는 유틸리티 메서드를 공통화해두어야 합니다.
마무리하며
오늘은 Java 백엔드 개발자의 영역을 확장하여 SAP ERP와의 RFC 통신 방법을 다뤘습니다.
JCo 프로그래밍은 일반적인 REST API 호출보다 훨씬 Low-level의 제어가 필요하며, 데이터 타입 하나하나에 민감해야 합니다. 하지만 이 기술을 보유하고 있다는 것은 기업의 기간계 시스템(Legacy)을 두려움 없이 핸들링할 수 있다는 강력한 증거가 됩니다.
그런데 여기서 한 가지 무서운 상상을 해봅시다. 내 자바 시스템에서는 자산 상태를 ‘취득 완료’로 바꿨는데, 그 순간 네트워크 오류로 SAP 전표 생성이 실패한다면? 내 DB는 ‘성공’, ERP는 ‘실패’. 데이터 불일치가 발생합니다.
다음 시간에는 이렇게 분산된 환경에서 데이터 정합성을 지키기 위한 최후의 보루, [분산 트랜잭션과 보상 트랜잭션 전략]에 대해 깊이 있게 고민해 보겠습니다.