AspectJ & Java 호환성 이슈

2024. 10. 2. 12:24·Language/Java

출석체크 이벤트 기능을 구현 중이다.


관리자페이지에서 해당 이벤트에 대한 지급 쿠폰을 등록할 수 있다.


1. 출석체크 시 무조건 지급하는 일일 쿠폰

2. 연속 출석 시 지급하는 연속 쿠폰 -> admin에서 연속 출석 일수를 설정할 수 있다.

 

각 쿠폰마다 여러 장 등록될 수 있다.

ex) 일일 쿠폰 3장 / 연속 쿠폰 2장

 

사용자가 출석 체크 이벤트에 참여하면

서버에서는 해당 이벤트로 등록된 쿠폰 목록을 모두 조회하고,

사용자의 이벤트 참여 상태에 따라 어떤 쿠폰을 지급해야할 지 판단한다.

 

쿠폰 목록을 조회할 때, 일일/연속 구분 없이 해당 이벤트로 등록된 모든 쿠폰을 조회한다.

쿠폰 조회 후, 쿠폰마다 가지고 있는 type으로 일일/연속 쿠폰으로 분리한다.

일일 쿠폰 타입 : D
연속 쿠폰 타입 : C
// 출석체크 이벤트 쿠폰 조회
List<AttendCoupon> attendCoupons = dao.getCoupontList(event.getEventId());

// 쿠폰 타입별 분리
List<AttendCoupon> dailyCoupons = new ArrayList<>(); // 일일 쿠폰
List<AttendCoupon> consecutiveCoupons = new ArrayList<>(); // 연속 쿠폰

for (AttendCoupon coupon : attendCoupons) {
    if ("D".equals(coupon.getType())) {
        dailyCoupons.add(coupon);
    }
    if ("C".equals(coupon.getType())) {
        consecutiveCoupons.add(coupon);
    }
}

스트림으로도 구현해볼 수 있지 않을까.

// 출석체크 이벤트 쿠폰 조회
List<AttendCoupon> attendCoupons = dao.getCouponList(event.getEventId());

// 쿠폰 타입 기준 grouping
Map<String, List<AttendCoupon>> groupedCoupons = attendCoupons.stream()
        .collect(Collectors.groupingBy(AttendCoupon::getType));

List<AttendCoupon> dailyCoupons = groupedCoupons.getOrDefault("D", new ArrayList<>());
List<AttendCoupon> consecutiveCoupons = groupedCoupons.getOrDefault("C", new ArrayList<>());

스트림으로 작성 후, 실행했는데 에러가 발생했다.

Caused by: org.aspectj.apache.bcel.classfile.ClassFormatException: File: '파일위치':
Invalid byte tag in constant pool: 18

AspectJ가 바이트 코드를 제대로 처리하지 못하고 있다는 내용을 담고 있다.

 

자바 컴파일러가 스트림/람다의 바이트 코드를 생성했지만

AspectJ가 해당 바이트 코드를 지원하지 않아 발생한 문제로 확인된다.

 

AspectJ가 바이트 코드를 지원하지 않은 이유

프로젝트의 Java 버전과 aspectJ 버전이 맞지 않아서다.

현재 Java 8 을 사용 중이고, aspectJ는 Java 7 버전까지만 지원하는 1.6.11 버전을 사용 중이다.

 

AspectJ 같은 바이트코드 조작 라이브러리는 특정 자바 버전에서의 바이트코드 구조에 의존한다.

Java 7 까지는 invokestatic, invokevirtual, invokeinterface, invokespecial 을 사용했지만

Java 8 은 새로운 기능인 스트림, 람다를 처리하기 위해 invokedynamic 라는 새로운 바이트 코드 명령어를 사용한다.

현재 사용 중인 aspectJ 버전에서 invokedynamic 을 인식하지 못해 에러가 발생한 것이다.

 

어떻게 해결할 수 있을까?

aspectJ를 최신 버전으로 업데이트하여 스트림을 사용하거나, 단순 반복문을 사용함으로써 해결할 수 있다. 

 

현재 프로젝트에서는 스트림이 사용된 로직이 없고, 복잡한 로직이더라도 전부 반복문으로 구현되어 있다.

갑자기 스트림으로 작성된 코드를 본다면 의문을 품을 수밖에 없다. 

일관성을 지키고자 반복문을 선택했다.

 

스트림으로 구현할 수 있는 코드이더라도, 어쩌면 스트림으로 작성하는 것이 더 좋은 코드일지라도,

읽는 사람에게 혼동을 줄 수 있다면 코드의 일관성을 지키는 게 좋지 않을까.

저작자표시 (새창열림)

'Language > Java' 카테고리의 다른 글

Readable Code 적용  (2) 2024.10.24
'Language/Java' 카테고리의 다른 글
  • Readable Code 적용
tjdgus
tjdgus
  • tjdgus
    Do It...
    tjdgus
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Language
        • Java
      • CS
        • Data Structure
        • OS
        • Algorithm
        • Network
      • 오류 모음집
      • ETC
      • 함수형 프로그래밍
      • JPA
      • Toy
      • 데이터베이스
      • Spring
      • 코딩테스트
        • 99클럽 4기
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코딩테스트준비
    개발자취업
    티스토리챌린지
    99클럽
    항해99
    TiL
    오블완
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
tjdgus
AspectJ & Java 호환성 이슈
상단으로

티스토리툴바